第1章
公開されている気象データで気温を予測する
Web APIから東京の過去の気象データを取得し、翌日の最高気温を予測する回帰モデルを作って評価します。
この章で学ぶこと
- Web APIからJSON形式のデータを取得する
- 学習に使う特徴量と、予測したい目的変数を決める
- 時系列の順序を守って学習用・テスト用データに分ける
- 平均絶対誤差(MAE)と単純な予測を使ってモデルを評価する
- 予測結果だけでなく、データの出所や限界も説明する
作るもの
Open-MeteoのHistorical Weather APIから東京の2022〜2025年の日別データを取得し、今日の気象から翌日の最高気温を予測するプログラムを作ります。
Web API → JSON → 表に変換 → 特徴量を作る
↓
結果を評価 ← 予測 ← モデルを学習
機械学習は、データに含まれる規則性をモデルに学習させ、未知のデータに対する分類や数値予測に利用する方法です。この章では、答えとなる数値を予測する回帰を扱います。
この演習のモデルは、気象機関の予報を置き換えるものではありません。機械学習の一連の流れを理解するための小さな実験です。
1. 実行環境を準備する
Python 3が使えるターミナルで、作業用フォルダーを作成します。Windows PowerShellでは次のように実行します。
mkdir ml-weather
cd ml-weather
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install requests pandas numpy scikit-learn matplotlib
macOS・Linuxでは、仮想環境を有効にする行を次のように変更します。
source .venv/bin/activate
仮想環境を使うと、この演習のライブラリをほかのPythonプロジェクトと分けて管理できます。
2. APIからデータを取得する
完成コードをダウンロードし、作業用フォルダーへ保存します。
完成コード:weather_temperature.pyをダウンロード
コード内では、緯度・経度、期間、必要な項目をパラメーターとしてAPIへ送ります。
params = {
"latitude": 35.6762,
"longitude": 139.6503,
"start_date": "2022-01-01",
"end_date": "2025-12-31",
"daily": ",".join([
"temperature_2m_max",
"temperature_2m_min",
"precipitation_sum",
"wind_speed_10m_max",
]),
"timezone": "Asia/Tokyo",
}
response = requests.get(API_URL, params=params, timeout=30)
response.raise_for_status()
payload = response.json()
latitude と longitude は東京付近の座標です。daily には、日ごとの最高・最低気温、降水量、最大風速を指定しています。日別データを指定するときは timezone も必要です。
raise_for_status() は、サーバーがHTTPエラーを返したときに処理を止めます。さらに完成コードでは daily が応答にあるかも確認し、誤った応答をそのまま学習に使わないようにしています。
取得したJSONはpandasの表へ変換し、weather_tokyo.csv に保存します。2回目以降はCSVを使うため、APIへ繰り返しアクセスしません。新しく取得し直したい場合だけ、このCSVを削除してください。
Historical Weather APIの値は、観測値と数値モデルを組み合わせた再解析データです。特定の気象台で直接観測した値と完全に同じとは限りません。利用時はデータの説明とライセンスも確認してください。
3. 学習用の表を作る
1行を1日のデータとし、次のように入力と正解を対応させます。
| 種類 | この章で使う値 |
|---|---|
| 特徴量(モデルへの入力) | 今日の最高・最低気温、降水量、最大風速、翌日の季節を表す値 |
| 目的変数(正解) | 翌日の最高気温 |
翌日の正解は shift(-1) で1行手前へ移します。
frame["target_date"] = frame["time"].shift(-1)
frame["target_max_temperature"] = frame["temperature_2m_max"].shift(-1)
季節は年末から年始へ循環します。12月31日と1月1日が数値上も近くなるよう、翌日の日付をsinとcosの2つの値で表します。
frame["target_day_sin"] = np.sin(
2 * np.pi * frame["target_date"].dt.dayofyear / 365.25
)
frame["target_day_cos"] = np.cos(
2 * np.pi * frame["target_date"].dt.dayofyear / 365.25
)
未来を予測する時点で知ることのできない値を特徴量へ入れると、データリークが起こります。例えば「翌日の最低気温」を入力に使うと、本番ではまだ分からない情報を学習時だけ使うことになります。評価結果が不自然によくなるため、特徴量を決めるときは「予測時点で利用できるか」を必ず確認します。scikit-learnのデータリーク解説
4. 過去で学習し、未来で評価する
ランダムに行を分けると、未来のデータが学習側へ混ざります。この章では日付順の前半80%を学習用、後半20%をテスト用にします。
split_at = int(len(dataset) * 0.8)
train = dataset.iloc[:split_at]
test = dataset.iloc[split_at:]
モデルには複数の決定木の予測を組み合わせる RandomForestRegressor を使います。random_state を固定すると、同じ環境で結果を再現しやすくなります。
model = RandomForestRegressor(
n_estimators=300,
max_depth=12,
min_samples_leaf=3,
random_state=42,
n_jobs=-1,
)
model.fit(train[feature_names], train["target_max_temperature"])
prediction = model.predict(test[feature_names])
fit が規則性を学習し、predict がテストデータの答えを予測します。テストデータは学習や設定の調整には使いません。
5. モデルを評価する
プログラムを実行します。
python weather_temperature.py
初回はインターネットへの接続が必要です。実行すると、学習期間・評価期間と2種類のMAEが表示され、weather_prediction.png が作られます。
MAE(平均絶対誤差)は、予測と正解の差の絶対値を平均したものです。例えばMAEが 2.1 ℃ なら、予測は正解から平均で約2.1 ℃ずれたと読めます。0に近いほどよい指標です。mean_absolute_errorの仕様
この章では、機械学習モデルと次の単純予測を比べます。
明日の最高気温 = 今日の最高気温
複雑なモデルでも、単純予測よりMAEが大きければ改善したとはいえません。データの期間やライブラリのバージョンにより数値は変わるため、特定の正解率ではなく、同じテスト期間で公平に比較できているかを確認してください。
6. 結果を読み解く
作成されたグラフには、評価期間の最後の60日について、実際の最高気温とモデルの予測が表示されます。次の点を観察します。
- 気温が急に変わった日に誤差が大きくないか
- 実際の値より予測の線が滑らかになっていないか
- 機械学習モデルのMAEが単純予測より小さいか
- 4年間というデータ量と東京だけのデータで、どこまで一般化できるか
誤差が大きいこと自体は失敗ではありません。どのような場面で間違えるかを調べ、次の特徴量やデータ収集につなげることが評価の目的です。
トラブル対処
| 症状 | 確認すること |
|---|---|
ModuleNotFoundError |
仮想環境を有効にし、pip install を実行したか |
| APIへの接続エラー | インターネット接続、URL、プロキシ設定。少し時間を置いて再実行する |
| APIの項目を変えたのに結果が変わらない | 保存済みの weather_tokyo.csv を削除してから再実行する |
| グラフの日本語で警告が出る | サンプルのグラフ内は英語表記。変更する場合は日本語フォントも設定する |
| MAEが例と一致しない | 取得データやライブラリの版によって変わる。期間と比較条件を確認する |
やってみよう
- 緯度・経度を自分の地域へ変更し、東京とのMAEを比較してください。
relative_humidity_2m_meanなど別の項目をAPIと特徴量へ追加し、単純予測との差が改善するか確かめてください。- 学習期間を短くしたとき、評価結果がどう変化するか説明してください。
- 「翌日の降水量」を予測する場合、回帰と「雨か雨でないか」の分類のどちらが目的に合うか考えてください。
データや特徴量を増やす前に、それが予測時点で取得できる情報か、利用条件に問題がないかも記録しましょう。