精肉店が商品ごとの売上・曜日・天気・催しの記録から Python で翌週の売れ数を幅付きで予測し、部分肉の仕入と日ごとの加工の量の案を出す
精肉店のレジの商品別の売上と、曜日・天気・催しの記録から、Python で翌週の商品ごと日ごとの売れ数を幅付きで予測します。歩留まりの表で部分肉の必要量に直し、仕入のケース数と加工の量の案を出します。
- 連携・自動化
- Python
- 対象業界
- 小売/飲食
- 対象部門
- 生産/購買
- 対象業務
- 集計・分析
- 主な課題
- データ分析に時間がかかる/判断に時間がかかる/属人化している
- AIで行う処理
- 予測
- 主な効果
- 判断支援/属人化解消/機会損失防止
- 導入難易度
- ★★★★☆
- 実装レベル
- 本格構成
- 費用感
- 個別開発(大)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 木曜の夕方、店主がレジから先週と前年の同じ週の商品別の売上を印刷する
- 商品ごとに、前年の同じ週・先週・先々週の売れ方を見比べる
- 週間の天気予報と、翌週の売出し・地域の催しを見て、商品ごとに翌週の日ごとの売れ数を頭の中で決める
- 商品の売れ数を、どの部位からどれだけ取るかに直し、部位ごとの必要量を手計算する
- 冷蔵庫の在庫を見て差し引き、問屋のケースの単位に丸めて発注量を決める
- FAX で問屋に発注し、加工の責任者に日ごとの加工の量をメモで渡す
- 人毎日の閉店後、加工の責任者が売り切れた商品と時刻、廃棄と値引きの数を記録のシートに入れる(1日数分)
- 人水曜に、店主が翌週の催しの予定と、週間天気予報の日ごとの最高気温と天気を予定のシートに入れる
- 自動木曜の昼、店のパソコンで Python が動き、レジの CSV と記録のシートを読み込む
- 自動学習済みのモデルで、翌週の商品ごと日ごとの売れ数を、中央と上振れと下振れの3つで予測する
- 自動歩留まりの表で部位ごとの必要量に直し、在庫を引いて、ケースの単位で仕入の案を作る
- 自動日ごとの加工の量の案と、予測が大きく振れている商品の印を付けた表を作る
- 人店主が印の付いた商品を中心に見て、仕入の案を直す
- 人店主が問屋に発注し、加工の責任者に日ごとの加工の量の表を渡す
各工程の詳しい説明を読む
- 木曜の夕方、店主がレジから先週と前年の同じ週の商品別の売上を印刷する
- 商品ごとに、前年の同じ週・先週・先々週の売れ方を見比べる
- 週間の天気予報と、翌週の売出し・地域の催しを見て、商品ごとに翌週の日ごとの売れ数を頭の中で決める
- 商品の売れ数を、どの部位からどれだけ取るかに直し、部位ごとの必要量を手計算する
- 冷蔵庫の在庫を見て差し引き、問屋のケースの単位に丸めて発注量を決める
- FAX で問屋に発注し、加工の責任者に日ごとの加工の量をメモで渡す
(a)店主しか決められない。 2番目と3番目は、何年もの経験で見当を付けています。店主が仕入の展示会や体調で木曜にいないと、加工の責任者が先週と同じ量で発注します。 天気が変わる時期は、それで大きく外れます。
(b)部位の取り合いを頭で計算している。 肩ロースをしゃぶしゃぶ用に多く回せば、生姜焼き用ととんかつ用が減ります。4番目は商品の数だけ掛け算と足し算があり、店主も細かくはやらずに丸めています。 丸めた分は、端材が余るか、特定の商品が昼に売り切れる形で出てきます。
(c)売り切れた日の売上を、そのまま「売れた数」として見ている。 前年の同じ週に昼で売り切れていた商品は、売上の数字だけを見ると少なく見えます。それを基準にすると、また売り切れます。 どの日に売り切れたかは店主の記憶にしかありません。
(d)振れる週ほど時間がかかる。 天気や催しが重なる週は、商品ごとに迷い、木曜の夜が長くなります。普段の週は先週と同じでも大きくは外れず、迷うのは一部の週と一部の商品です。 その見分けを毎週一から行っています。
- 【人】 毎日の閉店後、加工の責任者が売り切れた商品と時刻、廃棄と値引きの数を記録のシートに入れる(1日数分)
- 【人】 水曜に、店主が翌週の催しの予定と、週間天気予報の日ごとの最高気温と天気を予定のシートに入れる
- 【自動】 木曜の昼、店のパソコンで Python が動き、レジの CSV と記録のシートを読み込む
- 【自動】 学習済みのモデルで、翌週の商品ごと日ごとの売れ数を、中央と上振れと下振れの3つで予測する
- 【自動】 歩留まりの表で部位ごとの必要量に直し、在庫を引いて、ケースの単位で仕入の案を作る
- 【自動】 日ごとの加工の量の案と、予測が大きく振れている商品の印を付けた表を作る
- 【人】 店主が印の付いた商品を中心に見て、仕入の案を直す
- 【人】 店主が問屋に発注し、加工の責任者に日ごとの加工の量の表を渡す
1番目の売り切れの記録が、この設計の土台です。 売り切れた日を印で分けなければ、モデルは「売り切れるまでの数」を覚え、同じ売り切れを繰り返します。 記録は時刻と商品を書くだけで、閉店後の数分で終わります。
7番目で確定させるのは店主です。 モデルは過去にあったことしか知りません。新しい取引先の飲食店からの注文、テレビの紹介、問屋の値上がりは、店主が足し引きします。
02今回想定するシステム構成
レジの商品別・日別の売上(CSV) + 売り切れ・廃棄・値引きの記録(スプレッドシート) + 過去の天気(気象庁の過去の気象データ)+ 祝日(内閣府のCSV) + 翌週の催しと天気予報(店主が入れる予定のシート) │ ▼【トリガー】毎週木曜の昼(店のパソコンの定時実行) Python(pandas) ├──▶ 商品ごと日ごとの表にそろえ、売り切れの日に印を付ける ▼ scikit-learn(HistGradientBoostingRegressor、分位点の損失で3本) │ 翌週の商品ごと日ごとの売れ数:下振れ・中央・上振れ ▼ Python ── 歩留まりの表で部位ごとの必要量に直し、在庫を引いてケースに丸める ▼ 仕入の案と、日ごとの加工の量の案(印刷用の表) ▼ 【人】店主が印の付いた商品を見て直し、問屋に発注
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Python(pandas・scikit-learn) | R |
| 処理エンジン | scikit-learn の HistGradientBoostingRegressor(分位点の損失) | LightGBM、Prophet |
| 集計 | Python(歩留まりの換算、在庫の差し引き、ケースへの丸め) | スプレッドシートの計算式 |
| 保管 | Google スプレッドシート(売り切れ・廃棄の記録、予定、歩留まりの表、在庫) | - |
新しく足すのは、Python の処理と、売り切れ・廃棄の記録、予定のシート、歩留まりの表です。 レジとFAXの発注はこれまでどおりで、この構成は問屋に発注を送りません。 出すのは店主が直すための案です。
予測のエンジンに HistGradientBoostingRegressor を選んだのは、3つの理由からです。 1つ目は、loss="quantile" と quantile の指定で、中央だけでなく上振れ・下振れの線を同じ仕組みで引けること。2つ目は、categorical_features の既定が 'from_dtype' で、pandas の Categorical の列(商品・曜日)をそのまま扱えること。3つ目は、欠けた値(天気の記録が抜けた日)を埋めずに学習できることです。公式の説明では、分岐ごとに欠けた値を左右どちらに送るかを学習するとされています。
生成AIは使いません。 売れ数の見込みは数の問題で、文章を作る部分がありません。 店主に渡すのは表です。
03どうやって実装するのか
処理の起点を決める
毎週木曜の昼に1回動かします。 問屋の発注の締めが木曜の夜なので、店主が昼休みの後に案を見て、夕方までに直せる時刻にします。店のパソコンの定時実行の仕組み(Windows ならタスク スケジューラ)で Python のスクリプトを起動します。
水曜の夜までに予定のシートが入っていることが前提です。 木曜の昼の時点で翌週の予定の行が空なら、予測は出しますが、表の一番上に「予定と天気予報が未入力」と大きく出します。 天気と催しの無い予測は、普段の週の見込みにしかなりません。
月に1回、モデルを作り直します。 毎月の第1木曜の朝に、先月までの記録で学習し直し、作り直す前と後で、先月の4週の当たり方を比べた結果を残します。悪くなっていれば、前のモデルのまま使います。
店のパソコンが止まっていると動きません。 動かなかった週は、店主が手で実行できるように、デスクトップに実行のためのショートカットを置きます。 結果の表には、作った日時を必ず印字します。古い表で発注しないためです。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 売上 | 日付、商品コード、売れた数(パック数または重さ)、売上額 | レジの CSV |
| 売り切れ・廃棄・値引き | 日付、商品、売り切れた時刻、廃棄の数、値引きした数 | 記録のシート(新しく作る) |
| 過去の天気 | 日ごとの最高気温、降水量 | 気象庁の過去の気象データ・ダウンロード(CSV) |
| 祝日 | 国民の祝日の日付 | 内閣府の祝日の CSV |
| 予定 | 翌週の日ごとの催し(売出し・地域の行事・給料日の前後)、天気予報の最高気温と天気 | 予定のシート(店主が入れる) |
| 歩留まりの表 | 部位ごとに、どの商品へ何割取れるか。端材の割合 | スプレッドシート(店で量って作る) |
| 在庫 | 木曜の昼の時点の部位ごとの在庫の重さ | スプレッドシート(加工の責任者が入れる) |
| ケースの単位 | 問屋の部位ごとのケースの入り数と重さの目安 | スプレッドシート |
質を決めるのは、売り切れの記録と歩留まりの表です。 売り切れの記録が無ければ予測は低めに偏り、歩留まりの表が無ければ、商品の予測を仕入に直せません。 どちらもレジからは出てこないデータで、この構成のために店で付け始めるものです。
歩留まりの表は、店で実際に量って作ります。 同じ部位でも、問屋や時期によって脂の付き方が違い、本や業界の目安の数字では合いません。 部位ごとに数回、加工の前後の重さを量り、平均を表に入れます。
データの取得方法を決める
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 売上 | レジから毎日書き出す CSV を、決まったフォルダに置く | 学習の目的の値(売れた数) |
| 売り切れ・廃棄・値引き | 記録のシートを CSV で書き出す | 売り切れの日の印と、売れ残りの把握 |
| 過去の天気 | 気象庁の過去の気象データ・ダウンロードで、近くの観測地点の日別の値を CSV で取る | 最高気温・降水量の項目 |
| 祝日 | 内閣府の祝日の CSV | 祝日の印 |
| 予定・天気予報 | 予定のシート | 翌週の催しと天気の項目 |
過去の天気は、月に1回まとめて取ります。 気象庁の過去の気象データ・ダウンロードは、地点と項目と期間を選んで CSV で落とせます。CSV には値の列のほかに品質情報や均質番号の列が並ぶので、値の列だけを名前で選んで読み込みます。列の位置で読むと、項目を足したときにずれます。
翌週の天気は、店主が週間天気予報を見て入れます。 予報を自動で取りに行く仕組みも考えられますが、この構成では店主が見て入れる形にしています。 毎週7日分で数分の作業で、予報を見ること自体が店主の判断の材料になるからです。
祝日の CSV は、内閣府が翌年の分を前の年の2月に載せるとされています。年に1回、2月に入れ替えます。
AIへ渡す前に整形する
- 商品コードをそろえる … レジの商品コードが変わった商品(名前を変えた、量を変えた)を、対応表で1つにまとめます
- 商品ごと日ごとの表にする … 売れなかった日を0で埋めます。休業日は0ではなく行ごと外します
- 売り切れの日に印を付ける … 売り切れた時刻が閉店の2時間より前の日を「売り切れ」とします
- 売り切れの日の目的の値を扱う … 売り切れの日は、売れた数を「少なくともこれだけ」の値として、学習から外すか、上振れのモデルだけに使います
- 項目を作る … 曜日、祝日とその前日、月、年の中の週、最高気温、降水量の有無、催しの種類、前年の同じ週の同じ曜日の売れ数、直近4週の同じ曜日の平均
- 商品と曜日を Categorical にする … pandas の Categorical の型にしておけば、
categorical_featuresの既定でそのまま扱われます
3番目と4番目が、この構成の肝です。 売り切れの日をそのまま学習させると、モデルは店の棚の量を覚えます。閉店の2時間前という線は、店主と相談して決めます。 夕方の売り切れは「ちょうど売り切った」日で、昼の売り切れは「足りなかった」日です。
単位をそろえることにも気を付けてください。 パックで売る商品は1パックの重さが決まっていますが、対面の量り売りは客ごとに重さが違い、レジには売上額とグラムが残ります。同じ「豚バラ」でも、パックと量り売りを別の商品として予測し、部位に直すときに重さで足し合わせます。 1つにまとめると、パックの数とグラムが混ざった目的の値になり、何を予測しているのか分からなくなります。
飲食店への卸は、店頭の売上と分けます。 卸は注文があってから切るもので、曜日や天気より取引先の都合で動きます。店頭の予測の学習からは外し、仕入の案を作るときに、決まっている注文の量だけを部位ごとに足します。
年末の数日は、別に扱います。 年に1回しか来ない売れ方で、学習の記録が少ないためです。12月の最終週は予測を出しつつ、表に「年末:前年の実績を必ず見る」と印を付けます。
AIに処理させる
させるのは、翌週の商品ごと日ごとの売れ数を、3つの分位で予測することだけです。 機械学習のモデルを3本作り、それぞれ quantile を0.2・0.5・0.8にします。
| 出すもの | 中身 | 使いみち |
|---|---|---|
| 下振れ(0.2) | 5回に1回はこれを下回る見込み | 売れ残りの心配が大きい商品の目安 |
| 中央(0.5) | 半々の見込み | 加工の量の基準 |
| 上振れ(0.8) | 5回に1回はこれを上回る見込み | 売り切れを避けたい商品の目安 |
商品ごとに、中央と上振れのどちらで仕入れるかを決めておきます。 日持ちのしない生の薄切りは中央に寄せ、ひき肉やメンチに回せる部位から作る商品は、売れ残っても端材の行き先があるので上振れに寄せられます。この選び方は店主の判断で、表の設定の列に持たせます。
モデルは商品ごとに作らず、1本で全商品を学習させます。 商品を Categorical の項目として入れることで、売れる数の少ない商品も、似た商品の曜日や天気の動き方を借りられます。 30商品で30本のモデルを持つより、作り直しも当たり方の確認も楽になります。
| させないこと | 理由 |
|---|---|
| 発注の確定 | 問屋との関係、値上がり、新しい注文は店主が足し引きする |
| 値引きの時刻と率 | 予測とは別の判断。店頭の様子で決める |
| 消費期限の判断 | 衛生の管理は店の決まりで行う |
| 催しの効果の推し量り | 初めての催しは記録が無い。店主が上乗せする |
| 歩留まりの推定 | 店で量った表を使う。モデルに覚えさせない |
当たり方は、店主の見当と同じ物差しで比べます。 去年の同じ週の実績をそのまま翌週の見込みにする「前年どおり」と、先週と同じにする「先週どおり」を並べ、モデルの中央の外れがその2つより小さいかを、商品ごとに見ます。 どちらにも勝てない商品は、モデルを使わずに前年どおりで出し、表に「前年どおり」と書きます。
4行目を気を付けてください。 初めて行う売出しは、モデルにとって「普段の週」と同じに見えます。予定のシートに初めての催しの印があれば、表で「初めての催し:上乗せを店主が決める」と出します。
指示内容を固定する
生成AIを使わないので、プロンプトはありません。 かわりに、予測の中身を決める学習の設定を示します。
from sklearn.ensemble import HistGradientBoostingRegressor
FEATURES = ["item", "weekday", "is_holiday", "is_pre_holiday", "month",
"week_of_year", "temp_max", "rain", "event_type",
"last_year_same_wd", "recent4w_same_wd_mean"]
# item・weekday・event_type は pandas の Categorical にしておく
# categorical_features の既定 'from_dtype' でカテゴリとして扱われる
def fit_quantile(df, q):
# 売り切れの日を外して学習する(上振れのモデルにだけ含める案も試す)
train = df[~df["sold_out_early"]] if q < 0.8 else df
model = HistGradientBoostingRegressor(
loss="quantile", quantile=q,
max_iter=500, learning_rate=0.05,
early_stopping=True, validation_fraction=0.15,
random_state=0,
)
model.fit(train[FEATURES], train["sold_qty"])
return model
models = {q: fit_quantile(history, q) for q in (0.2, 0.5, 0.8)}
学習の目的の値は、売上額ではなく売れた数です。 値上げや値引きで売上額が動いても、仕入に要るのは数と重さだからです。パックで売る商品はパック数、対面の量り売りはグラムで持ち、歩留まりの換算のときに重さにそろえます。
early_stopping を明示的に有効にしているのは、既定の 'auto' では、学習の行が10,000を超えるときにしか有効にならないからです。 30商品で2年分なら超えますが、商品を絞って試す段階では超えないことがあります。
3本のモデルの線が交わることがあります。 分位ごとに別々に学習するため、まれに下振れが中央を上回ります。その場合は3つの値を小さい順に並べ替えて使い、交わった件数を記録に残します。 多いようなら、項目か学習の量を見直す合図です。
出力形式を固定する
店主に渡すのは、次の2つの表です。 印刷して木曜の夕方に見ることを前提に、A4の横1枚に収まる形にします。
【仕入の案(部位ごと)】
| 部位 | 翌週の必要量(中央) | 上振れのとき | 在庫 | 仕入の案(ケース) | 印 |
|---|---|---|---|---|---|
| 豚肩ロース | 38.4kg | 45.1kg | 6.0kg | 4 | 寒くなる予報 |
| 牛肩ロース | 12.2kg | 15.8kg | 2.5kg | 2 | 振れ大 |
| 鶏モモ | 30.5kg | 34.0kg | 4.0kg | 3 | - |
【日ごとの加工の量(商品ごと)】
| 商品 | 月 | 火 | 水 | 木 | 金 | 土 | 日 | 寄せ方 |
|---|---|---|---|---|---|---|---|---|
| 豚しゃぶしゃぶ用(パック) | 14 | 12 | 13 | 12 | 16 | 24 | 22 | 中央 |
| 合挽きひき肉(g) | 3,200 | 2,800 | 3,000 | 2,900 | 3,500 | 5,200 | 4,800 | 上振れ |
「印」の列が、店主の目を向ける先です。 中央と上振れの差が大きい部位には「振れ大」、予定のシートの天気予報で最高気温が前の週から大きく下がる週には「寒くなる予報」、初めての催しには「催しの上乗せ未定」を出します。印の無い行は、案のまま発注して大きくは外れない行です。
機械で読む用には、同じ内容を CSV でも残します。 列は、週、部位または商品、日、下振れ・中央・上振れ、寄せ方、在庫、仕入の案、印、モデルを作った日付です。翌週に実績と並べて当たり方を見るのは、この CSV です。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| レジ | 毎日の CSV の書き出しを決まったフォルダに置く | 売上を読む |
| 記録・予定・歩留まり・在庫のシート | スプレッドシートを CSV で書き出して読む(またはシートの API で読む) | 売り切れの印、催し、換算、在庫 |
| 気象庁の過去の気象データ | 月に1回、画面から CSV を落としてフォルダに置く | 過去の天気 |
| 内閣府の祝日の CSV | 年に1回、入れ替える | 祝日の印 |
| 問屋 | つながない(店主が FAX と電話で発注) | - |
問屋への発注は自動にしません。 精肉の仕入は、問屋との日々のやり取りの中で、「今週はこの部位が高い」「この部位は品薄」という話を聞きながら決めるものです。案を見て店主が直す時間を、構成の中に残します。
レジの CSV は、書き出しの手順を決めておきます。 レジの機種によって、商品別の売上を日付の範囲で書き出す画面が違います。毎日閉店後に前日分を書き出すか、週に1回まとめて書き出すかを決め、ファイル名に日付を入れるように決めます。
人が確認する
店主が見るのは、印の付いた行です。
- 作った日時を見る … 表の上の日時が当日の昼であることを確かめます。古い表で発注しない
- 印の付いた部位から見る … 「振れ大」「寒くなる予報」「催しの上乗せ未定」の部位で、上振れに寄せるか中央に寄せるかを決めます
- 予測の外の事情を足し引きする … 飲食店からの大口の注文、問屋の値上がり、品薄の話を足し引きします
- 直した数を表に書き込む … 直した量と理由を一言書き、翌週の当たり方の確認に使います
目標は、30商品をならして1件2分です。 印の無い行は数字を見て丸を付けるだけで、時間を使うのは印の付いた数商品です。
加工の責任者は、日ごとの加工の量の表を見て、前の日の売れ残りを引いて加工します。 表の数はあくまで目安で、前日の売れ残りと店頭の様子を見て、その日の朝に決めます。
例外に対処する
| 起きること | 対応 |
|---|---|
| レジの CSV が届いていない日がある | その日を欠けとして扱い、表に「売上の欠け:○日」と出す |
| 予定のシートが空 | 予測は出し、表の一番上に「予定と天気予報が未入力」 |
| 新しく売り始めた商品 | 記録が4週に満たない間は予測を出さず、「新商品:店主が決める」 |
| 商品コードが変わった | 対応表に無ければ新商品として扱い、表に出す |
| 3本の線が交わる | 並べ替えて使い、件数を記録 |
| 歩留まりの表に無い商品 | 部位への換算から外し、表に「歩留まり未登録」 |
| 年末・お盆など記録の少ない週 | 予測は出し、「前年の実績を必ず見る」と印 |
| 作り直したモデルが前より外れる | 前のモデルのまま使い、作り直しの記録を残す |
| パソコンが止まっていて動かなかった | 店主が手で実行。作った日時が古い表は使わない |
上から4行目までは、記録の付け方の問題です。 起きるたびに直せば減ります。モデルの問題で起きる例外は、下の方の数行だけです。
記録を残す
- 実行の日時、使ったモデルの作成日、読み込んだ売上の期間
- 商品ごと日ごとの下振れ・中央・上振れと、寄せ方の設定
- 部位ごとの必要量、在庫、仕入の案
- 店主が直した量と理由
- 翌週の実績(売れた数、売り切れた時刻、廃棄・値引きの数)
- 月ごとの当たり方(中央の外れの大きさ、上振れを上回った日の割合)と、モデルの作り直しの結果
4つ目と5つ目を並べると、店主の足し引きが当たったかが分かります。 店主の直しが毎回同じ方向なら、その事情をモデルの項目に足す候補になります。 たとえば、毎週金曜に飲食店の注文の分を足しているなら、注文の予定を項目にできます。
上振れを上回った日の割合は、0.8の線なら5日に1日ほどが目安です。 それより多ければ上振れの線が低すぎ、少なければ高すぎます。この割合が、モデルの線を信じてよいかを見る一番わかりやすい物差しです。
04実装レベルの3段階
本記事の想定は本格構成です。 半自動化では売れ数の見込みまでで、部位への換算と在庫の差し引きは店主の手に残ります。 それだけでも見比べの時間は減りますが、第3章の(b)の部位の取り合いの計算は残ります。 半自動化で1件6分が4分ほどに、本格構成で2分になります。 差が大きいのは、部位への換算とケースへの丸めが、商品の数だけ掛け算のある手計算だからです。 段階を飛ばさないでください。 半自動化の表を1か月見ると、どの商品の予測が当たり、どの商品が外れるかが分かります。 外れる商品の歩留まりや売り切れの記録を先に直してから、本格構成に進みます。 本格構成の先に、卸の注文の予定を取り込む段階も考えられます。 取引先の飲食店から前週のうちに翌週の見込みの量をもらえれば、店頭の予測と卸の予定を部位ごとに足した仕入の案になります。ただし、取引先に手間をかける話なので、無理に進めなくてかまいません。
05工数削減シミュレーション
導入後 120件 × 2分 ÷ 60 = 4 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 部分肉で仕入れて店でスライス・焼肉用・ひき肉・揚げ物などに加工し、対面とパックで売る精肉店。レジで商品ごとの売上を日別に書き出せ、2年分ほどの記録がある場合。毎週の仕入と加工の量を店主が前年と先週の売れ方を見て決めていて、店主が不在だと決められない、または売り切れと売れ残りの出方が週によって大きく振れる場合。精肉の売場を持つ小さなスーパーや、肉料理の多い飲食店の仕込みにも使える。
- 加工済みのパックを仕入れて並べるだけで、店で部位から加工していない場合。レジが部門別の合計しか出せず、商品ごとの売上が残っていない場合。開業から1年未満で、季節の動きが記録に無い場合。なお、仕入の確定、値付けと値引き、消費期限と衛生の管理の判断は、この構成では代替できません。
07最小構成で試す方法
- レジから、よく売れる商品5つの2年分の日別の売上を書き出す
- 店主の記憶とメモから、売り切れた日に印を付ける(分かる範囲でよい)
- 気象庁の過去の気象データ・ダウンロードで、近くの地点の日別の最高気温と降水量を落とす
- Python で第7章の学習の設定を動かし、去年の秋の4週を「翌週」として予測させる
- 当時の店主の仕入と、予測の中央・上振れを、実際の売れ数と並べる
5商品・4週で十分です。 確かめたいのは、「天気と曜日の動きを、店主の見当と同じくらい拾えるか」です。
| 出てきた内容 | 判断 |
|---|---|
| 店主の見当と同じくらい当たり、寒くなる週の伸びも拾えた | 商品を広げ、歩留まりの表を作る段階に進む |
| 普段の週は当たるが、催しの週が外れる | 催しの記録を足す。催しの週だけ店主が上乗せする運用でも進められる |
| 全体に低めに外れる | 売り切れの印が足りていない。記録を付け始めてから学習し直す |
3行目は、ほとんどの店で出ます。 過去の売り切れが記録に無いためで、失敗ではなく、売り切れの記録を付け始める理由が数字で分かったということです。
5商品の選び方にも気を付けてください。 よく売れる商品だけを選ぶと、当たり方が良く見えます。5つのうち1つは、天気で売れ方が大きく変わるすき焼き用か焼肉用を入れ、1つは週に数パックしか出ない商品を入れます。 売れ数の少ない商品でどれくらい外れるかを、最初に知っておくためです。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 売り切れの日を学習させて予測が低めに偏る | 売り切れの時刻を記録し、早い売り切れの日を分けて扱う |
| 歩留まりを業界の目安で入れて仕入が合わない | 店で量った値を使う。問屋や時期で変わるので年に数回量り直す |
| 商品コードが変わって記録が途切れる | 対応表で1つにまとめる |
| 休業日を0として学習する | 休業日は行ごと外す |
| 初めての催しを普段の週と同じに見る | 予定のシートに初めての印を付け、店主が上乗せする |
| 3本の線が交わる | 並べ替えて使い、件数を見る |
early_stopping が効かない | 行が10,000以下だと既定では無効。明示して有効にする |
| 気象庁の CSV を列の位置で読む | 品質情報などの列が並ぶ。列名で選ぶ |
| 古い表で発注する | 作った日時を必ず印字する |
| 当たり方を見ないまま使い続ける | 上振れを上回った日の割合を毎月見る |
| パックと量り売りを1つの商品にする | 単位が混ざる。別の商品として予測し、部位で足す |
| 卸の注文を店頭の売上と一緒に学習する | 卸は外し、決まった注文だけを仕入の案に足す |
上の2行が、この構成の失敗のほとんどです。 どちらも、レジに残らない店の中の事実(どの日に足りなかったか、1本の部位から何が取れるか)を、記録に起こしていないことから起きます。
下の方の行は、作ってからの運用で出てくるものです。 毎月の当たり方の確認を習慣にしておけば、どれも早いうちに気づけます。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 商品別の売上、仕入と在庫、歩留まり、店の催しの予定です。個人の情報は扱いません。 飲食店への卸の売上を含める場合は、取引先ごとの数量が入ります。
- データを外に出さない … 予測は店のパソコンの中で動き、生成AIや外部のサービスに売上を送りません。 気象庁と内閣府からは取ってくるだけです
- 歩留まりの表と仕入の案を、店の外の人と共有しない … 仕入の量と歩留まりは、問屋との交渉や競合に関わる店の情報です
- 発注は人が確定する … 予測は過去にあったことしか知りません。新しい取引、問屋の事情、テレビの紹介は店主が足し引きします
- 予測を消費期限や衛生の判断に使わない … 売れ残りをいつまで並べるか、加工した肉をいつ下げるかは、店の衛生の決まりで決めます。予測が多めだったからといって、期限を延ばす理由にはなりません
- 気象庁のデータの使い方を確かめる … 気象庁のホームページのコンテンツは、権利表記の無いものは公共データ利用規約(第1.0版)に沿って使え、使うときは出典を記載し、加工したものは加工したことを書くとされています。店の中の表でも、天気の列の見出しに出典を書いておくと、表を外に見せることになったときに困りません
誤りが起きた場合のリスクは、仕入が足りずに売り切れることと、仕入が多すぎて廃棄が出ることの2つです。 前者は売り切れの記録を付けずに学習すると起き、後者は上振れの線を全部の商品に使うと起きます。商品ごとの寄せ方を店主が決め、毎月の当たり方を見ることで、両方を抑えます。
10まず何から始めるか
1週目:売り切れと廃棄の記録を付け始める
閉店後に、売り切れた商品と時刻、廃棄と値引きの数を書くシートを作り、加工の責任者が毎日付けます。 これが一番時間のかかる準備で、記録がたまるほど予測が良くなります。
2週目:5商品・4週で試す
第8章のとおり、よく売れる5商品の2年分の売上と気象庁の過去の天気で、去年の秋の4週を予測させます。店主の当時の仕入と並べ、寒くなる週の伸びを拾えるかを見ます。
3週目:歩留まりの表を作る
部位ごとに、加工の前後の重さを数回量り、どの商品へ何割取れるか、端材がどれだけ出るかを表にします。ケースの入り数も問屋に確かめて入れます。
4週目:全商品の予測を毎週出す
木曜の昼に全商品の売れ数の表を出す半自動化を始め、店主はこれまでどおり自分で発注しながら、表と見比べます。 この時期は表で発注を決めず、店主の発注と表の中央のどちらが実績に近かったかを、毎週の月曜に商品ごとに書き残します。 4週分たまると、表を信じてよい商品と、店主の見当のほうが当たる商品が分かれます。
2か月目以降: 部位への換算と在庫の差し引きを足し、仕入の案を出します。店主が直した量と理由、上振れを上回った日の割合を毎月見ます。 店主が印の付いた部位だけを見て発注を決められ、店主が不在の週も加工の責任者が案で発注できるようになった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
HistGradientBoostingRegressor の loss に 'quantile'(pinball 損失)があり quantile で分位を指定すること。categorical_features の既定が 'from_dtype' で Categorical の列をカテゴリとして扱うこと。欠けた値を分岐ごとに左右どちらへ送るか学習すること。early_stopping='auto' は行が10,000を超えるときに有効になること(版 1.9.1) | scikit-learn: HistGradientBoostingRegressor | 2026-10-28 |
| 過去の気象データ・ダウンロードで複数地点・複数項目の過去の観測値を CSV で落とせること。CSV に品質情報・均質番号の列が並ぶこと | 気象庁: 過去の気象データ・ダウンロード(このページでできること) | 2026-10-28 |
| 国民の祝日の CSV が昭和30年から令和9年までを収録し、翌年の分を前年の2月に掲載するとされていること | 内閣府: 国民の祝日について | 2026-10-28 |
| 気象庁のホームページのコンテンツが、権利表記の無い限り公共データ利用規約(第1.0版)に準拠して使え、出典の記載と、加工した場合はその旨の記載が求められること | 気象庁: 気象庁ホームページについて | 2026-10-28 |
仕入の確定、値付け、消費期限と衛生の管理は、店の判断と決まりで行ってください。 本記事は公開されている仕様で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-2140)についてのご相談はこちらから。
