福岡人データサイエンティストの部屋

データサイエンスを極めるため、日々の学習を綴っています。

【LinearRegression】気温の予測【Python】



こんにちは!こーたろーです。


機械学習の基礎トレーニングを暫くやっていなかったので、基礎トレーニングも交えながらやっていきます


今回は、回帰の問題を解いていきます。


身近にある気象データから自分の住んでいるエリアの気温予測を行ってみました。


scikit-learnのLinearRegressionを使うのは1年ぶりぐらいです。


早速やっていきましょう!




必要データのダウンロード



今回は、気象庁のHPから自分の住んでいるエリアの気温データだけを取り出します。


データは2012年4月1日から2022年3月31日までを取り出してみました。


気象庁|過去の気象データ・ダウンロード


サイトはこちらになります。



GUIでポチポチっと選んでダウンロードするだけです。

データの確認



それでは、データを可視化していきます。

import pandas as pd

df = pd.read_csv("data.csv",sep=",", encoding ="SHIFT-JIS")
df






ファイルを表示させたらこんな感じです。


「平均気温(℃)1」「平均気温(℃)2」は今回は使いません。
また、年月日については、「年」「月」「日」に分けてカラムにしておきます。



df.dtypes






型を確認すると、年月日が文字列となっていますので、扱いやすいように変換してから、カラム分けを行います。

df["年月日"] = pd.to_datetime(df["年月日"])

df["年"] = df["年月日"].dt.year
df["月"] = df["年月日"].dt.month
df["日"] = df["年月日"].dt.day

df = df.drop(["年月日","平均気温(℃).1","平均気温(℃).2"], axis =1)
df






データの形としては、こちらで行っていければと思います。


データの調査



続いて、データの理解を深めるために月ごとの平均気温を出していきます。

import matplotlib.pyplot as plt
%matplotlib inline

df_month_mean = df.groupby(["月"])["平均気温(℃)"].mean()

df_month_mean_index =df_month_mean.index
df_month_mean = df_month_mean.values

plt.plot(df_month_mean_index, df_month_mean)






日本の四季がよくわかるカーブになりました。




次に、気温が30度超の日数を年毎にカウントしてみます。

hot_date_bool = (df["平均気温(℃)"] > 30 )
hot_date_count = df[hot_date_bool]

hot_date_count_group = hot_date_count.groupby(["年"])["年"].count()


df_year_count_index = hot_date_count_group.index
df_year_count = hot_date_count_group.values

plt.plot(df_year_count_index, df_year_count)






年毎ですので、冷夏だった年がよくわかります。


データの前処理



さて、実際にデータを使って予測をかけていきます。


過去9年分を学習データにして1年分を確認データにします。


ここで、1年分を予測するのはいいのですが、それよりも現在から7日分遡って気温データを入れたら翌日のデータがでてくるといった予測を行うモデルを作成したいと思います。


こちらの方が、現実的につかえて、なおかつ1年先を予測するよりも精度は高くなるはずです。


データの前処理を行っていきます。


import numpy as np

def data_set(data):
    x = []
    y = []
    temps = list(data["平均気温(℃)"])
    
    for i in range(len(temps)):
        if i < interval : continue
        y.append(temps[i])
        xa =[]
        
        for j in range(interval):
            k = i + j - interval
            xa.append(temps[k])
        x.append(xa)
        
    return(x, y)

train_year = (df["年"] <= 2020)
test_year = (df["年"] > 2020)
interval = 7


x_train,y_train = data_set(df[train_year])
x_test,y_test = data_set(df[train_year])



データをforループの変数jの部分が、ちょうど7日分のデータをリスト化するところです。
そのリストを次々と配列としてxのデータに登録しています。
その処理を、学習用データ及びテストデータに適用します。


モデルの作成(LinearRegression)



今回はscikit-learnのLinerRegressionのモデルを学習させていきます。



from sklearn.linear_model import LinearRegression

model = LinearRegression(normalize = True)
model.fit(x_train,y_train)



モデルのオブジェクトを作成し、学習用データをfitさせて完了です。

モデルの評価



テストデータを代入して、予測を行っていきます。



y_pred = model.predict(x_test)

y_test =np.array(y_test)



y_testは単なるリストですので、nandarrayにして、y_predと同じ型にしておきます(一応)

plt.figure(figsize = (10, 6), dpi=100)
plt.plot(y_test, c = "y")
plt.plot(y_pred, c = "b")
plt.show



可視化してみました。結果は次のようになります。





ところどころ黄色が見えているところは、誤差が大きそうです。


誤差の評価を行います。
今回は簡単な回帰問題ですので、誤差の絶対値平均を取っていきます。


y_diff = abs(y_pred - y_test)

print("average = ", sum(y_diff)/len(y_diff))
print("Max = ", max(y_diff))






誤差の絶対値平均は1.35℃ということなので、かなりの精度で翌日の予測ができています。
一方で、誤差の最大は7℃あります。これは翌日の天気が急激に変わった影響でしょうか。


時間があるときに、もう少し詳細な考察ができればと思います。


ではでは。


Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎