前回のおさらい
前回はscikit-laernを用いた重回帰分析で積雪深を予測してみました。
モデルには、気象庁が公開している気象データのうち、「月」「日」「気圧」「気温」「湿度」「降水量」「降雪量」を説明変数として入力し、「積雪深」を目的変数として得る方法としていました。
さらに線形回帰モデルによる分析の結果、学習データとテストデータに対する決定係数がいずれも0.6以上出ていたことから、一定の予測精度を得ることができました。
一方で積雪深の予測値と実際の値の誤差を評価指標としてRMSEで求めた結果、約18cmと比較的大きな誤差が確認できました。

考察として、使用した気象データのばらつきが大きいことや、各気象要素と積雪深が線形の関係でないという可能性が示唆されました。
そこで今回は、非線形モデルを用いた重回帰分析で積雪深を予測し、得られた予測結果の誤差を線形回帰モデルと比較と評価をします。
month | day | atmosphere | temperature | humidity | precipitation | snow_falling | snow_depth | |
12 | 6 | 1008.9 | 5.2 | 82 | 0 | 0 | 0 | |
12 | 7 | 995.3 | 7.7 | 79 | 3 | 0 | 0 | |
12 | 8 | 1009.6 | 1.6 | 62 | 0.5 | 2 | 2 | |
12 | 9 | 1009.7 | 7.7 | 83 | 4.5 | 0 | 0 | |
12 | 10 | 1017.6 | 0.3 | 57 | 0 | 0 | 0 | |
12 | 11 | 1022 | -1.9 | 64 | 0 | 1 | 1 | |
12 | 12 | 1014.1 | -0.7 | 78 | 7 | 6 | 6 | |
12 | 13 | 1018.2 | -1.9 | 58 | 0.5 | 1 | 7 | |
12 | 14 | 1022 | -1.9 | 54 | 0 | 0 | 5 |
線形・非線形とは
線形と非線形の違いについて簡単に説明をすると、説明変数と目的変数の関係が比例かどうかによって区別をすることができます。
線形回帰では説明変数と目的変数の関係を左の図のような直線で近似しますが、変数間の関係が単純である場合に有効です。一方で、非線形回帰は右の図のように曲線で表現するため線形回帰モデルでは表現できない複雑な関係性を捉えることができます。
今回の分析では、各気象情報と積雪深の関係が線形でないと考えたため、非線形モデルを用いて予測モデルを作成します。

今回やること
冒頭でも記述した通り、前回の取り組みで各気象情報と積雪深が線形の関係にないことが示唆されました。これを踏まえて、今週は非線形回帰分析を用いて積雪深の予測を行います。
さらに、非線形回帰モデルによって得た誤差を、線形回帰モデルで得られた誤差との比較をし、2つのモデルの精度の評価をしていきます。
データ整理
データ分析について色々と調べた結果、説明変数が多すぎると、予測値が低下するという情報を得たため、7つの説明変数を4つに削減し、モデルの精度向上を図ります。
なお、説明変数が多くなる場合には機械学習を用いる方が適している可能性もあります。
まず説明変数の選定においては積雪深との関連が比較的低いと考えられる「月」「日」「気圧」を説明変数から除外しました。
したがって今回モデルに与える説明変数は「降水量」「気温」「湿度」「降雪量」の4つとなります。
precipitation | temperature | humidity | snow_falling | snow_depth | |
2.5 | -1.9 | 76 | 6 | 28 | |
0 | -6.7 | 56 | 0 | 28 | |
0 | -5.9 | 56 | 1 | 27 | |
0 | -5.3 | 56 | 2 | 27 | |
0 | -2.1 | 56 | 1 | 27 |
さらに、データ量を2023年〜2024年の約2年分増やしました。
学習
今回使用する学習モデルは前回と同様にLinearRegressionクラスを使用します。
LinearRegressionは本来、説明変数と目的変数が線形関係にあることを前提としたモデルですが、特徴量を非線形に変換することで結果として非線形の回帰分析を行うことができるようです。
さらに、モデルに非線形な特徴量を与える手段として、多項式回帰という手法を用いてみました。
多項式回帰を用いることで、元の説明変数を累乗することで新たな特徴量を生成し、元の特徴量と組み合わせて学習に用いることで非線形な関係性を線形モデルで近似することが可能となります。
#非線形特徴量の処理
poly = PolynomialFeatures(degree=3, include_bias=False)
x_train_poly = poly.fit_transform(x_train_scaled)
x_test_poly = poly.transform(x_test_scaled)
# 線形重回帰モデル(非線形特徴量を使用)
model = LinearRegression()
model.fit(x_train_poly, y_train)
特徴量を非線形に変換する方法としてscikit-learnのPolynomialFeaturesクラスで変換することができます。このクラスを用いることで元の説明変数に対して多項式展開を行い、2乗根や交差項などを含む新たな特徴量を生成することが可能です。
PolynomialFeaturesクラスの使い方について調べたところ、第一引数であるdegreeで多項式の次数を指定することができます。デフォルトはdegree=2のようですが、今回は3としています。
このdegreeの値を変えるだけでも特徴量の構造が変化するため、回帰モデルの切片や各回帰係数、決定係数の差にばらつきが生まれます。ですので、この設定を変更して適宜確認してみると良いでしょう。
たったの3行追加するたけで非線形の回帰分析ができるなんてすごいですね。
評価結果と比較

今回新たに作成した気象データを用いて、線形回帰モデルおよび非線形回帰モデルで学習を行った結果、線形回帰モデルの決定係数が0.5であったのに対して、非線形回帰モデルの決定係数は0.6であったことから非線形モデルの方がやや高い予測精度を得ることが確認できました。
また、RMSEで予測値と実測値の誤差を求め2つのモデルを比較したところ、学習データおよびテストデータの値が比較的優れていることがわかります。以上から、非線形モデルの方がより精度が高いことが示唆されました。
# モデルの評価
print("\nモデルの評価:")
print("訓練データの決定係数: {:.3f}".format(model.score(x_train_poly, y_train)))
print("テストデータの決定係数: {:.3f}".format(model.score(x_test_poly, y_test)))
# 予測値の計算
y_pred_train = model.predict(x_train_poly)
y_pred_test = model.predict(x_test_poly)
# MSEの計算
train_mse = mean_squared_error(y_train, y_pred_train)
test_mse = mean_squared_error(y_test, y_pred_test)
print("\nMSE:")
print("訓練データMSE: {:.3f}".format(train_mse))
print("テストデータMSE: {:.3f}".format(test_mse))
# RMSEの計算
train_rmse = np.sqrt(train_mse)
test_rmse = np.sqrt(test_mse)
print("\nRMSE:")
print("訓練データRMSE: {:.3f}".format(train_rmse))
print("テストデータRMSE: {:.3f}".format(test_rmse))
# 切片の表示
print("\nパラメータ-")
print(f"切片: {model.intercept_[0]:.4f}")
考察
線形と非線形の回帰モデルの結果を比較してみたところ、非線形モデルの方が損失がやや小さく予測精度が向上していることが確認できました。
しかし、いずれのモデルも予測された積雪深が実際の値と比較して大きくずれる場合があり、これらの結果からは単純な回帰分析では十分に実データを適合させることが難しいことが示唆されます。そのため、今後は何らかの独自のアルゴリズムを開発し、係数の調整や新たな特徴量の作成を行う必要があるかもしれません。
これまでの分析では古典的な回帰分析を行ってきましたが、今後はニューラルネットワークや他の機械学習手法を用いることで、より高い精度の予測が可能になると考えています。
また、積雪深の予測においては説明変数が多い方が有利と考えていましたが、実際には説明変数が多すぎると予測精度が低下するという課題があることがわかりました。この問題に対して機械学習を用いることでモデルの調整をすることができると期待しています。
おわりに
いかがでしたでしょうか。
今回までのようなデータ分析は初めての取り組みでしたので、難しかったですがなかなか面白い取り組みができたのではないかと思います。
今回作成したソースコードは僕のgithubから使うことができます!
必要なライブラリについては前回とほとんど変わりませんので、すでにインストールしている方はすぐに扱うことができます。
まだインストールしていない方はgithubのREADMEに記載の方法でインストールできます!
参考URL
