以前ガッツリ Tableau を使っていた頃、各種 Viz の腕試し的な催しに参加し、スキルを高めるのに役立った。その中で一つ印象的だったテーマが桜の開花予想。Tableau は BI ツールなので予測そのものは出来ず、データを見栄え良く可視化するだけだ。今回は Google の機械学習ソリューションの中から使い慣れた BigQuery で利用可能な BigQuery ML で 2020年東京の桜の開花日を予測してみよう。
目次/Contents
活用データ
今回利用したデータは以下の 2つ
桜の開花予測モデル
機械学習で予測をする前に簡単な桜🌸開花日予測モデルを 2つ紹介しよう。有名なので見聞きしたことがあるかもしれないが、
- 400℃の法則
- 600℃の法則
それぞれその年の 2月1日以降の平均気温(400℃の法則)・最高気温(600℃の法則)を累積していき 400℃/600℃を突破した日が開花日と予測するモデルだ。シンプルで分かりやすいし、これがけっこう良く当たる。
実際の実績で確認してみよう。下表の各列はそれぞれ次の通り
- date その年の実際の桜の開花日
- date2 その日付のみ
- cumAvg 実際の開花日の累積平均気温
- _400 その年の累積平均気温が 400℃を突破した日
- dif_400 → 実際の開花日との差
- cumMax 実際の開花日の累積最高気温
- _600 その年の累積最高気温が 600℃を突破した日
- dif_600 → 実際の開花日との差
赤い色の行や太字の部分があるが現時点では無視して欲しい。
けっこう良く当たる は言い過ぎたかもしれない。当たらずとも遠からずの年もあるが、最大 8日ズレた日もあった。
累積気温で見ると、累積平均気温 330℃で開花している年もあれば、431℃必要な年もあった。600℃の法則の方も 550〜653℃と 100℃以上の幅がある。
この要因は何だろうか? この辺が紐解ければ、もっと精緻な予測ができそうだ。
ともあれ、実はこの累積気温という考え方は桜の開花予想を機械学習で行うに当たり非常に助けになる。それはまた後述。
そして、これから過去データを使って機械学習を行い、最終的には過去実績との比較・評価に加えて実践的に今年 2020年これからの開花予想を行っていく。少なくともこの 400℃・600℃の法則での予測は上回るとして、日付ドンピシャか少なくともせいぜい前後一日のズレ以内に収めることを目指す。
まずは気象庁データをそのまま活用して線形回帰モデルで予測
気象庁データにラベルの追加
気象庁データから桜の開花に関連のあるもの(列)のみを残し、まずはロジスティック回帰モデルで開花日を予測してみよう。なお、このシリーズでは追って線形回帰モデルでの予想や K 平均法クラスタリングモデルも出てくるのでお楽しみに。
気象庁データに一列ラベル列を追加し、そのシーズンの開花前を FALSE 、開花後は TRUE とした。そうするとこんな風になる。
このサンプルはちょうど 2001年のもので、この年は 3/23 に開花している。
念の為各列の意味は、
- avgTemp その日の平均気温
- maxTemp その日の最高気温
- minTemp その日の最低気温
このデータを 2000年 9月から 2019年 4月までの 20年間分用意した。
さて、このままこのデータでロジスティック回帰モデルで学習を行っても、正しい予測はできない。BigQuery ML はこのデータ塊の一つひとつのレコードをそれぞれ独立したデータとして捉える。逆に言うと、データの流れや蓄積みたいなものは理解できない。三寒四温で行きつ戻りつはするけれど、それでもちょっと長い目で見ると段々暖かくなって春めいてくるよね みたいな感覚はないのだ。
それでもまぁ試しに BigQuery ML で学習を行って予測させてみると、、正解率は僅かに 58% 程だった。そりゃそうだ。同じような平均気温、最高気温なのに TRUE の日もあれば FALSE もある。秋なんてそれが FALSE だけだし!
という訳でここで 400℃の法則や 600℃の法則のように累積気温が役に立つ。これでそのシーズンの気温変化の流れが表現可能だ。
実際のデータはこんな体 ↓
cumAvg が 2/1 以降の平均気温の累計、cumMax が同じく最高気温の累積だ。
なお、cumMaxWin は累積を始めるのが早く、前年の 10/1 以降。これについては後述。
BigQuery ML で学習させる際には日々の気温情報はノイズになるので削除した。
まずはこれで学習と予測を行ってみよう。2015年までのデータで学習させ 16,17年データで評価を行い 18,19年の予測をさせてみる。なお、今回のシリーズを通して細かいパラメーターの手動調整・設定は行っておらず基本的に BigQuery ML に任せている。(一箇所を除いて。それは後述する)
モデルの作成と学習
create or replace model `cherryBlossom.cherry3_model`
options(
model_type = 'logistic_reg'
,input_label_cols = ['label']
) as
SELECT
* except( date )
FROM `cherryBlossom.cherry3`
where
date < '2015-10-1'
2018,19年の予測を行う
SELECT * FROM ML.predict(MODEL `cherryBlossom.cherry3_model`,
(
select
*
from
cherryBlossom.cherry3
where
date > '2017-9-30'
)
)
結果は以下の通り。predicted_label が BigQuery ML(BQML)による予測、label が実際の実績値だ。
- 2018年 4日遅い
- 2019年 2日早い
2年分だけだが、あまり芳しくない。これでは 400℃/600℃の法則と変わらない、、、
最初に 400℃/600℃の法則での予測を評価した時にも記載したが、このズレの要因を探って対策していこう。
桜の開花のメカニズム
春になって暖かくなってくると桜が咲くのを僕らは毎年見ている。じゃあ、「暖かくなってくると」の程度はどのくらいなのだろうか? 累積気温だと 100℃の幅があったのでそれだけではないようだ。ある閾値を超えると咲くのか? それが何日か続く必要があるのだろうか?
気象予報士会埼玉支部のこのイラストがいたく気に入ってしまったので是非紹介させて欲しい。
詳細はそちらをご覧いただきたいがポイントは以下の 2点
- 休眠期には冬しっかり寒く充分休眠できることが必要
→ 暖冬の場合にはより多くの累積気温が必要となる - 開花の直前に冷え込むとより多くの累積気温が必要となる
これらをデータで表現して説明変数として取り入れてより精緻な機械学習・予測を行いたい。
実はこれもあって冬からの累積気温も含めてみたのだが、この方法はうまく行かなかった。
色々トライアル&エラー(トライ&エラーじゃあないよw)を繰り返し、次の 2項目をラベルとすることにした。
- 秋冬の寒さの指標 そのシーズンの 10/1〜2末の毎日の平均気温の平均 下表 win 列
- 開花直前の気温 3/1〜3/15 の毎日の平均気温の平均 下表 firstMar 列
データとしてはこんな体 ↓
これで学習させ、また 2018,19年分を予測してみると、
2018年は無事一致したが 2019年分は BQML の予測の方が 3日早かった。もっと精度を高めたい。
BQML 線形回帰モデルで桜の開花日を直接予測する
BigQuery ML は線形回帰で数値を直接予測させることも出来る。これを使って直接開花日を予測してみよう。
各年の実開花日データ等に先程ロジスティック回帰モデルで使った win ラベルと firstMar ラベルを加えた。実際に機械学習に使った列は下コード参照。
create model `cherryBlossom.cherryAnal_model`
options(
model_type = 'linear_reg'
,input_label_cols = ['date2']
) as
SELECT
cumAvg
, cumMax
, win
, firstMar
, date2
FROM `cherryBlossom.cherryAnal`
where
year < 2020
なお、ここで使われているテーブル名やモデル名はデイヴ・ムステインが分析的 / analystic について、「あぁ、あいつらは Anal だからなw」と言っていたことに端を発しているだけで他意はない。
レコード数が少ないので全年分を予測させてみよう。
SELECT
year
,predicted_date2
,date2
FROM
ML.predict(MODEL `cherryBlossom.cherryAnal_model`,
(
select
date2
,year
, cumAvg
, cumMax
, win
, firstMar
from
cherryBlossom.cherryAnal
)
)
出力された結果は次の通り
400℃・600℃の法則に比べればかなり良いがそれでもまだ最大 3.8日のズレがある。
更に予測の精度を高めるにはどうしたら良いだろうか? 続く Part 2 に詳述していこう。