見出し画像

【プログラミング初心者】が売上を予測してみました (vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル)

この記事は、週毎の売上分析、予測に気象庁のデータを加えることで、予測精度が上がるかどうかをまとめたものです。
内容は2部構成になっています。
vol.4 : データ整理編
vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル
です。

これまでに
「【プログラミング初心者】が売上を予測してみました」
では週毎の売上分析・予測を、
vol.1 : データ整理編
vol.2 : 時系列解析編
vol.3 : 回帰編
3部構成でまとめており、

「【プログラミング初心者】が在庫を予測してみました」
では在庫状況を分析し、未来の在庫を予測しています。

今回は「【プログラミング初心者】が売上を予測してみました」
のvol.1〜vol.3 でまとめた週毎の売上分析・予測を改良し、気象庁のデータを加えることで、予測の精度が上がるか検証します。
今回は「vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル」です。

前回までのおさらい

「vol.4 : データ整理編」では、売上データと気象庁のデータを整理し、週毎のcsvデータに変換しました。「vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル」ではcsvデータを用いて、線形重回帰モデル・LSTMモデルを作成したいと思います。気象庁のデータを加えることで、予測の精度が上がるかどうか楽しみです。


【線形重回帰モデル】

線形重回帰を用いて回帰分析をしていきます。
線形重回帰については【プログラミング初心者】が売上を予測してみました (vol.3 : 回帰編)でご紹介しているので、よければご覧ください。
https://note.com/kosari/n/ndbbccc65ed43#lVsl4

 

CSVデータの読み込み

まずはCSVデータを読み込みます。

import pandas as pd
df= pd.read_csv("sales_wether.csv", index_col=0)
df

スクリーンショット 2021-05-23 20.22.44

1行目は不要なため、削除します。

df= df.drop("MD週", axis=1)
df

スクリーンショット 2021-05-23 20.25.43

「vol.2 : 時系列解析編」で、周期は週ごとのデータであることも考慮して、4週区切りとしました。その流れを引き継いで、回帰モデルでは4つのデータ(t, t-1, t-2, t-3)を1セットとして学習用データを作成します。
また​ t+1を予測するとし、教師データとします。

X=[]
y=[]
idx=4
for num in range(idx-1, len(df)-idx):
 tmp_list=[]
 for i in range(idx):
   tmp_list+=df.iloc[num-(idx-1) + i, :].values.tolist()
 X.append(tmp_list)
 y.append(df.iloc[num+1, 0])

「vol.2 : 時系列解析編」にて119週までをtrainデータとし、120週から150週までをtestデータとしました。testデータは30週分です。
精度を検証するため、回帰モデルを作成する際も期間(予測対象数)を合わせます。

import numpy as np
X=np.array(X)
y=np.array(y)
num=int(X.shape[0]*0.8)
train_X=X[:num]
train_y=y[:num]
test_X=X[num:num+30]
test_y=y[num:num+30]
train_X.shape
(119, 16)

モデル作成

モデルを作成します。

from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(train_X, train_y)
# 決定係数の出力です
print(model.score(test_X, test_y))
-0.77152446278302

グラフの可視化、二乗誤差の出力・精度確認

予測期間での予測値を代入しグラフを可視化します。
実際の売上は青色、予測値は赤色でプロットします。
同時に二乗誤差を出力し、精度を確認します。

import matplotlib.pyplot as plt
x = list(range(30))
y1= test_y[:30]
y2 = model.predict(test_X)
# グラフの描画
plt.plot(x, y1,color="r")
plt.plot(x, y2)
plt.show()
#二乗誤差を出力し、精度を確認します。
from sklearn.metrics import mean_squared_error
Y_train_pred = model.predict(train_X) 
Y_test_pred = model.predict(test_X)
print('MSE train data: ', mean_squared_error(train_y, Y_train_pred)) # 学習データを用いたときの平均二乗誤差を力
print('MSE test data: ', mean_squared_error(test_y, Y_test_pred))         # 検証データを用いたときの平均二乗誤差を出力

スクリーンショット 2021-05-23 20.32.22

「vol.3 : 回帰編」で作成した、気象データを入れていない線形重回帰の結果がこちらです。

画像8

MSE train data: 1221112749.7203033
MSE test data: 990164256.8432528

比較すると一目瞭然ですが、気象データを入れてなかった時よりも、精度があがりました。


【XGBOOST】

XGBOOST用いて分析をしていきます。
XGBOOSTについても【プログラミング初心者】が売上を予測してみました (vol.3 : 回帰編)でご紹介しているので、よければご覧ください。
https://note.com/kosari/n/ndbbccc65ed43#cvos1

モデル作成

グラフの可視化、二乗誤差の出力・精度確認
予測期間での予測値を代入しグラフを可視化します。
実際の売上は青色、予測値は赤色でプロットします。
同時に二乗誤差を出力し、精度を確認します。

import xgboost as xgb
model = xgb.XGBRegressor()
model.fit(train_X, train_y)
print(model.score(test_X, test_y))
import matplotlib.pyplot as plt
x = list(range(30))
y1= test_y[:30]
y2 = model.predict(test_X)
# グラフの描画
plt.plot(x, y1,color="r")
plt.plot(x, y2)
plt.show()
#二乗誤差を出力し、精度を確認します。
from sklearn.metrics import mean_squared_error
Y_train_pred = model.predict(train_X) 
Y_test_pred = model.predict(test_X)
print('MSE train data: ', mean_squared_error(train_y, Y_train_pred)) # 学習データを用いたときの平均二乗誤差を出力
print('MSE test data: ', mean_squared_error(test_y, Y_test_pred))         # 検証データを用いたときの平均二乗誤差を出力

スクリーンショット 2021-05-23 20.45.51

線形重回帰モデルよりもさらに精度が上がりました。

【時系列解析 / LSTMモデル作成】


LSTMモデルを用いて時系列解析をしていきます。
LSTMモデル【プログラミング初心者】が在庫を予測してみました の記事の中でご紹介しているので、よければご覧ください。
https://note.com/kosari/n/nf1487d3753da#FHRCe

CSVデータの読み込みは線形重回帰モデルと同様のため省略します。
月毎のデータにするため、4週で1セットにします。

import numpy as np
np.array(X).shape
(149, 4, 4)
(149, 1)

学習用データとテスト用のデータに分けます。

num=int(X.shape[0]*0.8)
train_X= X[:num]
test_X= X[num:]
train_y= y[:num]
test_y= y[num:]

モデル作成

モデルを作成します。

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, Dropout, BatchNormalization, Activation
from tensorflow.keras.optimizers import Adam

model = Sequential()
num_hidden_units = 128 
len_sequence = 4
input_dim = 1 
model.add(LSTM(
   num_hidden_units,
   input_shape= (len_sequence,4),
   return_sequences=True))
#もう1層LSTM層を追加します
model.add(LSTM(units=30, return_sequences=False))
model.add(Dropout(0.5))

#Denseを加えます
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Activation("relu"))
model.add(Dense(128, "relu"))

output_dim = 1
model.add(Dense(output_dim))
model.compile(loss="mean_squared_error", optimizer=Adam())
model.summary()
# 学習
history = model.fit( train_X, train_y, batch_size=1, epochs=64, verbose=1, validation_data=(test_X, test_y) )

スクリーンショット 2021-05-23 21.01.35

スクリーンショット 2021-05-23 21.02.28

スクリーンショット 2021-05-23 21.03.20

二乗誤差の出力、精度確認

二乗誤差を出力し、精度を確認します。

import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error
#予測値を出力します
y_pred = model.predict(test_X)
# 二乗誤差を出力します
mse= mean_squared_error(test_y, y_pred)
print("REG RMSE : %.2f" % (mse** 0.5))
%matplotlib inline
plt.figure()
plt.scatter(train_y,model.predict(train_X),label='Train',c='blue')
plt.scatter(test_y,y_pred,c='lightgreen',label='Test',alpha=0.8)
plt.title('Neural Network Predictor')
plt.xlabel('Measured')
plt.ylabel('Predicted') 
plt.show()
loss=history.history['loss']
val_loss=history.history['val_loss']
epochs=len(loss)
plt.plot(range(epochs), loss, marker = '.', label = 'loss')
plt.plot(range(epochs), val_loss, marker = '.', label = 'val_loss')
plt.legend(loc = 'best')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
REG RMSE : 13365.11

スクリーンショット 2021-05-30 15.39.41

lossもval_lossもグラフが張り付いてしまっています。
今回のデータ数119個ですとLSTMモデルに入れるには少なすぎたため、学習がうまく進まないようです。

【まとめ】

「vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル」 では、XGBOOSTをGRIDSERCHを使って一番いいパラメーターで調整したところ、一番精度が優れているという結果になりました。

「vol.2 : 時系列解析編」、「vol.3 : 回帰編」で作成したSARIMAモデル・PROPHETモデル・線形重回帰・ラッソ回帰・ランダムフォレスト・XGBOOSTのなかでも、XGBOOSTがもっとも精度が優れていました。今回気象庁のデータを加えてモデルを改良しましたが、やはりXGBOOSTが一番精度が優れているということがわかりました。しかしまだまだ実務に使える精度にはなっていないので、今後さらにデータを加えたり、分析の方法をかえることで売上予測の精度を上げていきたいです。
6ヶ月にわたるアイデミープレミアムプランの学習期間も残りわずかですが、学習した内容をもとに、これから売上予測を在庫管理に活用し、売上向上とともに過剰在庫を削減する目標を達成するのがとても楽しみです。

「【プログラミング初心者】が売上を予測してみました(vol.5 : モデル作成編 / 線形重回帰モデル・LSTMモデル)」はこちらで終わりです。

もしよければ、「【プログラミング初心者】が売上を予測してみました(vol.1 : データ整理編)、(vol.2 : 時系列解析編)、(vol.3 : 回帰編)、(vol.4:データ整理編)」
「【プログラミング初心者】が在庫を予測してみました 」もあわせてぜひご覧くださいませ。
最後まで読んでいただき、ありがとうございました。



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