Создавайте свои собственные взгляды на глобальное потепление, используя общедоступные данные.

Сейчас вы читаете третью и последнюю часть моей мини-серии об анализе общедоступных данных для исследования изменения климата. Тем не менее, идея состоит не в том, чтобы стать настоящим экспертом в области метеорологии, а в том, чтобы применить здравый смысл с соответствующими инструментами для получения некоторой информации, чтобы каждый, имеющий некоторый опыт программирования и работы с данными, мог сделать свои собственные выводы. Демократизация науки о данных, да!

Как я уже писал ранее, способность широкой аудитории воспроизводить научные идеи с помощью общедоступных методологий становится все более и более важной в этом мире, где все большее число решений все чаще основывается на данных и математических моделях, в то время как социальные сети упрощают распространять ложную информацию. Наряду с этой идеей, эта серия статей является моим подходом к исследованию изменения климата и, таким образом, к борьбе со всеми этими ложными утверждениями, следуя более научному подходу, не будучи при этом экспертом по климату.

Исходный код

В этой статье опущены многие детали этапов обработки, чтобы сосредоточиться на общем подходе. Блокнот Jupyter с полным рабочим кодом можно найти на GitHub.

Контур

Весь путь от загрузки некоторых данных до создания некоторых изображений разбит на три отдельные истории, поскольку каждый шаг уже содержит много информации.

  1. Получение данных. Первая часть посвящена получению общедоступных данных о погоде и извлечению из этих данных соответствующих показателей. В зависимости от источника данных это оказывается сложнее, чем можно было бы предположить.
  2. Подготовка данных. Следующий шаг будет сосредоточен на подготовке данных таким образом, чтобы мы могли легко ответить на вопросы о средних показателях, таких как температура или скорость ветра, по метеостанции и по стране.
  3. Создание аналитических данных(вы только что читаете эту часть). Наконец, в последней части мы сможем провести некоторый анализ на основе подготовленных данных, которые покажут климат изменять.

1. Ретроспективные и заключительные шаги

Первая часть этой серии была посвящена получению необработанных данных о погоде от Национального управления океанических и атмосферных исследований (NOAA) и преобразованию данных в более удобный формат файла. Вторая часть серии была посвящена построению агрегированного набора данных, который хорошо подходит для ответов на основные (но, тем не менее, актуальные) вопросы об общей погоде для каждой страны на ежедневной основе.

Теперь осталось провести сам анализ и сделать некоторые выводы. В частности, я попытаюсь воспроизвести некоторые графики от настоящих экспертов по погоде в моей стране (Deutscher Wetterdienst в Германии).

Итак, что мы узнаем на этот раз?

  • Как агрегировать данные с помощью PySpark (еще раз…)
  • Как создавать осмысленные и проницательные визуализации данных о погоде

2. Предпосылки

Я предполагаю, что вы уже следили за первой частью и второй частью этой серии, так как мы снова будем опираться на полученные файлы Parquet. Хорошей новостью является то, что на этот раз мы не будем генерировать новые наборы данных, что потребует больше свободного места на вашем жестком диске или SSD.

В качестве первого шага (и чтобы снова разогреться) давайте прочитаем окончательный набор данных, который мы создали в прошлой статье, и отобразим его схему:

# Read in data again
daily_country_weather = 
        spark.read.parquet(daily_country_weather_location)
# Inspect Schema
daily_country_weather.printSchema()

3. Среднегодовая погода

Как я уже говорил вам, мы будем полагаться на «здравый смысл» и посмотрим, к чему мы придем. Таким образом, очень очевидная идея для доказательства изменения климата состоит в том, чтобы создавать несколько ежегодных графиков — и это не самое худшее, что можно сделать. Но прежде чем мы пойдем по этому пути, позвольте мне еще раз указать на систематические недостатки, с которыми нам придется смириться:

3.1 Отказ от ответственности

Я не специалист по погоде, и поэтому моя методика не совсем верна. В частности, мы работаем с огромным набором данных, содержащих измерения погоды с метеостанций по всему миру. Но срок службы большинства метеостанций очень ограничен, а это означает, что точки измерения со временем меняются, и поэтому информация о погоде не является строго сопоставимой в разные годы с разными наборами активных метеостанций. Мы также не взвешиваем измерения метеостанций в зависимости от их расстояния до других метеостанций (что может быть интересной идеей) или других причудливых вещей. Мы придерживаемся простого глупого (но все же образованного) подхода, игнорируя все эти важные детали.

3.2 Годовая мировая температура

Самое простое, что можно сделать прямо сейчас, — создать визуализацию, отображающую глобальную среднюю температуру по всем странам за все годы. Мы будем использовать PySpark для агрегации и Seaborn для визуализации:

# Aggregate average weather for all countries
yearly_weather = daily_country_weather \
    .withColumn("year", f.year(f.col("date"))) \
    .groupBy("year").agg(
        f.avg(f.col("avg_temperature")).alias("avg_temperature"),
        f.avg(f.col("avg_wind_speed")).alias("avg_wind_speed"),
        f.avg(f.col("max_wind_speed")).alias("max_wind_speed")
    )\
    .orderBy(f.col("year")).toPandas()
# Create a plot with Seaborn (which as imported as sns)
plt.figure(figsize=(24,6))
sns.regplot(data=yearly_weather, 
               x="year", y="avg_temperature", color="r")

Таким образом, мы видим явное увеличение средней глобальной температуры в пределах набора данных, но, конечно, здравый смысл подсказывает нам, что здесь что-то не так, поскольку повышение на 15°C между 1920 и 1950 годами уже привело бы к превысило любой наихудший сценарий, который может произойти в будущем.

Итак, каковы возможные объяснения того, что мы здесь видим? Что ж, если исключить какие-либо ошибки программирования с нашей стороны и предположить правильные реализации во всех библиотеках, эффект должен находиться внутри самого набора данных в сочетании с нашим подходом. Помните предупреждение обо всех упрощениях и проблемах с постоянно меняющимся набором метеостанций? Давайте попробуем выяснить, может ли это быть проблемой. Поскольку мы уже потеряли отдельные метеостанции в совокупности, давайте просто посчитаем количество стран за год, содержащихся в наборе данных:

# Count number of distinct countries in the data set per year
yearly_countries = daily_country_weather \
    .withColumn("year", f.year(f.col("date"))) \
    .groupBy("year").agg(
        f.countDistinct(f.col("CTRY")).alias("num_countries")
    )\
    .orderBy(f.col("year")).toPandas()

# Plot the number of countries per year
plt.figure(figsize=(24,6))
sns.relplot(data=yearly_countries, 
            x="year", y="num_countries", color="r", aspect=4)

Этот график ясно показывает, что набор данных имеет очень сильное смещение примерно до 1975 года, потому что он содержит слишком мало стран, чтобы быть репрезентативным для глобальной погоды по всей Земле.

Это первое исследование показывает нам, что мы несколько ограничены в своих глобальных выводах об изменении климата, поскольку набор данных нельзя считать «репрезентативным» для погоды во всем мире. Конечно, все могло бы быть иначе, если бы у нас был другой набор данных. Но надежда не потеряна: зачем сосредотачиваться на всей земле, когда мы могли бы также смотреть на отдельную страну? Это то, что мы будем делать в следующих шагах.

4. Годовая погода в Германии

Живу в Германии всю свою жизнь, поэтому у меня есть некоторый личный опыт с погодой последних нескольких десятилетий. Теперь возникает очевидный вопрос: могут ли данные подтвердить мое субъективное впечатление, что у нас действительно все более теплые годы с меньшим количеством снега зимой? Давайте запросим наш набор данных, чтобы найти некоторые идеи.

4.1 Среднегодовая температура

В качестве первого шага мы фильтруем все записи в агрегированном наборе данных таким образом, чтобы просматривать только записи, принадлежащие метеостанции в Германии. Для этого нам сначала нужно найти код страны FIPS Германии, который равен GM. Возможно, вы захотите выбрать другой код страны.

# Chose a FIPS country code for limiting our research to an
# individual country
country = "GM"
# Read in data again and filter for selected country
daily_country_weather = \
     spark.read.parquet(daily_country_weather_location) \
    .filter(f.col("CTRY") == country)

Теперь мы можем использовать тот же код PySpark для расчета среднегодовой температуры. На этот раз мы поручим Seaborn выполнить линейную регрессию, а также нанесем результат на то же изображение.

yearly_weather = daily_country_weather \
    .withColumn("year", f.year(f.col("date"))) \
    .groupBy("year").agg(
        f.avg(f.col("avg_temperature")).alias("avg_temperature"),
        f.avg(f.col("avg_wind_speed")).alias("avg_wind_speed"),
        f.avg(f.col("max_wind_speed")).alias("max_wind_speed")
    )\
    .orderBy(f.col("year")).toPandas()
# Plot average temperature per year, this time with a regression
plt.figure(figsize=(24,6))
sns.regplot(data=yearly_weather, 
              x="year", y="avg_temperature", color="r")

Это выглядит намного лучше. Как мы видим, набор данных не содержит никакой информации о Германии примерно до 1925 года. Возможно, вам больше или меньше повезет с другой страной. Но хотя общая средняя температура колеблется довольно незначительно, мы можем наблюдать устойчивый рост, особенно за последние 25 лет. Обратите внимание, что средняя температура достигает новых максимальных значений, а старые минимальные значения больше не достигаются. Это совпадает с моим личным опытом более продолжительного лета и «теплой» зимы без большого количества снега.

Конечно, можно возразить, что эффект, который я наблюдаю, опять-таки связан с данными, которые я использую — я вернусь к этому вполне обоснованному и обоснованному возражению позже.

4.2 Годовые диапазоны температур

Используя Seaborn, мы также можем легко создавать графики с доверительными интервалами температур за все годы. Это даст нам больше информации, чем просто среднее значение.

df = daily_country_weather \
    .withColumn("month", f.month(f.col("date"))) \
    .withColumn("year", f.year(f.col("date"))) \
    .orderBy(f.col("date")).toPandas()
plt.figure(figsize=(16,4))
sns.regplot(data=df, x="year", y="avg_temperature", 
        x_estimator=np.mean, x_ci="sd", ci=100, 
        fit_reg=True, lowess=False, 
        line_kws={'color':'red'})

Мы снова видим явный рост, особенно за последние 20 лет.

4.3 Годовая скорость ветра в Германии

Поскольку у меня также сложилось впечатление, что в последние годы у нас увеличилось количество штормов (с очень заметным ущербом в лесу), мне также было любопытно, смогу ли я найти какое-либо подтверждение в данных, поэтому я также включил скорость ветра в данные. Запрос PySpark выше.

plt.figure(figsize=(24,6))
sns.regplot(data=yearly_weather, 
        x="year", y="avg_wind_speed", color="b")
sns.regplot(data=yearly_weather, 
        x="year", y="max_wind_speed", color="r")

Полученный график выше меня довольно удивителен: средняя скорость ветра не сильно меняется, а максимальная скорость ветра даже уменьшается. Но можно ли доверять сюжету? Честно говоря, я так не думаю: я не специалист по погоде, но моя интуиция подсказывает мне, что «средняя скорость ветра» — не самый лучший показатель. «Максимальная скорость ветра» может быть более интересной, но при максимальном агрегировании теряется вся информация о частоте и продолжительности периодов времени. И, наконец, я не уверен, правильно ли я интерпретировал данные, семантика измерений ветра кажется более сложной, чем для температуры воздуха.

Таким образом, «скорость ветра» нуждается в дополнительных исследованиях, чтобы либо подтвердить, либо опровергнуть приведенный выше график. Но опять же, можем ли мы доверять «температурным графикам»? Это будет исследовано в следующем разделе.

5. Среднемесячная погода

Как узнать, можно ли доверять своим результатам? Очень хороший вариант — сравнить свои результаты с результатами других людей или, что еще лучше, с результатами других людей, которые действительно знают, что делают :)

В Германии официальным органом по погоде и климату является Deutscher Wetterdienst (DWD), штаб-квартира которого находится в Оффенбахе, всего в 10 км от моего дома. Они также предоставляют некоторые графики изменения средней температуры в Германии с течением времени на https://www.dwd.de/DE/leistungen/zeitreihen/zeitreihen.html.

У этих участков есть один интересный аспект: они предоставляются помесячно, а не глобально на весь год. На приведенном выше графике показано, как средняя температура января менялась с течением времени — опять же с явным повышением за последние 20 лет. На самом деле изменения температуры за много лет распределяются по месяцам неравномерно, поэтому имеет смысл создавать разные графики по месяцам. Это то, что мы будем делать дальше, и мы сравним наши результаты с официальными графиками из DWD.

monthly_country_weather = daily_country_weather\
    .groupBy(
        "CTRY", 
        "STATE", 
        f.year("date").alias("year"), 
        f.month("date").alias("month")
    ).agg(
        f.avg(f.col("avg_temperature")).alias("avg_temperature"),
        f.min(f.col("date")).alias("date"),
    )

А теперь постройте результаты, которые отличаются графиком в месяц:

for m in range(1,13):
    data = df[df["month"] == m]
    plt.figure(figsize=(16,4))
    plt.plot(
        data["year"], 
        data["avg_temperature"], 
        label="Month " + str(m))
    plt.legend()
    sns.regplot(
        data=data, 
        x="year", 
        y="avg_temperature")

Теперь эти графики дают нам возможность сравнить наши результаты с результатами официальных экспертов DWD. Когда вы внимательно сравните самый верхний график с графиком из DWD, вы ясно увидите сильное сходство, хотя детали могут различаться. Но лично я более чем доволен результатом, учитывая упрощенный подход.

Как я уже говорил, тенденция повышения средней температуры не затрагивает равномерно все месяцы. Но если вы выберете любой из более теплых месяцев с апреля по октябрь, это снова станет очень очевидным:

Здесь хорошо видно, что средняя температура повышается — конечно, в прошлом были сентябрьские месяцы с такой же средней температурой. Но за ними в более поздние годы последовали довольно холодные или нормальные сентябрьские дни. Примерно с 2000 г. ситуация изменилась, и минимальная средняя температура неуклонно, но явно растет без какого-либо «холодного» сентября между ними.

6. Сводка достижений

Теперь я достиг конца фактического анализа. Позвольте мне резюмировать весь путь от первой части до последних изображений:

  1. Мы загрузили огромный общедоступный набор данных, содержащий данные о погоде.
  2. Мы разобрались с необработанными данными, извлекая некоторую важную информацию из сложного формата файла.
  3. Мы очистили данные, аккуратно заменив подозрительные значения значениями NULL.
  4. Мы выполнили несколько агрегаций, чтобы получить гораздо меньший набор данных, который позволяет нам задавать простые вопросы о некоторых основных показателях погоды (температура, скорость ветра) для разных стран и лет.
  5. Наконец, мы использовали этот набор данных для визуализации температуры в Германии, что подтверждает тезис о повышении температуры.
  6. Мы сравнили наши результаты с результатами известного авторитета в Германии и пришли к выводу, что мы смогли получить аналогичные идеи, используя здравый смысл и немного программирования. Кроме того, я предполагаю, что метеостанции NOAA отличаются от тех, которые использует DWD.

Что касается меня, я доволен результатами на данный момент. Но, как всегда, все можно улучшить.

7. Возможные улучшения

Хотя я надеюсь, что вы согласитесь с тем, что мы смогли добиться хороших результатов, есть еще много деталей, которые можно улучшить или которые потребуют дополнительных исследований:

7.1 Показатели качества данных

Когда мы впервые взглянули на среднюю температуру по всему миру, мы сразу увидели, что приведенный набор данных не содержит достаточно информации, чтобы делать достоверные выводы. Многие страны были недостаточно представлены до 1980 года, что делает набор данных непригодным для действительно глобальных исследований.

Но как насчет данных по отдельным странам, таким как Германия? Графики выглядели нормально, но мы не знаем, сколько метеостанций использовалось в отдельные годы. Можно предположить, что большее количество метеостанций повысит общее качество данных. Простая идея состоит в том, чтобы подсчитать количество различных метеостанций в день и использовать эту информацию в качестве основного показателя качества для измерения надежности любых выводов.

7.2 Скорость ветра

Как я уже писал выше, данные содержат информацию о скорости ветра, но наш анализ оставляет открытым много вопросов, в частности, является ли усредненная скорость ветра хорошей метрикой. Чтобы сделать выводы о скорости ветра, нужны дополнительные исследования, но это тоже было бы интересно.

7.3 Осадки

Дождь – еще одна очень важная тема. В Германии уже пару лет выпадает необычно мало осадков в летние месяцы. Если ситуация не изменится в ближайшие годы, отсутствие осадков создаст множество серьезных проблем, поскольку вода станет дефицитным ресурсом. Что-то, во что я не верил, что скоро произойдет в Германии до прошлого года.

К сожалению, работа с данными об осадках намного сложнее (вас интересует не «среднее» количество осадков, а общее количество осадков за период времени), и я не смог понять точную семантику данных, даже после просмотра документации по формату. .

Заключение

Изменение климата и, в частности, глобальное потепление реальны. Период.

Имея некоторое научное образование, я научился доверять научному дискурсу, включая экспертные оценки и постепенное улучшение знаний и понимания. Поэтому я никогда не сомневался в существовании изменения климата, поскольку большинство (если не все) специалистов в этой области твердо убеждены в его существовании. Конечно, интересный и сложный вопрос, в какой степени человеческая раса ответственна за это изменение — но, насколько мне известно, те же специалисты также убеждены, что это так.

Но доверять экспертам — это одно, а возможность самостоятельно отслеживать результаты — еще лучше. И это еще более важно в широко обсуждаемых областях, таких как изменение климата и глобальное потепление, тема, которая, с одной стороны, окажет огромное влияние на молодые и будущие поколения людей, но, с другой стороны, борется с ложной информацией для человечества. ради краткосрочной прибыли.

Надеюсь, вам понравилось читать эту статью, и, возможно, вы даже узнали что-то новое о работе с данными о погоде, PySpark или о том, где найти большие и значимые объемы данных.