まず最初に結論を言っておきます。10回中9回は、データが原因です。

倉庫業界で20年もやっていると、この映画は何度も観てきました。あるDCが大金を投じてAI需要予測モジュールを導入し、モデルが稼働し始める。ところが3か月後、補充は依然としてベテランの計画担当者の勘頼み。ITの最初の反応はいつも「モデルが悪い、別のアルゴリズムを試そう」。私の反応はいつも同じです。モデルにはまだ触るな——投入したデータを引っ張り出して、よく見てみろ、と。ほぼ毎回、問題はそこにいます。

モデルは単なる勤勉な生徒です。ページが抜けて誤植だらけの教科書を渡しておいて、試験に落ちたからと生徒を責めるわけにはいきません。

まず問いたい:データはそもそも揃っているのか?

多くの予測プロジェクトは第一歩で死にます。SKUマスタデータがぐちゃぐちゃなのです。

数年前、カリフォルニア州オンタリオにある3PLの倉庫を歩いたことがあります——100,000平方フィートをはるかに超え、SKUは20,000を超える規模——そこでMLベースの補充予測が導入されていました。導入から半年、精度は惨憺たるもの。掘り下げてみると、商品カテゴリ、季節フラグ、代替関係といったフィールドが、カタログの相当な割合で空欄でした。新商品はカテゴリすら割り当てられないまま何か月もシステムに放置されている。モデルはいったい何から学べというのか。何もないところからか?

一貫しないタグ付けもあります。同じ商品が、あるDCでは「winter style」、別のDCでは「Winter-2023」、3つ目のDCでは空欄。これではモデルは3つの異なる商品として認識し、3つすべてに間違ったパターンを学習します。

チェック方法は単純です:SKUをランダムに200件抜き出し、カテゴリ、季節性、ライフサイクル状態、代替フィールドを見てみる。NULL率が20%を超えていたら、モデルの話はやめてマスタデータを直しに行く。地味な作業ですが、これを飛ばしたら下流のすべてが無駄になります。

次に問いたい:そもそも測っているものは正しいのか?

これは私が知る限りで最もずるい失敗モードです。モデルが学習する「過去の販売実績」は、実は真の需要ではないことが多いのです。

典型例:あるSKUが去年の11月に2週間欠品し、システムは販売ゼロを記録した。モデルは「このSKUは11月に誰も欲しがらない」と学習し、今年は在庫を薄くした——ところが今年は欠品がなく、需要はいつも通りやってきて、棚は空になった。欠品中のゼロは需要ではありません。それは供給できた分の上限です。上限を下限と取り違えるようモデルに教え込んだら、正しくなるはずがありません。

もう一つ:倉庫間移動。DC Aで在庫が足りなくなり、DC Bから500単位を移動させる。するとDC Bの出庫ログに500単位の「販売」が計上される。モデルはそのSKUのDC Bにおける需要が強いと判断し、在庫を積み増せと言ってくる——しかしそれは実は単なる内部移動だった幻の需要です。実需と内部移動が一つの数字に混ざっていたら、すべての予測が歪みます。

高いパレットラックで商品を補充する倉庫作業員

そして返品も忘れないでください。ECフルフィルメントでは、総売上と純売上は大きく食い違うことがあります。総売上ベースで学習させたら、モデルは慢性的に過大見積もりします。

チェック方法:売上指標を定義した文書を探す——存在すれば——そして3つの質問をする。欠品期間はどう扱っているのか、真の需要を再構成したか?移動出荷は除外されているか?総売上か純売上か?誰も答えられない、あるいは「そんなことはやったことがない」という答えなら、根本原因を見つけたことになります。指標が曖昧なら、モデルが賢ければ賢いほど、自信満々に間違えます。

もう一つ言っておきたいこと。多くの倉庫は売上データをERPから直接流し込んでいますが、ERPの出庫記録は「顧客に売れた」と「姉妹DCに出荷した」を区別しません。そのクリーニング工程を誰もやっていないので、モデルは一日中フェイク需要を勉強し続けることになる。私はたいてい、データチームに1年分の出庫記録を売上・移動・廃棄に分割してもらいます。この一工程で、複数のSKUの「過去需要」が目に見えて縮むことが多い——そして消えた単位はすべてノイズでした。

3つ目の問い:イベントのタグ付けは誰かやったのか?

予測モデルは説明のつかないスパイクが大嫌いです。去年のある月に売上が2倍になり、モデルはそのパターンを記憶し、今年は2倍仕入れた——ところが去年のスパイクは大型プロモーションによるもので、今年はプロモーションがない。こうして死に在庫を抱えることになります。

プロモーション、クリアランス、インフルエンサー発の急増、異常気象、競合の欠品——これらにタグが付いていなければ、モデルはそれらを「自然な需要」として吸収します。それが学ぶのはパターンではありません。ノイズです。

私が見た最悪のケース:パンデミック期の買いだめデータ3年分が、注釈ゼロのまま学習データに残っていた。モデルはその異常なピークを基準値として扱い、日常の安全在庫を恒常的に高く保ち、死に在庫が通路2本分を埋め尽くした。その期間にタグを付けて重みを下げた途端、予測は現実に引き戻されました。

もう一つ見落とされがちな次元があります。供給側のイベントです。サプライヤーの納期遅れ、港湾ストライキで入荷が3週間後ろ倒し——こうしたことが売上カーブに説明のつかない穴をあけます。モデルには「商品が届かなかったから売れなかった」が理解できません。ただ「このSKUはあの月誰も欲しがらなかった」と学習するだけです。だからイベントカレンダーはプロモーションだけを追っていてはダメ。主要な供給混乱と入荷異常も記録すること。両側にタグを付けなければ、絵は完成しません。

チェック方法:過去の変動が最も激しいSKU月を10件取り出し、営業チームに何が起きたのか聞いてみる。半分以上を説明できるのに、システムには何も記録されていないなら、イベントカレンダーは空っぽです。イベントタグの収集は、営業側が説明するのに10分、データチームの実装に2週間程度——1時間たりとも無駄になりません。

では、本当にモデルが悪いのはどんな時か?

データが3つのチェックをすべて通過——マスタデータは完備、指標はクリーン、イベントはタグ付け済み——それでも予測が外れるなら、はい、その時はモデルを議論しましょう。私が最初に賛成します。

本物のモデルの問題はこう見えます。データはクリーンなのに、単純なモデルと複雑なモデルの精度がほぼ同じ、時には単純な方が少し上。あるいは需要分布が構造的に変わった——卸売から小売へ、実店舗からオンラインへ事業が移行したなど——古いモデルはもう存在しない世界のルールを学習していた。

特徴量エンジニアリングの不足もあります。販売時系列だけをモデルに食わせ、価格、在庫ポジション、リードタイム——実際に事業が回っている要因——を入れていない。これは「アルゴリズムが悪い」というより「モデルを作った人が倉庫を理解していない」。アルゴリズムを変えても助からない。補充を理解している人を連れてくるべきです。

私の経験では、この領域では特徴量がアルゴリズムにほぼ毎回勝ちます。補充ロジックを理解した計画担当者と素朴な回帰の組み合わせは、倉庫の床に一度も立ったことのない人がチューニングした派手なモデルにたいてい勝ちます。倉庫の需要ドライバーは具体的です。プロモーションカレンダー、未出荷の受注、季節性、サプライヤーのリードタイムのばらつき。これらを特徴量に変えれば、どんなアーキテクチャの変更よりも遠くへ行けます。

私の経験則は単純です。同じクリーンなデータセットで3つの異なるモデルがほぼ同じスコアなら、ボトルネックはモデルではありません。汚いデータでモデル選定をチューニングするのは、ただの高価な無駄仕事です。

実際に使えるデータ準備チェックリスト

診断は終わり——さあ掃除です。この順番で、飛ばさずに:

  • マスタデータ:すべてのSKUについてカテゴリ、季節性、ライフサイクル、代替フィールドを整備し、NULL率を5%未満に
  • 指標:欠品期間の真の需要を再構成(最低でもフラグを立てる)、移動出荷を除外、純売上ベースで学習
  • イベント:イベントカレンダーを構築——プロモーション、クリアランス、異常気象、単発の大口注文、すべてタグ付け
  • 粒度:予測の粒度(SKU-DC-週)が補充判断の粒度と一致していることを確認。間違った粒度での正しい予測は無意味
  • バックテスト:クリーンなデータで3か月のバックテストを回し、何かを稼働させる前に誤差分布を研究する

この5工程を終えた倉庫の多くが、面白いことに気づきます。古いモデルが急に「賢く」なった。それは決して頭が悪かったわけではありません。誤植だらけの教科書を読まされていただけです。

持ち帰りのセルフテスト問題を一つ:今あなたの予測モデルに食わせている過去の売上のうち、どの行が実需で、どれが欠品で、どれが内部移動か、区別できますか? 区別できないなら、モデルを慌てて取り替える前に——まずこの3つを切り分けること。その問いに答えられれば、予測が外れる謎のほとんどは解けます。

英語版からの翻訳。内容に相違がある場合は英語版を優先します。