需要予測 と ゼロ過剰

# 概要
　機械学習の代表的なユースケースである需要予測を進める上で、天敵[^obj]となる**ゼロ過剰**とその対応について考察してみようという内容です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/e5ec1554-44ab-2259-ce55-4b81a1513206.png)

[^obj]: 需要予測の目的が不明確だったり、予測対象のセグメントを絞り込まずに取り扱いの全SKUを予測対象としたりするケースにてゼロ過剰がよく発生します。その意味において需要予測の天敵と記載しています。実際、うまくハンドリングされているプロジェクトではゼロ過剰は問題にならないかもしれません。

本稿の内容に何か学術的な拠り所があるといったものではなく、あくまでも私見であり、「こういったアプローチもありますよ！」というご紹介程度に見てもらえると助かります。

## 需要予測って？
https://ja.wikipedia.org/wiki/%E9%9C%80%E8%A6%81%E4%BA%88%E6%B8%AC
> 需要予測は、物の需要を短期的または長期的に予測することである。

と記載の通り、「未来」の需要を予測する技術です。様々な領域に応用が可能です。

　具体的には、後述の①～⑤に示す通り、「売り場」、「サプライチェイン」、「財務」といった様々な要素の改善に向けて活用が可能であり、プロジェクトの初期段階で、需要予測の目的を明確化できるか？が重要なポイントと考えています。


## 需要予測の目的[^PB]

需要予測の実施目的は、思いつく範囲でも、下記の様に様々です。

[^PB]: ECや小売を想定し列挙してみましたが、PB品で自社生産のものがあったりする場合には、そのPB品の生産計画やその原材料の調達計画等、SCMを遡ると需要予測の活用先は様々です。ただし、そういったものを列挙し始めると枚挙に暇がないので、本稿では若干絞り込んでいます。

| # | 目的 | 主たる要請元 | メモ |
|:---:|:---:| :---:| --- |
| ① | **機会損失**の最小化 | 売り場（需要） | 損失回数や損失額 |
| ② | **ロス**の最小化 | 売り場（供給） | 消費・使用期限がある商材にて |
| ③ | **倉庫在庫**の最適化 | SCM（倉庫） | 保管にコストを要する |
| ④ | **店舗在庫**の最適化 | SCM（店舗） | 店舗の保管スペースに限りがある |
| ⑤ | **バランスシート**の適正化 | 財務（資本効率） | 高価格・低回転な商材にて |

ちょっと長くなりますが、、やはり「手段」ではなく「目的」が最重要ですので、
少し詳しめに確認していきましょう。

### 目的①：機会損失（額、回数）の最小化
　一番よくあるテーマで、「在庫切れ」による「売り逃し」（機会損失）の最小化です。
お客さんがせっかく買いに来てくれたのに、在庫切れは商売人としては悲しい限りです。

* 「機会損失額が合計いくらか？」（損失額の最小化）
* 「在庫切れが何回起きたか？」（回数の最小化、CS低下の回避）

とパターンがあるので、目的は入念に確認する必要があります。

<img width=200px src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/bce068fe-32d7-6375-41e0-b5dcba1fe4b9.png>

### 目的②：ロスの最小化
　食品、薬剤などの消費、使用に期限がある商材の過剰在庫はロスの原因となります。
ロスは、経済的なデメリットもあれば、フードロス等の観点でも最小化したいものです。
特に消費・使用期限がある商材の需要予測では、

* 目的①（機会損失）のために在庫に余裕をもたせると、目的②（ロス）が達成できず
* 目的②（ロス）のために在庫をギリギリにすると、目的①（機会損失）が達成できず

と①と②は、トレードオフの関係にある点を理解することが重要かと思います。

![multi_syouhou_zaiko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/66594c7f-be3b-3799-3013-17a0807c497d.png)


### 目的③：倉庫在庫の最適化
目的①②は「売り場」観点でしたが、目的③は「サプライチェイン」観点での目的です。

* 商材のサイズが「大きい、重い」等で保管スペースを要する
* 商材の保管条件が「温度、湿度、保管場所を選ぶ」等でシビア

といった具合に、倉庫で保管するにしても、その保管自体のコストが大きい。
そのため、目的①～②の売り場の論点とバランスを取りながら、倉庫在庫を最適化したい。[^1]
そういった目的が③です。

[^1]: 「売り手」の論点と比較し、「サプライチェイン」の論点はこの需要予測に加えて、商材の導線の整理が必要等で一般に複雑です。具体的には、倉庫に在庫される商品はどれだけあって、それらがどれくらいの保管スペースを要するか？それらの商材のハンドリングにはどれだけの手間がかかるか？といった需要予測以外の論点も出てきます。ただし、これらの検討のベースとなるのは、需要の予測と理解しています。その需要量をベースとして、離散事象シミュレーション等のツールも活用します。

![souko_building.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/af39103a-7d10-39be-c3fa-328e61cd98ad.png)

### 目的④：店舗在庫の最適化
目的④も「サプライチェイン」観点で、倉庫ではなく店舗（の保管スペース）の論点です。

* 特に、店舗の在庫スペースが狭く、在庫量が限られる業態（狭小店舗等）
* 在庫回転率が高いが、在庫量も限られるので、店舗の在庫スペースを上手く使いたい

店舗の在庫スペースを上手く使うためには、その店舗での商品毎の需要予測が必要です。

![nimotsu_picking_tanaoroshi_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/863a6701-5296-c359-758a-db40993f108c.png)

### 目的⑤：バランスシートの適正化
　在庫はバランスシート上、資産[^2]であり、在庫を持ちすぎると資本効率性が低下します。
売り場の論点である目的①②や、SCMの論点の目的③④とはまた異なる論点です。
主には、単価が高く、在庫回転率の低い在庫をいかに減らすか？が重要です。

[^2]: 商材やその特性によりますが、一般には流動性が低い資産であり、資本効率が低下します。

![money_choubo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/a0c3a380-05d8-717c-fb15-17975537fe11.png)


## ゼロ過剰って？

「ゼロ過剰」、言葉の通り「ゼロ」が「過剰」な状態です。
「ふつー」の状態と「ゼロ過剰」な状態を比較して見ていきましょう。

### 「ふつー」の需要予測
　例えば、Amazonや楽天等のECにて、ある機種の「マウス」の日別販売量を予測したい。
「ふつー」の需要予測では、
* 学習対象：下図の、<font color=#0066FF>**1/1～1/23日**の期間</font>が学習データ
* 予測対象：下図の、<font color=#FF9933>**1/24～1/31**の期間</font>が未知で、これを予測

といった具合に、学習対象のデータに含まれる周期性・傾向を学習し、未来の売上を予測したい。よく見る「ふつー」の需要予測や回帰分析、時系列分析です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/86acd88d-b3e8-6038-aacd-4404815bb258.png)


### 「ゼロ過剰」な需要予測
**用途が限られるマニアックな「ネジ」** の日別販売量を予測したい。
マニアックなネジですので、毎日売れるわけは無く、**売上「ゼロ」が大量**[^zero] に並びます。
これがカウントデータにてゼロが過剰である<font color=red>**「ゼロ過剰」**</font> な状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/c37cc03a-eccd-6ff9-6753-999bae2e3cd1.png)

[^zero]: 販売実績データに、売上「ゼロ」が並ぶのですが、実は２つのケースで発生します。それは「需要不足（売れない）」と「需要過多（売り切れ）」です。この２つの全く反対の現象が、売上「ゼロ」としてデータにあらわれてくるので注意が必要です。よって、実際は、販売実績データだけではなく在庫マスタ等を確認し、「売上ゼロ時に、在庫もゼロではなかったか？」の確認が必要で、注意すべきポイントです。

### 「ゼロ過剰」の何が問題か
　ARIMA、Prophet、LSTM等の時系列モデルでも良いですし、LightGBMのようなモデルでも良いのですが、機械学習以前に、**人間が予測するとしたら**どちらが難しそうでしょうか？

#### 「ふつー」の需要予測
　月の前半／後半がよく売れる。土曜日はよく売れる。５日に１度よく売れる。といった具合に傾向や周期性から、未来の売上が予測できるかもしれません。

#### 「ゼロ過剰」の需要予測

* **「販売事象の発生」**　　：数量は問わず、 **「どのタイミング」** で販売が発生するか？
* **「その時の販売数量」**　：販売が発生する日には、その日に **「何個売れるか？」** 

と、「販売の発生有無」とその時の「販売数量」を予測する必要があり、機械学習を使うか以前に、人が予測するとしても難易度が高いテーマなのです。

## 正攻法
正攻法としては、下記にあるような「ハードルモデル」や「ゼロ過剰モデル」を用いる。[^3]
（恐縮ながら、リンクさせて頂きます。）


[^3]: ハードルモデルとゼロ過剰モデルでは、２段目のPoisson分布による推定にて、ゼロを扱うか否かに差があるので「ゼロを扱わない、ゼロ切断Poisson分布として扱うべきなのか？」で判断が分かれるようです。


https://qiita.com/nozma/items/52211b1bacaa8a898164

　または、「販売の発生有無」とその時の「販売数量」をうまくハンドリングできような、Gamma分布（各事象）とPoisson分布（一定期間内の発生回数）の混合分布のTweedie分布[^4]のような確率分布を活用してみる等、あると思います。

 https://en.wikipedia.org/wiki/Tweedie_distribution

**ただ、本稿では少し違う角度から**、この問題にアプローチしてみたいと思います。

[^4]: 生存分析等の医療統計、気象学や気候学、計量経済学等、様々な分野で活用されているようですが、保険数理研究（アクチュアリー）の分野で使われている事が多い様です。例えば、保険金の支払い等、普段は発生しない（ゼロ）なのだが、事象発生時にどれだけの保険金支払いが発生するか？といった用途に利用されます。


# （ちょっと脱線）３つの着眼点
**「解くことが難しい」** 問題に直面した時のアプローチの着眼点は、
**「i）問題、ii）データ、iii）学習」** の３種に分類できるのではないか？と考えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/d1fd0b98-b020-9c7c-2655-ccb1dd1f1d58.png)

　上記は着眼点毎に「どんなアプローチがあるか？」、「その効果（私見）※」を整理したものですが、「解くことが難しい」問題に直面した際には、「ii）データ、iii）学習」に着目するよりは、「i）問題」そのものに着目し、

**「解くことに意味があり、解くことが可能な問題を見つける・問題を変化させる」**

アプローチが重要で、どう頑張っても「解けない問題は解けない」ですので、その問題にこだわる事無く、当初設定した目的が達成可能な方法を検討すべきと考えます。

:::note warn
※上記の着眼点、アプローチ、（特に）効果は、完全に著者の私見です。
なんの保証もありません（笑）
:::

# 需要予測でのゼロ過剰へのアプローチ
　では、ゼロ過剰にはどの様にアプローチ（問題を変化させれば）良いでしょうか？
本稿では、下記３つの対応策を検討してみたいと思います。

* １）ロングテールを諦める（売れ筋に絞る）
* ２）単品予測を諦める（商品分類別）
* ３）日次予測を諦める（週次、月次）

　「諦める」というネガティブワードが並びますが、冒頭の**需要予測の目的①~⑤**が達成できるのであれば、難しい問題を無理に解く必要はありません。目的が達成できるように問題を再設定すれば良いのです。

## １）ロングテールを諦める（売れ筋に絞る）[^longtail]
　「ゼロ過剰」の原因は何でしょうか？「売上がゼロ」が一杯なので困っているわけで、「売上がゼロ」になりそうな、売れ筋ランキング下位の商品を予測対象外としてしまう。
つまりロングテール品の予測を諦めるという方法です。

[^longtail]: 近年、ロングテール領域の需要予測に取り組む事例も増えてきており、そういったものを否定する意図はありません。ただ、需要予測を活用する上で、販売実績データがパレート則に従うのであれば、まず取り組むべきは売れ筋のセグメントで、そこが達成できたら、次はロングテールのセグメント。そういった順番論かなと考えています。がこれも目的次第ですね（笑）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/32fd0182-4bba-cb5b-4616-32ece0585f85.png)

こんな事して良いのでしょうか？

https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AE%E6%B3%95%E5%89%87

Wikipediaにあるように、

> 商品の売上の8割は、全商品銘柄のうちの2割で生み出している。

販売実績データにて、上記のような「パレート則」が確認されたのならば、

**予測の対象を上位２割に絞っても、売上の８割の需要を正確の予測できる可能性がある。**

冒頭の目的①～⑤を再掲すると、**目的①**で特に、機会損失の回数ではなく、
**機会損失額の最小化**が需要予測の目的ならば、有効なアプローチといえるでしょう。

| # | 目的 | 主たる要請元 | メモ |
|:---:|:---:| :---:| --- |
| ① | **機会損失**の最小化 | 売り場（需要） | 損失回数や損失額 |
| ② | **ロス**の最小化 | 売り場（供給） | 消費・使用期限がある商材にて |
| ③ | **倉庫在庫**の最適化 | SCM（倉庫） | 保管にコストを要する |
| ④ | **店舗在庫**の最適化 | SCM（店舗） | 店舗の保管スペースに限りがある |
| ⑤ | **バランスシート**の適正化 | 財務（資本効率） | 高価格・低回転な商材にて |

　また、**目的④の店舗在庫の最適化**を考えてみると、店舗の在庫スペースが狭小で、そもそもロングテール品を在庫するような余裕がない場合には、予測対象からロングテールを外してしまうのは良い選択なのではないでしょうか？

　一方で、**目的⑤ バランスシート適正化**の場合、ロングテールの中に「高価格・低回転な商品が含まれる」といったことがあるので、目的を達成できない可能性があります。
　ただ、ここは商材の特性によるので、注意が必要です。例えば、高価格・低回転が宝飾品のようなものであれば、倉庫に在庫しているかもしれませんが、産業機械の様に「発注を請けてから60日で納品」といった類のものの場合、そもそも倉庫に在庫はせずに、メーカ→顧客で直送になるかもしれません。業務や目的を明確にする必要があります。


## ２）単品予測を諦める（商品分類別）[^cat]
　次のアプローチは、やはり「ロングテール」もある程度予測したい。といった場合にどうするか？ですが、改めて、なぜ「売上ゼロ」が発生するのでしょうか？
　それは、マニアックなネジ **「単品」** で売上を予測するからです。
「売上ゼロ」が発生しないように、**「単品」ではなくひとつ上の「商品分類」** のレベルで予測してあげれば良いのです。

[^cat]: 単品でなく商品分類やカテゴリでの需要予測は、ロングテール品に限らずメリットがある場合があります。単品での需要予測では、単品毎の需要に対して潜在的な需要に＋／―の双方向にノイズが乗ります。これを商品分類やカテゴリ毎の需要予測にしてあげることにより、その＋／―の双方向のノイズが互いに打ち消し合い予測がし易い状況を作り出すことができます。また、マウスの例で言えば、メーカ毎、機種毎のノイズは様々な要因の影響を受けますが、メーカ、機種問わず「マウス」という商品分類に対する（買い替え）需要は、「マウスでPCで作業をする母数　ｘ　マウスの平均故障率」といった形で表されるはずなので予測傾向も安定します。その為、ロングテール品以外だとしてもこのノイズの相殺効果や予測傾向の安定性を狙う目的で単品予測ではなく、カテゴリ予測を行う場合もあると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/e3ee689f-e7e7-40b3-7db2-fca185649ad5.png)

　つまり、マニアックでロングテールになりそうな「商品分類」については「単品」ではなく **「商品分類」毎に１日に何個売れそうか？** を予測してあげる。これにより「ゼロ過剰」を回避することができます。
　仮に、単品での日販予測値がほしい場合には、商品分類毎での予測結果を、商品分類に占める単品毎の売上構成比（期間平均値）で割り戻せば、ある程度の目安となる数値を作ることができます。
　一方、このアプローチは、商品分類「ネジ」と単品「各種ネジ類」は、ちょっとマニアックなネジを含めて、その需要は一定の連動性が有るであろうという前提をおいて算出した参考値なので、扱いは注意が必要です。

## ３）日次予測を諦める（週次、月次）
　最後のアプローチは、日次予測を諦めるというものです。
「売上ゼロ」の原因を商品単品に求めるのではなく、日別予測を原因とみなすのならば、日別ではなく、週別／月別と集計期間を長くすることで、「売上ゼロ」を回避するアプローチです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/de673c61-1dc7-3f92-fd6a-ba35317530ee.png)

　どんなに売れない商品でも、週や月、四半期まで遡って上げれば、「売上ゼロ」を回避できるはずです。商品分類と同様に、週販や月販を予測し、日次予測がほしい場合には、曜日別等の売上構成比（期間平均値）で割り戻すことで、目安となる数値を手に入れることができます。

また、**需要予測において本当に、日次の売上予測が必要なのか？[^Lot]** という話もあります。

　例えば、日次で需要が予測できたとしても、発注周期や納品周期が週次や月次の商材だったりすると、結局、発注／納品は週次や月次となるので意味がありません。
その意味でも、目的に立ち返り、本当に、日次での需要予測が必要なのか検討してみることは価値があるでしょう。

[^Lot]: 発注／納品周期以外にも、ロット（最小発注数）も留意が必要です。あまり無いですが、最小発注数が大きい割に売れ行きはほぼゼロといった商材があった場合には、日別に予測しても結局、最小発注数が大きいので、日別と細かく需要予測する意味が薄れます。

## まとめ
　**どの手がつかえるかは、結局、目的次第**です。目的に立ち返ることで、問題をどこまで変化・改造してよいかが見えてきます。「解くことが困難な問題」に直面した際には、 まず、

* その問題は本当に解くべき、解くに値する「問」なのか
* もっと簡単にその問題を解くことはできないか

**「問題」に着目し、対応方法を検討してみてはいかがでしょうか？というご提案でした。**

そして需要予測における「ゼロ過剰」の原因は下記の３点です。

* 対象に**ロングテール品**を含む
* 商品**単品**の予測
* **日別**売上の予測

　このうちどれか１つ、もしくは複数を、崩すことができれば「ゼロ過剰」は回避できると考えています。問題を解きやすい構造へ変化させ、もっとも簡単な手順で目的が達成出来るよう、今後も精進して参りたいです。

<img width=600px src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/14ec87f7-cab3-923a-a9b5-1507e9fa7e2f.png>


# おまけ
**i）「問題」** にて、解くべき問を定めたあと、次に着目すべきは、**ii)「データ」** であり、
そこで重要になるのが、**特徴量エンジニアリング**です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/9ae7b5b4-cdb6-14bf-a08f-1b390b0dcf29.png)


私事で恐縮ですが、直近、こういった書籍の翻訳、監訳を担当させていただきました。
12月下旬に書店等店頭に並ぶと思いますので、ぜひお手に取ってみて頂ければ嬉しいです。

https://www.oreilly.co.jp/books/9784814400546/

<a href="https://www.amazon.co.jp/dp/4814400543">
<img width=200 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183826/e2c1d961-c78f-652a-95fa-8c375726cc77.jpeg">
</a>

# 参考
* [ゼロがたくさんあるカウントデータを扱う](https://qiita.com/nozma/items/52211b1bacaa8a898164)
* [A comparison of zero-inflated and hurdle models for modeling zero-inflated count data](https://jsdajournal.springeropen.com/articles/10.1186/s40488-021-00121-4)
* [Tweedie Gradient Boosting for Extremely Unbalanced Zero-inflated Data](https://arxiv.org/abs/1811.10192)
* [Identifying and Overcoming Transformation Bias in Forecasting Models](https://arxiv.org/abs/2208.12264)
* [Tweedie_distribution @ Wikipedia](https://en.wikipedia.org/wiki/Tweedie_distribution)
* [Zero-inflated_model @ Wikipedia](
https://en.wikipedia.org/wiki/Zero-inflated_model)
* [Hurdle_model @ Wikipedia](https://en.wikipedia.org/wiki/Hurdle_model)
* [モデル最適化指標・評価指標の選び方](https://www.datarobot.com/jp/blog/model-optimization-metrics-and-evaluation-indicators/)