前の「中小企業のための実践的需要予測入門①」では需要予測の概要に関して話しましたが、今回は実践編になります。もし①を見ていない方がいれば、是非①を先に見ることをお勧めします。
需要予測のやり方
需要予測のやり方はどのようなものがあるのでしょうか?
以下は筆者が知っている幾つかの方法になります。
手法名 | 分類 | 特徴 | 長所 | 短所 | 向いているケース |
---|---|---|---|---|---|
単純移動平均 | 統計モデル | 過去一定期間の平均を予測値とする | シンプル・直感的 | トレンドや季節性を反映できない | 安定した需要、短期予測 |
ARIMA | 統計モデル | 自己回帰+移動平均+差分で時系列を表現 | トレンドのあるデータに強い | 季節性や外部要因を扱えない | 単変量の中長期予測 |
ARIMAX | 統計モデル | ARIMAに外部変数(気温・価格等)を加えたモデル | 外部要因を考慮できる | 外生変数の選定と整備が必要 | 値引き・イベントの影響を反映したい時 |
状態空間モデル(例:Kalman) | 統計モデル | 観測値を隠れた状態で説明する構造的モデル | 構造変化・ノイズに強い | モデル設計が複雑・専門性が必要 | 不規則変動や多ノイズ環境 |
Prophet(Facebook製) | 統計モデル | トレンド・季節性・休日効果を自動分離 | パラメータ少で手軽に使える | データ頻度・長さに制約あり | 季節性や祝日効果のある販売データ |
XGBoost / LightGBM | 機械学習モデル | 勾配ブースティング決定木ベースの回帰モデル | 高精度、特徴量次第で柔軟に対応 | 特徴量設計が重要・時系列性の工夫が必要 | 外部要因が多い実務データ、応用の幅広さ |
LSTM(ディープラーニング) | ディープラーニング | RNNの長期依存性対応型モデル | 非線形性・長期パターンに強い | 学習に大量データと計算リソースが必要 | 複雑・高頻度な時系列、IoT/センサデータ等 |
こんなに色々あるんだなということを感じてもらえれば良いです。私もすべてを知っているわけではありません。
さて、今回は代表的な統計モデルであるARIMAXモデルと機械学習モデルのXGBoostを使って、どこまでの予測が可能になるのか、予測のポイントはどのなのか、どちらが精度が良いのかなどを実際に行っていこうと思います。
今回のレシピ(予測をするのに使ったツール)
今回の予測モデルを調理(=構築)するにあたって使った、いわば「食材」は以下の通りです。
それぞれの役割を簡単にご紹介します。
🍳 Windowsパソコン
これが無いと始まりません。すべての作業のベースとなるマシンです。
🧪 Google Colab(Python)
Pythonを実行するためのオンライン実験室のような存在です。
ブラウザ上で動作し、さまざまなライブラリをインストールせずに使えるのが最大の魅力。今回の予測モデルは、主にここで構築しました。
📊 QlikView
スタンドアロン型のBIツールで、主にデータの可視化に使用しました。
大量のデータをわかりやすくグラフ化し、傾向や異常値を確認するのに役立ちます。
🤖 ChatGPT
コードの作成から構文チェック、考え方の整理まで、さまざまな場面で活躍しました。
筆者は以前から簡単なプログラミングを触っていましたが、ChatGPTの登場で格段に効率が上がりました。
近年は「ノーコード」や「ローコード」といった言葉もありますが、
ChatGPTのような生成AIを使えば、より複雑な処理でも自然言語からコードを作成できます。 これを私は勝手に「スマートコード(スマコ )」と呼んでいます 😙。
ちなみに以前整理したいまどきITの「サービス層モデル10階層」で整理すると以下のような感じです。
ARIMAXを使った予測
今回は予測の精度も出したかったので、以下の方針で行いました。
直近1年間の実績データを使って1か月先の予測値を出す
ある商品は2016年4月末まで実績があるとすると、2015年4月~2016年3月までの実績を使って、2016年4月の予測を行い、2016年4月の実績と比べてどれだけあっているかを調べる。
これからは、実際に予測モデルのプログラミングを行った内容に入りますが、コードの詳細はここでは割愛します。筆者が本記事でお伝えしたいのは、「こうした予測モデルの構築は、ゴリゴリの技術者でなくても十分にできる」ということです。
さらに言えば、この記事の内容をChatGPTに見せて「この予測モデルをPythonで実装して」と依頼すれば、ある程度のコードを自動生成してくれる時代です。
だからこそ、本記事ではコードの記述よりも、「どんなデータをどのようにモデルに入力すれば、予測の精度が上がるか」という、よりデータサイエンティスト的な視点で話を進めていきます。
【今回使用したデータと特徴量の追加について】
🎯 予測対象(目的変数)
- sales(販売量)
→ 商品別・日別での売上数量を予測します。データとしては店舗ごとのデータがありましたが、店舗全体の販売量を予測することにしました。
🧾 使用したデータファイル
sales_train_validation.csv
:各商品の日別売上実績(最大1913日分)calendar.csv
:日付、曜日、祝日、イベント情報などsell_prices.csv
:商品 × 店舗 × 週ごとの販売単価
上記3つのデータを統合・加工し、以下のような時系列データを作成しました。
このデータは、売上実績に対してカレンダー情報や販売価格情報を結合したもので、特徴量として以下の項目を加えています:
event_flag
:イベントがある日かどうか(1/0)is_weekend
:週末(土日)かどうかのフラグ(1/0)
これらの特徴量が、モデルに「売上が伸びる条件」を理解させる上で大きなヒントとなります。
- なぜ
event_flag
を追加したのか?
(※多少の加工は加えていますが…)
元々のカレンダーデータには、event_name_1
や event_name_2
といった形でイベント情報が含まれていました。しかし、そのままだとモデルにとって「この日がイベントかどうか」を判断しにくいため、イベント名が入力されている日を明示的に識別できるように、event_flag
というフラグを追加しました。
具体的には、event_name_1
または event_name_2
に文字が入っていれば event_flag = 1
、
どちらも空であれば event_flag = 0
となるように加工しています。
以下が、加工前のカレンダーデータの一部です。
- 何故is_weekendを追加したか
まずは、以下のグラフをご覧ください。
このデータを見ると、土日に売上が「山」を描くように伸びていることがわかると思います。
アメリカでも日本と同じように、スーパーマーケットには週末に買い物へ行く人が多いため、販売数も土日に集中する傾向があります。
実は、最初に is_weekend
フラグを加えずに予測モデルを構築したところ、
土日でも売上の「山」が現れず、平日と同じようなフラットな予測結果になってしまいました。
そこで、「この日は週末だよ」とモデルに明示的に教えるため、is_weekend
フラグを追加しました。
この追加により、モデルは「土日は売上が増える」というパターンを学習し、より実態に近い予測を行うようになったのです。
※ ただし、過去の実績において土日に売上が伸びていない商品は、フラグを追加しても予測値に大きな山は現れません。
※ この傾向は、ARIMAXだけでなく、XGBoostやLSTMなど他の予測モデルでも同様です(表現の仕方に違いはありますが)。
予測の精度
先ほどの図を再度使って、予測値と実績値を比較しながら予測の精度を見ていきます。
ここでは、単に「どれくらい当たったか」を見るだけでなく、精度評価の考え方についてもう少し掘り下げて説明していきます。
以下は、ある商品の予測値と実績値を比較したグラフです。
予測精度が高いとは、実績値と予測値が日ごとにほぼ一致している状態、つまりグラフの線が重なっている状態を指します。
このように予測と実績が完全に一致すれば、「その商品についての需要を正確に予測できた」と言える、理想的な精度といえるでしょう。残念ながらこの商品の予測はそこまでにはなっていないですね。
予測値と実績値の**ズレの大きさ(誤差)**を測定するためには、いくつかの評価指標が提案されていますが、今回はその中でも代表的な指標である RMSE(Root Mean Squared Error) を用いて評価していきます。
RMSEの具体的な数式はここでは省略しますが、興味のある方は「RMSE」で検索してみてください。
ざっくり言えば、1日あたりの予測値と実績値のズレの大きさを平均したものと考えていただければ大丈夫です。
予測結果
個別商品
これは1つのサンプルです。RMSEが2.22で1日平均が6個くらいなので、精度としてはあまりよくない例です。
このグラフを見ると、予測値は土日に売上が伸びる傾向をある程度捉えているものの、実績値のような日ごとの凸凹(変動)が予測値には現れていないことがわかります。また、販売数量自体も1日平均で6個程度と、それほど大きくありません。
いくつかの商品について同様の検証を行いましたが、実績データに対して明確に説明できるような予測結果はあまり見られず、今回のモデルにおける予測精度は、総じて高くはなかったと言えそうです。
FOOD全体
個別の商品では販売数量が少ないこともあり、予測精度はそれほど高くありませんでした。
そこで次に、全体の販売数量として予測した場合にどのような結果になるのかを見てみましょう。
以下は、今回予測を行った全商品の実績値と予測値を積み上げて可視化したグラフです。
このグラフを見ると、予測値と実績値の差が小さく、全体としてはおおむね一致していることがわかります。
個別商品よりも、全体の傾向を捉える予測としては良好な結果が得られたといえるでしょう。
さらなる改良の余地
今回は、非常にシンプルな特徴量のみを使って予測を行ったため、あまり高い精度は得られませんでした。しかし、以下のような工夫を加えることで、予測精度はさらに改善できると考えています。
- 土曜と日曜で売上傾向が異なるため、現在の「週末フラグ」を土曜・日曜で分ける
- イベントの種類ごとに売上への影響が異なるため、イベントも一律ではなく、効果のあるイベントだけを識別する
- その他の特徴量(例:天気、気温、プロモーション情報など)を追加検討
→ 実績が大きく伸びた日には、必ず何かしらの要因があるはず。それを明らかにする作業が鍵です - 現在の予測では平日がすべて同じ水準になっているが、実績では水曜日が最も低く、土日に向かって徐々に上がる傾向が見られました。
→ これも適切な特徴量を加えることで改善できる可能性があります
このように、「どのようなデータをモデルに与えるか」を工夫することで、予測精度の向上が期待できます。このプロセスは、機械学習の世界で 「特徴量エンジニアリング」 と呼ばれ、予測の精度を左右する非常に重要な工程です。
モデルがすべてを理解してくれるわけではありません。
分からないなら、モデルが分かるように情報を与えてあげるしかないのです。
おわりに
今回のARIMAXによる予測結果を見ると、完全ではないものの、「一定の精度で傾向を捉えられる」ことが分かりました。特に外的要因(価格・イベント・曜日)を加味することは、予測モデルにとって非常に重要です。
次回は、機械学習モデル(XGBoostなど)を使って、より精度を重視した予測にチャレンジしてみたいと思います。
コメント
予測がうまくいかない原因は「モデルの性能」だけではありません。むしろ「どのような情報を与えたか(特徴量)」による部分が大きいのです。
今回の予測も、「土日」と「平日」の違いはある程度捉えられたものの、イベントの種類や季節感などの情報が不足していたため、まだ伸びしろは十分にあります。
AIや統計モデルを使った予測は、もはや一部の専門家だけのものではありません。あなたの会社でも、今あるデータを使って、すぐに実践を始めることができるのです。
コメント