Загрузка данных, запрос исторической погоды, обучение модели ML

Европейский центр среднесрочного прогнозирования погоды (ECMWF) предоставляет прогнозы погоды по всему миру. Если у вас есть задача машинного обучения, для которой в качестве входной функции требуется погода (например, вы пытаетесь спрогнозировать спрос на зонты или мороженое), вы можете использовать данные ЕЦСПП для обучения модели машинного обучения на исторических данных и использовать прогнозы ЕЦСПП в реальном времени, когда предсказание.

Недавно Google открыл набор конвейеров Apache Beam, которые значительно упрощают включение данных о погоде в проекты по анализу данных и машинному обучению. Давайте возьмем это за спину.

Пример задачи машинного обучения

Я хочу использовать данные о погоде в качестве входных данных для модели, которая предсказывает, как долго жители Нью-Йорка будут хранить взятые напрокат велосипеды. Моя гипотеза состоит в том, что люди будут оставлять велосипеды на более короткие периоды времени, если будет слишком жарко или дождливо. Итак, давайте используем погоду в качестве одной из входных характеристик.

Данные об аренде велосипедов в Нью-Йорке доступны в виде общедоступного набора данных в BigQuery. Попробуйте запросить его в BigQuery:

SELECT 
  start_station_name,
  EXTRACT(hour from starttime) AS hourofday,
  EXTRACT(dayofweek from starttime) AS dayofweek,
  tripduration,
FROM `bigquery-public-data.new_york_citibike.citibike_trips`
LIMIT 5

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

CREATE OR REPLACE MODEL weather.rental_duration_nowx
OPTIONS(model_type='boosted_tree_regressor', 
        input_label_cols=['tripduration']) AS
SELECT 
  start_station_name,
  EXTRACT(hour from starttime) AS hourofday,
  EXTRACT(dayofweek from starttime) AS dayofweek,
  tripduration
FROM `bigquery-public-data.new_york_citibike.citibike_trips`
WHERE EXTRACT(year from starttime) = 2018

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

Настройка среды

  1. Перейдите в Консоль Google Cloud и запустите блокнот Vertex Workbench. Я выбрал относительно минимальную машину — последнюю версию TensorFlow без графических процессоров и n1-standard-2 — потому что мы не собираемся много работать на ноутбуке.
  2. Откройте JupyterLab по ссылке в консоли и запустите терминал.
  3. Чтобы получить данные из ECMWF, вы должны зарегистрироваться в ECMWF и получить ключ API при входе в систему.
  • Климатические данные (Коперник): зарегистрируйся и получи свой API-ключ. Поместите URL-адрес и ключ в файл в домашнем каталоге с именем ~/.cdsapirc, как показано на странице. Эти данные бесплатны, но вам нужно будет зарегистрироваться и получить ключ API.
  • Прогнозы погоды (MARS): зарегистрироваться и получить API-ключ. Поместите URL-адрес, адрес электронной почты и ключ в ~/.ecmwfapirc, как показано на странице. Эти данные платные (подробности см. в последнем разделе этого блога).

Чтобы следовать вместе со мной, зарегистрируйтесь на Copernicus и настройте ключ. Канал MARS является необязательным.

3. Установите пакет инструментов погоды:

pip install google-weather-tools

3. Создайте набор данных BigQuery, в который вы будете загружать данные для запросов:

bq mk weather

4. Создайте корзину для временного хранения загруженных файлов:

PROJECT=$(gcloud config get-value project)
BUCKET=${PROJECT}-ecmwf
gsutil mb gs://$BUCKET

Обратите внимание на имя созданного сегмента. Он понадобится вам на следующем шаге.

Скачать Исторические наблюдения

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

5. Скачайте пример конфигурации era5_example_config.cfg:

wget https://raw.githubusercontent.com/google/weather-tools/main/configs/era5_example_config.cfg

6. Измените пример, чтобы он отражал нужные нам данные (обязательно отредактируйте BUCKET и KEY из ~/.cdsapirc в этом файле):

  • набор данных, переменная: то, что мы хотим (варианты см. в списке наборов данных и документации набора данных). Я выбрал почасовые данные о температуре и количестве осадков.
  • target_path: обязательно измените имя корзины из моего примера на имя вашей корзины из шага 4.
  • api_key: не забудьте установить здесь свои значения .cdsapirc.
  • область: широта-долгота, включающая Нью-Йорк (широта = 41, долгота = -74)

6. Загрузите данные:

weather-dl era5_example_config.cfg \
   --project $PROJECT --region us-west1 \
   --runner DataflowRunner --temp_location=gs://${BUCKET}/temp

Это запустит задание Dataflow, которое вы можете отслеживать на https://console.cloud.google.com/dataflow.

Дождитесь завершения задания (около 6 минут). Обратите внимание, что в январе у нас всего пара дней.

7. Просмотрите журналы для шага FetchData, чтобы проверить, какие файлы загружаются:

8. Убедитесь, что данные загружены:

gsutil ls -l gs://$BUCKET/era5/2018/01/01.nc

[ДОПОЛНИТЕЛЬНО] Загрузите исторические данные за один год

Загрузка исторических данных за год займет 1–10 часов в зависимости от того, есть ли у вас платная лицензия ECMWF. Так что можете смело пропускать этот шаг. Чтобы увидеть, как все работает, достаточно небольшого набора данных, загруженного на предыдущем шаге.

Примечание. Вы можете ускорить загрузку, если используете несколько лицензий в конфигурациях. Документация подразделов параметров (https://github.com/google/weather-tools/blob/main/Configuration.md#subsections) описывает, как это сделать. Таким образом, команды людей с лицензиями CDS могут быстрее получать данные вместе.

9. Расширьте конфигурацию эры на все месяцы и все дни, указав диапазон дат, а не перечисляя отдельные месяцы/дни/и т. д. (как и раньше, не забудьте поменять ВЕДРО и КЛЮЧ в листинге ниже).

Перезапустите задание. Уже загруженные данные будут пропущены. Еще раз: это займет несколько часов. Так что не стесняйтесь пропустить этот шаг, если вы просто хотите посмотреть, как все работает.

Загрузить данные в BigQuery

Вы загрузили данные ERA5, но они в формате netcdf и не очень подходят для их включения в модели машинного обучения. Давайте загрузим его в BigQuery, чтобы сделать данные более удобными.

10. Загрузите данные в BigQuery

weather-mv --uris "gs://$BUCKET/era5/**.nc" \
           --output_table $PROJECT.weather.newyork \
           --temp_location gs://$BUCKET/temp \
           --direct_num_workers 2

Я запускаю его «локально», но вы также можете запустить его в Dataflow, указав DataflowRunner, как с инструментом Weather-DL:

weather-mv --uris "gs://$BUCKET/era5/**.nc" \
           --output_table $PROJECT.weather.newyork \
           --project $PROJECT --region us-west1 \
           --runner DataflowRunner \
           --temp_location=gs://${BUCKET}/temp

11. Изучите данные, которые мы только что получили:

SELECT 
  time, longitude, latitude,
  ROUND(t2m, 2) as temperature, 
  ROUND(tp, 2) AS rain
FROM weather.newyork
LIMIT 5

Результат должен быть примерно таким:

Обучайте модели машинного обучения, используя данные о погоде

12. Соедините данные о погоде с данными о велосипеде, чтобы мы знали погоду в месте/времени каждой аренды:

SELECT 
  start_station_name,
  EXTRACT(hour from starttime) AS hourofday,
  EXTRACT(dayofweek from starttime) AS dayofweek,
  tripduration,
  ROUND(t2m, 2) as temperature, 
  ROUND(tp, 2) AS rain
FROM weather.newyork
JOIN `bigquery-public-data`.new_york_citibike.citibike_trips
ON ABS(DATETIME_DIFF(EXTRACT(DATETIME FROM time), starttime, HOUR)) < 3
   AND ABS(start_station_latitude - latitude) < 0.5
   AND ABS(start_station_longitude - longitude) < 0.5
LIMIT 5

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

CREATE OR REPLACE TABLE weather.citibike_trips AS
WITH citibike_trips AS (
    SELECT 
    start_station_name,
    EXTRACT(hour from starttime) AS hourofday,
    EXTRACT(dayofweek from starttime) AS dayofweek,
    tripduration,
    TIMESTAMP_ADD(TIMESTAMP_TRUNC(CAST(starttime AS TIMESTAMP), HOUR), 
                  INTERVAL CAST(ROUND(EXTRACT(hour from starttime)/6) AS INT64) HOUR) AS time,
    ROUND(start_station_latitude*2)/2 AS latitude,
    ROUND(start_station_longitude*2)/2 AS longitude
    FROM `bigquery-public-data`.new_york_citibike.citibike_trips
    WHERE EXTRACT(YEAR FROM starttime) = 2018
)
SELECT 
    trips.*, 
    ROUND(t2m, 2) as temperature, 
    ROUND(tp, 2) AS rain
FROM citibike_trips trips
JOIN weather.newyork
USING (time, latitude, longitude)

14. Насколько важна погода? Обучите модель XGBoost с погодой:

CREATE OR REPLACE MODEL weather.rental_duration_wx
OPTIONS(model_type='boosted_tree_regressor', 
        input_label_cols=['tripduration']) AS
SELECT 
  start_station_name,
  hourofday,
  dayofweek,
  temperature, 
  rain,
  tripduration
FROM weather.citibike_trips

15. Сравните ошибку оценки:

Без учета погоды: средняя абсолютная ошибка = 265 секунд.

С погодой: средняя абсолютная ошибка = 245 секунд.

Успех! Мы можем лучше прогнозировать продолжительность аренды велосипедов, когда знаем погоду …

[НЕОБЯЗАТЕЛЬНО] Загрузите нужные данные прогноза погоды.

В моем рабочем процессе (выше) я использовал данные повторного анализа, которые создаются через несколько дней после факта. Таким образом, вы не можете использовать его для машинного обучения в реальном времени. Для машинного обучения в реальном времени вам нужны данные прогноза погоды, которые создаются и распространяются практически в режиме реального времени. Это не бесплатно, и вам нужна коммерческая лицензия от ЕЦСПП, чтобы загружать данные прогноза.

16. Скачайте пример конфигурации configs/mars_example_config.cfg:

wget https://raw.githubusercontent.com/google/weather-tools/main/configs/mars_example_config.cfg

17. Ключевое изменение, которое вам нужно внести, — это строка param:

target_path=gs://BUCKET/newyork/
param=max2t6/min2t6/maxtpr6
step=6/12/18/24
time=0500
date=2018-01-01/to/2018-12-31
  • param: погодные переменные, которые нам нужны, — это 6-часовая максимальная и минимальная температура на высоте 2 м над поверхностью (примерно температура на высоте лица человека) и 6-часовая максимальная интенсивность осадков. Здесь вы можете найти описания всех параметров погоды.
  • шаг, время, дата: Получите прогнозы на 6, 12, 18, 24 часа вперед, сделанные в 05:00 UTC (что в Нью-Йорке полночь), и получите все прогнозы, сделанные в 2018 году.

Теперь загрузите данные с помощью Weather-dl и добавьте их в BigQuery с помощью Weather-mv. В остальном рабочий процесс остается прежним!

Наслаждаться!