見出し画像

スギ花粉飛散量のデータ分析@機械学習編②

前回まで一通りデータ分析を行いました。

今回は、風速のデータを用いて改善されるかチェックしていこうと思います。

風速データ読み取り・前処理

前回と同じようなことをやるので、細かいことは省略します。
風速データを読み取り、前処理を行い、以下の表にまとめました。
今回は最大瞬間風速と日平均風速を用いて、各種lagデータも用いました。

このデータと前のデータを合わせて、以下の表にまとめました。

これらのデータを用いて、機械学習を行っていきます。

ランダムフォレスト

複雑さを減らしたランダムフォレストのコード及び結果を以下に記します。

import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score

# 説明変数1と目的変数1
X1 = merged_df10[["平均気温(℃)_t", "東京23区_lag1", "東京23区_rol3", "週番号", "東京23区_lag2", "東京23区_lag3",
                  "最大風速_東京", "平均風速_東京", "最大風速_東京_lag1", "最大風速_東京_lag2", "最大風速_東京_lag3", "平均風速_東京_lag1", "平均風速_東京_lag2", "平均風速_東京_lag3"]]
y1 = merged_df10['東京23区']

# 説明変数2と目的変数2
X2 = merged_df10[["平均気温(℃)_t", "東京23区外_lag1", "東京23区外_rol3", "週番号", "東京23区外_lag2", "東京23区外_lag3",
                  "最大風速_東京", "平均風速_東京", "最大風速_東京_lag1", "最大風速_東京_lag2", "最大風速_東京_lag3", "平均風速_東京_lag1", "平均風速_東京_lag2", "平均風速_東京_lag3"]]
y2 = merged_df10['東京23区外']


# 訓練データとテストデータに分割
X1_train, X1_test, y1_train, y1_test = train_test_split(X1, y1, test_size=0.2, random_state=42)
X2_train, X2_test, y2_train, y2_test = train_test_split(X2, y2, test_size=0.2, random_state=42)

# ランダムフォレスト回帰モデルのインスタンスを作成
regressor1 = RandomForestRegressor(n_estimators=100, max_depth=3, random_state=42)
regressor2 = RandomForestRegressor(n_estimators=100, max_depth=3, random_state=42)

# モデルの訓練
regressor1.fit(X1_train, y1_train)
regressor2.fit(X2_train, y2_train)

# 訓練データでの予測
y1_train_pred = regressor1.predict(X1_train)
y2_train_pred = regressor2.predict(X2_train)

# テストデータでの予測
y1_test_pred = regressor1.predict(X1_test)
y2_test_pred = regressor2.predict(X2_test)

# 評価
print("東京23区の予測モデル")
print("訓練データの平均二乗誤差(東京23区): ", mean_squared_error(y1_train, y1_train_pred))
print("テストデータの平均二乗誤差(東京23区): ", mean_squared_error(y1_test, y1_test_pred))
print("訓練データのR^2スコア(東京23区): ", r2_score(y1_train, y1_train_pred))
print("テストデータのR^2スコア(東京23区): ", r2_score(y1_test, y1_test_pred))
print()
print("東京23区外の予測モデル")
print("訓練データの平均二乗誤差(東京23区外): ", mean_squared_error(y2_train, y2_train_pred))
print("テストデータの平均二乗誤差(東京23区外): ", mean_squared_error(y2_test, y2_test_pred))
print("訓練データのR^2スコア(東京23区外): ", r2_score(y2_train, y2_train_pred))
print("テストデータのR^2スコア(東京23区外): ", r2_score(y2_test, y2_test_pred))

いやぁ、、、そんなに変わらないっすね。。。。
特徴量は増やせばいいってもんじゃないっぽいですね。。。

ニューラルネットワーク

次にニューラルネットワークを用いました。

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# 説明変数1と目的変数1
X1 = merged_df10[["平均気温(℃)_t", "東京23区_lag1", "東京23区_rol3", "週番号", "東京23区_lag2", "東京23区_lag3",
                  "最大風速_東京", "平均風速_東京", "最大風速_東京_lag1", "最大風速_東京_lag2", "最大風速_東京_lag3", "平均風速_東京_lag1", "平均風速_東京_lag2", "平均風速_東京_lag3"]]
y1 = merged_df10['東京23区']

# 説明変数2と目的変数2
X2 = merged_df10[["平均気温(℃)_t", "東京23区外_lag1", "東京23区外_rol3", "週番号", "東京23区外_lag2", "東京23区外_lag3",
                  "最大風速_東京", "平均風速_東京", "最大風速_東京_lag1", "最大風速_東京_lag2", "最大風速_東京_lag3", "平均風速_東京_lag1", "平均風速_東京_lag2", "平均風速_東京_lag3"]]
y2 = merged_df10['東京23区外']


# 訓練データとテストデータに分割
X1_train, X1_test, y1_train, y1_test = train_test_split(X1, y1, test_size=0.2, random_state=42)
X2_train, X2_test, y2_train, y2_test = train_test_split(X2, y2, test_size=0.2, random_state=42)

# データの標準化
scaler1 = StandardScaler()
scaler2 = StandardScaler()
X1_train_scaled = scaler1.fit_transform(X1_train)
X1_test_scaled = scaler1.transform(X1_test)
X2_train_scaled = scaler2.fit_transform(X2_train)
X2_test_scaled = scaler2.transform(X2_test)

# ニューラルネットワークモデルの作成
def create_nn_model(input_dim):
    model = Sequential()
    model.add(Dense(32, input_dim=input_dim, activation='relu'))
    model.add(Dense(16, activation='relu'))
    model.add(Dense(1, activation='linear'))
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model

# モデルの訓練
nn_model1 = create_nn_model(X1_train.shape[1])
nn_model1.fit(X1_train, y1_train, epochs=50, batch_size=8, verbose=0)

nn_model2 = create_nn_model(X2_train.shape[1])
nn_model2.fit(X2_train, y2_train, epochs=50, batch_size=8, verbose=0)

# 訓練データでの予測
y1_train_pred = nn_model1.predict(X1_train)
y2_train_pred = nn_model2.predict(X2_train)

# テストデータでの予測
y1_test_pred = nn_model1.predict(X1_test)
y2_test_pred = nn_model2.predict(X2_test)

# 評価
print("東京23区の予測モデル")
print("訓練データの平均二乗誤差(東京23区): ", mean_squared_error(y1_train, y1_train_pred))
print("テストデータの平均二乗誤差(東京23区): ", mean_squared_error(y1_test, y1_test_pred))
print("訓練データのR^2スコア(東京23区): ", r2_score(y1_train, y1_train_pred))
print("テストデータのR^2スコア(東京23区): ", r2_score(y1_test, y1_test_pred))
print()
print("東京23区外の予測モデル")
print("訓練データの平均二乗誤差(東京23区外): ", mean_squared_error(y2_train, y2_train_pred))
print("テストデータの平均二乗誤差(東京23区外): ", mean_squared_error(y2_test, y2_test_pred))
print("訓練データのR^2スコア(東京23区外): ", r2_score(y2_train, y2_train_pred))
print("テストデータのR^2スコア(東京23区外): ", r2_score(y2_test, y2_test_pred))

やはりニューラルネットワークの方が安定してますね。訓練データとテストデータの差が少ないです!!

ただ、R^2スコアはあまり改善されませんでした。風速の観測所とスギ花粉の観測所の相関が少ないのかもしれません。

まとめ

いかがでしたでしょうか。
実はこれが自分で行ったデータ分析の初の成果物です!

データの読み取りと前処理で8割以上の時間を費やしてましたが、このフェーズが最も大事であることを実感しました。

これからはもっとスムーズに行い、さらに精度の高い成果物を作成していきたいです。

みなさま!今後も引き続き、よろしくお願いしますね!!


この記事が気に入ったらサポートをしてみませんか?