#概要
前回、気温を予測するAIを作りましたが、天気を予測してみようと思い作りました
#環境
OS:Windows
言語:Python
エディター:Geany
#データを集める
AIに学習させるための気象データを集めましょう。
今回は気象庁のHPから過去の気象データをダウンロードします。
年月日,平均気温(℃),降水量の合計(mm),日照時間(時間),最深積雪(cm),平均風速(m/s),最多風向(16方位),平均蒸気圧(hPa),平均現地気圧,等のデータをダウンロードしましょう。
#説明変数がテキストだった場合どうすればよいか?
今回は説明変数の中に風向き(16方向)がありますが、そのままでは使えません。なのでテキストを種類ごとにナンバリングしてくれる機能を使います。
from sklearn import preprocessing
label = preprocessing.LabelEncoder()
label.fit(data)
labels_id = le.transform(data)
上2行はLabelEncoderの宣言。
label.fit(data)はラベルとラベルIDの対応づけを行います。この文字列は0にしよう,みたいなことを決めています。これはle.fit(ラベルの一次元リスト)で行います。
ラベルとラベルIDの対応づけの変換することができます。これはtransform(ラベルの一次元リスト)で行います。返り値に配列が来ます。
#AIモデルを決める
Scikit-learnのアルゴリズムチートシートを見てモデルを決めます。
今回は「サンプル数は50以上」→「カテゴリー予測」→「ラベル付きのデータを持っている」→「サンプル数は10万以下」としてLinerSVC(線形)やkneighbors classifier(非線形),ensemble classifier(非線形)等が選べます。
3つ試したところensemble classifierのスコアが一番良かったのでensemble classifierのコードのみ載せておきます。
#ensemble classifier(非線形)
作成したAIモデルにスコアをつけるプログラム。
値が大きいほど良い (0<score<1)
今回はあらかじめ説明変数のファイルと目的変数のファイルを分けています。(data.csv、targetGOZEN.csv)
# -*- coding: Shift-JIS -*-
import re
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import svm,linear_model,preprocessing,ensemble
from sklearn.neighbors import KNeighborsClassifier
np.set_printoptions(threshold=np.inf)
#年月日,平均気温(℃),降水量の合計(mm),日照時間(時間),最深積雪(cm),平均風速(m/s),最多風向(16方位),平均蒸気圧(hPa),平均現地気圧(hPa)
#天気概況(昼:06時~18時) 天気概況(夜:18時~翌日06時)
#気象データを説明変数として読み込む
f=open('data.csv','r')
data=re.split('[,\n/]',f.read())
f.close()
del data[-1]
print(data)
del data[::11]#西暦を消す
#方角をナンバリングする
dire=[]
for i in data[7::10]:
dire.append(i)
le = preprocessing.LabelEncoder()
le.fit(dire)
labels_id = le.transform(dire)
#方角データをナンバリング方角に置き換える
j=0
for i in range(len(data)):
if(i%10==0):
data[i+7]=labels_id[j]
j+=1
#二次元numpy配列にする
data = np.array(data, dtype='float64')
data=data.reshape(int(len(data)/10),10)
#天気データを目的変数とする
f=open('targetGOZEN.csv','r')
target=re.split('[,\n/]',f.read())
f.close()
del target[-1]
target = np.array(target, dtype='str')
#明日の天気を予測するために説明変数と目的変数を1日分ずらす
data=np.delete(data,len(target)-1,0)
target=np.delete(target,0)
#学習用データとテストデータに分ける
traind, testd, traint, testt =train_test_split(data,target, test_size=0.2)
#学習モデルの生成と学習
clf = ensemble.RandomForestClassifier(criterion='entropy', n_estimators=1000, random_state=1, n_jobs=2,class_weight="balanced")
clf.fit (traind,traint)
#スコアの表示
print(clf.score(testd,testt))
結果はこうなります。
スコア:0.1761904761904762
#まとめ
スコアが低いですが今回はクラス分類での正答率をスコアにしているので、例えば本来の天気が「晴れ」に対して「晴れのち曇り」という予測が出てきた場合、当たらずとも遠からずといった感じですがスコアでは不正解にカウントされています。
自分で予測を確認したところそこまで大きな間違いは感じられませんでしたし、逆にぴったり当たっている予測が17%ほどあるということはそこそこなスコアだと思います。