売上予測は、機械学習 (ML) の一般的かつ重要な用途です。予測売上は、ベースラインを確立して新しい取り組みの増分影響を判断し、予想される需要に基づいてリソースを計画し、将来の予算を計画するために使用できます。この記事では、売上を予測するために 5 つの異なる ML モデルを実装する方法を説明します。 初期準備 まず、データをロードして、各モデルで使用する構造に変換します。元の形式では、データの各行は 10 店舗の 1 日の売上を表します。私たちの目標は月間売上を予測することなので、まずすべての店舗と日数を合計して月間売上を算出します。 - def load_data():
- pd.read_csv('D:\Jupyter\dataset\demand-forecasting-kernels-only/train.csv') を返します。
-
-
- 月次売上データを定義します。
- 毎月のデータ= data.copy()
- 月次データ月次データ.date = 月次データ.date.apply(lambda x: str(x)[:-3])
- monthly_data monthly_data = monthly_data.groupby('date')['sales'].sum().reset_index()
- 月次データ.date = pd .to_datetime(月次データ.date)
- 月次データを返す
-
- monthly_df =月次売上(売上データ)
- 月次_df.head()
新しいデータ フレームでは、各行が特定の月におけるすべての店舗の合計売上を表すようになりました。 月間総売上高を時間の経過とともにプロットすると、月間平均売上高が時間の経過とともに増加していることがわかります。これは、データが定常ではないことを意味します。定常化するために、月間売上の差を計算し、それをデータ フレームに新しい列として追加します。 - get_diff(データ):
- データ['sales_diff'] = data.sales.diff()
- データデータ= data.dropna()
-
- data.to_csv('D:/Jupyter/dataset/demand-forecasting-kernels-only/stationary_df.csv')
- データを返す
-
- 静止_df = get_diff (月次_df)
差分変換の前後のデータを視覚的に表したものが以下です。 差異の前後の定常性を比較する 月間売上を表すデータを取得し、それを固定値に変換したので、さまざまなモデル タイプのデータを設定します。これを実行するには、ARIMA モデリングに使用する構造と、残りのモデルに使用する構造の 2 つの異なる構造を定義します。 Arima モデルでは、日時インデックスと従属変数 (売上の差) 列のみが必要です。 - 定義:
- dt_data = data.set_index('date').drop('sales', axis = 1 )
- dt_data.dropna(軸= 0 )
-
- dt_data.to_csv('D:/Jupyter/dataset/demand-forecasting-kernels-only/arima_df.csv')
-
- dt_dataを返す
-
- arima_datetime = generate_arima_data (stationary_df)
他のモデルについては、各機能が前月の売上を表す新しいデータフレームを作成します。機能セットに含める月数を決定するには、自己相関プロットと部分自己相関プロットを観察し、ARIMA モデリングでラグを選択するためのルールを使用します。この方法により、ARIMA および回帰モデルの一貫した遡及期間を維持できます。 自己相関と偏自己相関のプロット 上記に基づき、12 か月の遡及期間を選択します。したがって、12 か月ごとに 1 列ずつ、合計 13 列のデータ フレームを生成し、従属変数である売上の差を列 1 として指定します。 - def generate_supervised(データ):
- supervised_df =データ.copy()
-
- #ラグごとに列を作成
- iが範囲(1,13)内にある場合:
- col_name = 'lag_' + str(i)
- supervised_df[col_name] = supervised_df['sales_diff'].shift(i)
-
- #null値を削除する
- supervised_df supervised_df = supervised_df.dropna().reset_index( drop = True )
-
- supervised_df.to_csv('D:/Jupyter/dataset/demand-forecasting-kernels-only/model_df.csv',インデックス= False )
-
- supervised_df を返す
-
- model_df = generate_supervised (stationary_df)
これで、2 つの別個のデータ構造ができました。1 つは日時インデックスを含む Arima 構造で、もう 1 つは遅延時間機能を含む教師あり構造です。 売上予測のためのARIMAと教師ありデータフレーム モデリング すべてのモデルを作成して評価するには、次の機能を実行する一連のヘルパー関数を使用します。 - トレーニング/テストの分割: データを分割して、過去12か月のデータをテストセットの一部とし、残りのデータをモデルのトレーニングに使用します。
- データのスケーリング: 最小最大スケーラーを使用して、すべての変数が-1から1の範囲になるようにデータをスケーリングします。
- スケールの反転: モデルを実行した後、このヘルパー関数を使用してステップ2のスケールを反転します。
- 予測データフレームを作成する: テストセットでキャプチャされた実際の売上とモデルの予測を含むデータフレームを生成し、成功を定量化できるようにします。
- モデルのスコアリング: このヘルパー関数は、予測の二乗平均平方根誤差 (RMSE) と平均絶対誤差 (MAE) を保存し、5 つのモデルのパフォーマンスを比較します。
1. 回帰モデル: 線形回帰、ランダムフォレスト回帰、XGBoost 回帰モデルでは、scikit-learn ライブラリの fit-predict 構造を使用できます。したがって、各モデルに対して呼び出す基本モデリング構造を設定できます。以下の関数は、上記で概説したヘルパー関数の多くを呼び出して、データを分割し、モデルを実行し、RMSE スコアと MAE スコアを出力します。 - def regressive_model(トレーニングデータ、テストデータ、モデル、モデル名):
-
- # ヘルパー関数を呼び出して、X と y のデータとスケールデータを作成します
- X_train、y_train、X_test、y_test、スケーラーオブジェクト=
- スケールデータ(トレーニングデータ、テストデータ)
-
- # 回帰モデルを実行する
- mod =モデル
- mod.fit(X_train、y_train) を使います。
- 予測= mod .predict(X_test)
- # スケーリングを元に戻すためのヘルパー関数を呼び出して予測 DF を作成します
- original_df = pd .read_csv('D:/Jupyter/dataset/demand-forecasting-kernels-only/train.csv')
- unscaled = undo_scaling (予測、X_test、scaler_object)
- unscaled_df = predict_df (スケールなし、original_df)
- # ヘルパー関数を呼び出してスコアを印刷し、結果をプロットします
- get_scores(スケールなし_df、オリジナル_df、モデル名)
- plot_results(スケールなしの DF、元の DF、モデル名)
-
- # データをトレーニングセットとテストセットに分ける
- トレーニング、テスト= tts (model_df)
- # 線形回帰のモデルフレームワークを呼び出す
- regressive_model(トレーニング、テスト、LinearRegression()、'LinearRegression')
- # ランダムフォレスト回帰のモデルフレームワークを呼び出す
- 回帰モデル(訓練、テスト、
- ランダムフォレスト回帰( n_estimators = 100 ,
- 最大深度= 20 )、
- 「ランダムフォレスト」
- # XGBoost のモデルフレームワークを呼び出す
- regressive_model(train, test, XGBRegressor( n_estimators = 100 ,
- 学習率= 0.2 )、
- 'XGBoost')
以下の出力は、実際の売上 (青) に重ねた各回帰モデルの予測 (赤) を示しています。結果は似ているように見えますが、以下の比較セクションでわかるように、わずかな違いが売上高に数千ドルの差をもたらす可能性があります。 2. 長期短期記憶(LSTM) LSTM は、連続データを使用して予測を行うのに特に役立つ、リカレント ニューラル ネットワークの一種です。このために、非常に単純な LSTM を使用します。精度を向上させるために、周期的な特徴と追加のモデルの複雑さを追加できます。 - lstm_model(train_data, test_data)を定義します。
-
- X_train、y_train、X_test、y_test、 scaler_object = scale_data (train_data、test_data)
-
- X_train X_train = X_train.reshape(X_train.shape[0], 1, X_train.shape[1])
- X_test X_test = X_test.reshape(X_test.shape[0], 1, X_test.shape[1])
-
- モデル=シーケンシャル()
- モデルを追加します(LSTM(4, batch_input_shape =(1, X_train.shape[1], X_train.shape[2]),
- ステートフル= True ))
- モデルを追加します(密(1))
- モデルを追加します(密(1))
- model.compile(損失= 'mean_squared_error' 、オプティマイザー= 'adam' )
- model.fit(X_train, y_train,エポック= 200 ,バッチサイズ= 1 ,詳細= 1 ,
- シャッフル= False )
- 予測= model.predict (X_test、 batch_size = 1 )
-
- オリジナルdf =オリジナルdfをロードする()
- unscaled = undo_scaling (予測、X_test、scaler_object、 lstm = True )
- unscaled_df = predict_df (スケールなし、original_df)
-
- get_scores(スケールなし_df、オリジナル_df、'LSTM')
-
- plot_results(スケールなしの DF、元の DF、'LSTM')
結果のプロットは上記の 3 つの回帰プロットと似ているため、以下のエラーが表示されるまで結果を比較し続けます。 LSTMモデルの予測と実際の売上 3. 有馬 ARIMA モデルは上記のモデルとは少し異なります。モデルのトレーニングと動的な予測の生成には、statsmodels SARIMAX パッケージを使用します。 SARIMA モデルはいくつかの部分に分かれています。 - AR: pと表記され、自己回帰モデルである
- I: dで表される微分項
- MA: qと表記され、移動平均モデルである。
- S: 周期的なコンポーネントを追加できます
以下のコードでは、モデルを定義し、過去 12 か月のデータの動的な予測を実行します。標準の非動的予測の場合、翌月の予測は前月の実際の売上を使用して作成されます。対照的に、動的予測では、前月の予測売上を使用して翌月の予測を作成します。 - lstm_model(train_data, test_data)を定義します。
-
- X_train、y_train、X_test、y_test、 scaler_object = scale_data (train_data、test_data)
-
- X_train X_train = X_train.reshape(X_train.shape[0], 1, X_train.shape[1])
- X_test X_test = X_test.reshape(X_test.shape[0], 1, X_test.shape[1])
-
- モデル=シーケンシャル()
- モデルを追加します(LSTM(4, batch_input_shape =(1, X_train.shape[1], X_train.shape[2]),
- ステートフル= True ))
- モデルを追加します(密(1))
- モデルを追加します(密(1))
- model.compile(損失= 'mean_squared_error' 、オプティマイザー= 'adam' )
- model.fit(X_train, y_train,エポック= 200 ,バッチサイズ= 1 ,詳細= 1 ,
- シャッフル= False )
- 予測= model.predict (X_test、 batch_size = 1 )
-
- オリジナルdf =オリジナルdfをロードする()
- unscaled = undo_scaling (予測、X_test、scaler_object、 lstm = True )
- unscaled_df = predict_df (スケールなし、original_df)
-
- get_scores(スケールなし_df、オリジナル_df、'LSTM')
-
- plot_results(スケールなしの DF、元の DF、'LSTM')
繰り返しますが、結果はかなり良好です。以下でさらに詳しく説明します。 ARIMAモデル予測と実際の売上 比較モデル モデルのパフォーマンスを比較するために、二乗平均平方根誤差 (RMSE) と平均絶対誤差 (MAE) を調べます。これらのメトリックはどちらもモデルのパフォーマンスを比較するためによく使用されますが、その直感と数学的な意味は若干異なります。 - MAE: 平均絶対誤差は、予測値が実際の値からどれだけ離れているかを示します。この場合、すべてのエラーの重みは同じになります。
- RMSE: すべての二乗誤差の合計の平方根をとって RMSE を計算します。二乗すると、誤差が大きいほど全体の誤差に大きな影響を与えますが、誤差が小さいと全体の誤差にはあまり影響しません。
上記のヘルパー関数から、get_scores を使用して各モデルの RMSE スコアと MAE スコアを計算します。これらのスコアは辞書に保存され、保管されます。比較のために、辞書を Pandas データフレームに変換し、結果をプロットします。 - デフcreate_results_df():
- results_dict = pickle .load(open("model_scores.p", "rb"))
-
- results_dict.update(pickle.load(open("arima_model_scores.p", "rb")))
-
- restults_df = pd .DataFrame.from_dict(results_dict, orient = 'index' ,
- 列= ['RMSE', 'MAE', 'R2'])
-
- restults_df restults_df = restults_df.sort_values( by = 'RMSE' 、 ascending = False ).reset_index()
-
- 結果を返す_df
-
- 結果= create_results_df ()
これにより、次のデータ フレームが生成されます。 上のグラフではモデルの出力は似ているように見えますが、精度は異なることがわかります。以下に、違いを確認するのに役立つ図を示します。 モデルのパフォーマンスの比較 結論は 全体的に見ると、XGBoost モデルのパフォーマンスが最も優れており、ARIMA モデルと LSTM モデルがそれに続いていることがわかります。上記のモデルはすべて、売上予測にどのように使用できるかを示すために、最も基本的な形式で導出されたものであることに注意することが重要です。モデルは複雑さを最小限に抑えるために微調整されただけです。たとえば、LSTM にはパフォーマンスを向上させるために多くの追加ノードとレイヤーを含めることができます。 ユースケースに適したモデルを決定するには、次の点を考慮する必要があります。 - モデルの複雑さと解釈可能性の度合い。
- モデルを調整し、定期的な情報、休日、週末などを含むように機能を設計できます。
- 結果の使用方法と、データを入力してモデルを更新する方法について学習します。
- データの過剰適合を避けるために、クロス検証または同様の手法を使用してモデルを調整します。
|