こんにちは、気象予報士のy_kawasaki(取得してもう早、15年経つらしい)です。
前回は、精度が向上するどころか、悪化するという大惨事で終わりましたが、精度向上を目指します。
ここで、日本付近の気象学的知識を投入して考えましょう。そう、天気は西から変わるんです!というわけで、安直に、静岡くらいの天気情報を入れたいと思います。
東京と静岡を読み込んで、風向をDropします。
df_tokyo = pd.read_csv('Tokyo.csv') df_shizuoka = pd.read_csv('Shizuoka.csv') df_tokyo = df_tokyo.drop(['WindDirection', 'WindDirection_most', 'Date'], axis=1) df_shizuoka = df_shizuoka.drop(['WindDirection', 'WindDirection_most', 'Date'], axis=1)
このままでは、カラム名が、東京と静岡で被ってしまうので、変更します。
df_tokyo.columns = ['T_Temp_ave', 'T_Temp_max', 'T_Temp_min', 'T_Prec', 'T_Prec_is', 'T_SunDuration', 'T_SunDuration_is', 'T_WindSpeed', 'T_WindSpeed_max', 'T_RH', 'T_RH_min', 'T_Cloud'] df_shizuoka.columns = ['S_Temp_ave', 'S_Temp_max', 'S_Temp_min', 'S_Prec', 'S_Prec_is', 'S_SunDuration', 'S_SunDuration_is', 'S_WindSpeed', 'S_WindSpeed_max', 'S_RH', 'S_RH_min', 'S_Cloud']
ラベルを作ります。
y_label = [] for i in range(len(df_tokyo) -1): y_label.append(0 if df_tokyo.T_Prec[i + 1] < 1. else 1) df_label = pd.DataFrame({'label': y_label})
ラベルを結合して、
df = pd.concat([df_tokyo, df_shizuoka, df_label], axis=1).dropna()
シャッフルして、
df = df.reset_index(np.random.permutation(df.index), drop=True)
切片をつけて
df['intercept'] = 1
cross validationをします。
cross_val_score(LogisticRegression(), df.drop("label", axis=1), df.label, cv=5).mean()
0.71747329443213614
だめです。まだだめですね。ここでめげてはいけません。名古屋を追加して、風向をDropして、東京と静岡と名古屋とラベルを結合します。そしてシャッフル。切片項を付与!
df_nagoya = pd.read_csv('Nagoya.csv') df_nagoya = df_nagoya.drop(['WindDirection', 'WindDirection_most', 'Date'], axis=1) df = pd.concat([df_tokyo, df_shizuoka, df_nagoya, df_label], axis=1).dropna() df = df.reset_index(np.random.permutation(df.index), drop=True) df['Intercept'] = 1
で、恒例のcross validation、
cross_val_score(LogisticRegression(), df.drop("label", axis=1), df.label, cv=5).mean()
0.74850792065819993
精度が改善しました!念のため大阪も入れてみましょう。
df_osaka = pd.read_csv('Nagoya.csv') df_osaka = df_osaka.drop(['WindDirection', 'WindDirection_most', 'Date'], axis=1) df = pd.concat([df_tokyo, df_shizuoka, df_nagoya, df_osaka, df_label], axis=1).dropna() df = df.reset_index(np.random.permutation(df.index), drop=True) df['Intercept'] = 1 cross_val_score(LogisticRegression(), df.drop("label", axis=1), df.label, cv=5).mean()
0.74257704829365201
特に大きな変化は見られません。
流石に変数が多すぎて、良いモデルとはいえないので、変数選択をして、変数を減らしてみました。
df_t1 = df_tokyo['T_Prec_is'] df_s1 = pd.concat([df_shizuoka['S_SunDuration'], df_shizuoka['S_WindSpeed'], df_shizuoka['S_WindSpeed_max'], df_shizuoka['S_Cloud']], axis=1) df_n1 = pd.concat([df_nagoya['N_Prec'], df_nagoya['N_Prec_is'], df_nagoya['N_WindSpeed_max'], df_nagoya['N_RH']], axis=1) df_o1 = pd.concat([df_osaka['O_RH'], df_osaka['O_Cloud']], axis=1) df = pd.concat([df_t1, df_s1, df_n1, df_o1, df_label], axis=1).dropna() df = df.reset_index(np.random.permutation(df.index), drop=True) df['Intercept'] = 1 cross_val_score(LogisticRegression(), df.drop("label", axis=1), df.label, cv=5).mean()
0.74668767747371056
他の指標も確認しておきます。
指標名 | スコア |
見逃し率 | 0.15034168564920272 |
空振り率 | 0.07061503416856492 |
スレットスコア | 0.3618421052631579 |
バイアススコア | 0.7107438016528925 |
スキルスコア | 0.3922010819143318 |
全体的に改善はしています。
このアプローチでは、この程度が限界のようです。なかなか難しいですね。