動物園が過去の入園の記録・曜日・天気・催しから Python で日別の入園者数を予測し、ゲートと売店のスタッフの配置と売店の仕入の目安を出す
券売機とゲートの入園の記録に、暦・天気・催し・団体の予約を合わせて、開園日ごとの一般の入園者数を幅つきで見込みます。見込みからゲートと売店の人数の案と、売店の品目ごとの仕入の数の案を作り、担当者の確認に回します。
- 連携・自動化
- Python
- 対象業界
- その他/自治体
- 対象部門
- 経営企画
- 対象業務
- 集計・分析
- 主な課題
- 人手が足りない/判断に時間がかかる/属人化している
- AIで行う処理
- 予測
- 主な効果
- 判断支援/属人化解消/工数削減
- 導入難易度
- ★★★☆☆
- 実装レベル
- 本格構成
- 費用感
- 個別開発(大)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 水曜に、ゲートの仕組みから前年の同じ週と直近4週の日ごとの入園者数を書き出す
- 翌週の天気予報と、催し・動物の公開・夜間の開園の予定、団体の予約の台帳を確かめる
- 前年の数に天気と催しと団体の分を足し引きして、日ごとの入園者の見込みを決める
- 見込みと前年の時間ごとの入園の形から、開くゲートの数と、売店・駐車場の人数を時間帯ごとに決め、シフトの表を組む
- 毎日14時に、売店の責任者が翌日の天気予報を見直し、弁当・パンの数を決めて業者に伝える
- 週2回、アイスと飲み物の数を、その先の数日の天気予報と在庫から決めて発注する
- 当日、開門前の行列を見て、ゲートを足すか、売店の人をゲートに回す
- 自動毎週水曜の朝、ゲートの仕組みと売店のPOSから前日までの記録を書き出し、プログラムが読み込む
- 自動過去の入園の記録から、団体の券種の分を引いて、日ごとの一般の入園者数を作る
- 自動翌週の暦・催し・天気の見通しから、開園日ごとの一般の入園者数を真ん中と幅で見込み、団体の予約の数を足す
- 自動見込みと曜日の種類ごとの入園の時刻の形から、30分ごとの入園の数を作り、ゲート・売店・駐車場の人数の案を出す
- 自動品目ごとの販売の割合と、品目ごとに決めた幅の位置から、売店の仕入の数の案を出す
- 自動初めての催し、天気の大きな変わり目、団体の予約の多い日、幅の広い日に印を付ける
- 人運営課の担当が、印の付いた日の理由を見て、見込みと人数の案を直し、シフトを組む
- 【自動/人】 毎日13時に翌日分を作り直し、売店の責任者が仕入の数の案を確かめて業者に伝える
各工程の詳しい説明を読む
- 水曜に、ゲートの仕組みから前年の同じ週と直近4週の日ごとの入園者数を書き出す
- 翌週の天気予報と、催し・動物の公開・夜間の開園の予定、団体の予約の台帳を確かめる
- 前年の数に天気と催しと団体の分を足し引きして、日ごとの入園者の見込みを決める
- 見込みと前年の時間ごとの入園の形から、開くゲートの数と、売店・駐車場の人数を時間帯ごとに決め、シフトの表を組む
- 毎日14時に、売店の責任者が翌日の天気予報を見直し、弁当・パンの数を決めて業者に伝える
- 週2回、アイスと飲み物の数を、その先の数日の天気予報と在庫から決めて発注する
- 当日、開門前の行列を見て、ゲートを足すか、売店の人をゲートに回す
(a)団体と一般が混ざっている。 3番目の「前年の数」には、前年の同じ日に来た遠足の団体が含まれています。前年にたまたま遠足が3校来た日を基準にすると、今年は団体の予約が無いのに見込みが多めになります。 担当者は台帳を見て足し引きしていますが、前年の側の団体を引く作業までは手が回っていません。
(b)足し引きが人によって違う。 雨の土曜に何割減らすかが、担当者と売店の責任者で違います。理由が書かれていないので、外れても振り返れません。
(c)弁当が余る日と足りない日が出る。 多めに頼めば売れ残りを捨て、少なめに頼めば昼前に売り切れて、休憩所で「本日の弁当は終了しました」と貼り出す日があります。 土産の菓子のように翌日に回せる品目と、同じ考え方で数を決めていることも、余り方のむらの理由です。
(d)担当者が休めない。 見込みの作り方が頭の中にあるので、担当者が休む週は、前の週のシフトをほぼ写して済ませています。
- 【自動】 毎週水曜の朝、ゲートの仕組みと売店のPOSから前日までの記録を書き出し、プログラムが読み込む
- 【自動】 過去の入園の記録から、団体の券種の分を引いて、日ごとの一般の入園者数を作る
- 【自動】 翌週の暦・催し・天気の見通しから、開園日ごとの一般の入園者数を真ん中と幅で見込み、団体の予約の数を足す
- 【自動】 見込みと曜日の種類ごとの入園の時刻の形から、30分ごとの入園の数を作り、ゲート・売店・駐車場の人数の案を出す
- 【自動】 品目ごとの販売の割合と、品目ごとに決めた幅の位置から、売店の仕入の数の案を出す
- 【自動】 初めての催し、天気の大きな変わり目、団体の予約の多い日、幅の広い日に印を付ける
- 【人】 運営課の担当が、印の付いた日の理由を見て、見込みと人数の案を直し、シフトを組む
- 【自動/人】 毎日13時に翌日分を作り直し、売店の責任者が仕入の数の案を確かめて業者に伝える
7番目で、担当者は「足し引きを考える」代わりに「理由を確かめる」ことに時間を使います。 印の無い日は、人数の案を流し見てシフトに写します。
シフトの確定と仕入の発注を自動にしないのは、意図してのことです。 誰がその時間に入れるか、業者が作れる数や前日の売れ残りは、担当者と売店の責任者しか分かりません。
02今回想定するシステム構成
券売機・ゲートの仕組み(入園の時刻・券種・人数) 団体の予約の台帳/催し・動物の公開の予定表/売店のPOS(品目ごとの販売の数) 内閣府の祝日の表/過去の気象のデータ(気象庁のCSV)/天気の見通し │ ▼【トリガー】毎週水曜 8時(翌週分)、毎日13時(翌日分の作り直し) Python(pandas) ├──▶ 団体の券種の分を引き、一般の入園者数を作る ├──▶ 暦・催し・天気の項目を作る ▼ scikit-learn(HistGradientBoostingRegressor、loss="poisson" と loss="quantile") │ 開園日ごとの一般の入園者数(真ん中と、10・30・50・70・90の分位点) ▼ Python ── 団体の予約の数を足す、30分ごとの入園の数、人数の案、品目ごとの仕入の数の案、印付け ▼ 【運営課の担当と売店の責任者が理由を確かめ、シフトと仕入の数を決める】
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Python(pandas・scikit-learn) | R |
| 処理エンジン | scikit-learn の HistGradientBoostingRegressor(ポアソン損失と分位点損失) | LightGBM、Prophet(祝日の表と追加の項目を使う場合) |
| 集計 | Python(団体の分の加算、30分ごとの入園の数、人数と仕入の数の換算、印付け) | シフトの表の計算式 |
| データの取得元 | ゲートの仕組みと売店のPOSの書き出し、団体の予約の台帳、催しの予定表、祝日の表、気象のCSV | 受付の日報 |
| 結果の出力先 | 運営課の共有フォルダの見込みの表 | 担当者への通知 |
ゲートの仕組み、売店のPOS、団体の予約の台帳には、何も書き込みません。 前日までの記録を書き出してもらい、読むだけです。開園時間の変更や、入園の制限を、見込みから自動で掛ける作りにはしません。 それは園長と設置者の市が決めることです。
土台になるのは、scikit-learn の HistGradientBoostingRegressor です。 loss に poisson を選べ、その場合は目的の値が0以上である必要があります。 入園者数のような数える値に向いた損失です。loss="quantile" を選ぶとピンボール損失になり、quantile に0から1の値を渡して、分位点ごとの見込みを別々のモデルで作れます。 本記事では、真ん中をポアソン損失で、幅を10・30・50・70・90の5つの分位点で作ります。
欠けた値(NaN)をそのまま扱えるので、天気の見通しが届かなかった日も記録を捨てずに済みます。曜日の種類や催しの区分は、pandas の Categorical の型にしておけば、既定の categorical_features="from_dtype" で区分として扱われます。
祝日は、内閣府の「国民の祝日」の表を使います。 内閣府は、昭和30年(1955年)から令和9年(2027年)までの国民の祝日をCSVで公開しています。翌年分が載ったら差し替えます。
過去の天気は、気象庁の「過去の気象データ・ダウンロード」から取ります。 昨日までの気象観測のデータから、複数の地点の複数の項目を抽出でき、結果はCSVの形でダウンロードできます。 気象庁ホームページのコンテンツは公共データ利用規約(第1.0版)に準拠した利用条件で使え、利用するときは出典を記載し、編集・加工した場合はそのことも別に記載するよう求められています。
03どうやって実装するのか
処理の起点を決める
毎週水曜の8時、開門の前に動かします。 運営課の担当が水曜の午後に翌週のシフトを組む前に、翌週の見込みと人数の案ができている状態にします。
毎日13時に、翌日分だけ作り直します。 売店の責任者が14時に弁当・パンの数を業者に伝える前に、翌日の天気の見通しで作り直した仕入の数の案を出します。 業者に数を伝える期限は契約によって違うので、取引のある業者に確かめ、作り直しの時刻を期限の1時間前に合わせます。
アイスと飲み物は次の配送まで、土産の菓子は次の発注までの合計を、発注の日の作り直しでまとめて出します。
ゲートの仕組みの書き出しが届かない、または前の開園日の入園者が0のときは、動かしません。 書き出しの失敗を「入園者が0人の日」として学ばせないためです。担当者に知らせ、ゲートの仕組みの保守の会社に書き出しのやり直しを頼みます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 入園の記録 | 入園の時刻、券種(大人・中学生以下・65歳以上・年間パスポート・団体)、人数 | ゲートの仕組みの書き出し |
| 団体の予約 | 来園の予定日、学校・団体の種類、予定の人数、雨天の扱い(中止・延期・決行) | 団体の予約の台帳 |
| 催しの予定 | 動物の公開の始まり、ガイドの催し、夜間の開園、無料で開放する日、近くの行事 | 運営課の予定表 |
| 暦 | 祝日、年末年始、大型連休、近くの小中学校の長期休みと運動会の振替休日 | 内閣府の祝日の表と自社の暦の表 |
| 過去の天気 | 日ごとの降水量、最高気温・最低気温 | 気象庁の過去の気象データ・ダウンロード |
| 天気の見通し | 翌週の日ごとの天気・最高気温・降水の確率 | 契約している気象会社の配信、または担当者の入力 |
| 売店の販売の記録 | 品目ごと・日ごとの販売の数、売り切れの時刻、廃棄の数 | 売店のPOSと廃棄の記録 |
| 休園・止まり | 臨時の休園、獣舎の工事で見られない動物、駐車場の閉鎖 | 運営課の日報 |
質を決めるのは、団体の予約の台帳です。 過去の記録から団体の分を引くには、その日に実際に来た団体の人数が要ります。予約の人数と当日の人数がずれることは多いので、ゲートの団体の券種の数を正とし、台帳は予定の側だけに使います。
雨天の扱いの列も必ず持ちます。 遠足は雨で中止や延期になるので、雨の予報の日に予約の数をそのまま足すと、見込みが上にずれます。
売り切れの時刻と廃棄の数が、仕入の側の質を決めます。 販売の数だけを記録していると、昼前に売り切れた日の「本当は売れた数」が分かりません。 売り切れた日を印にして、学ばせる記録から外すか、売り切れの時刻から1日分を見積もる列を作ります。
データの取得方法を決める
ゲートの仕組みからは、前日までの入園の記録を、30分ごと・券種ごとの人数の形で毎日書き出す設定を作ります。1人ずつの記録ではなく、30分ごとの人数の集計で受け取ります。 年間パスポートの番号や氏名は書き出しません。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 30分ごと・券種ごとの入園の数 | ゲートの仕組みの書き出し | 一般の入園者数、入園の時刻の形 |
| 実際に来た団体の数 | ゲートの団体の券種 | 過去の記録から団体の分を引く |
| 予約の団体の数と雨天の扱い | 団体の予約の台帳 | 翌週の団体の分の加算 |
| 催し・休園の日 | 運営課の予定表と日報 | 催しの項目、外す日の印 |
| 祝日 | 内閣府のCSV | 暦の項目 |
| 過去の天気 | 気象庁のCSV | 天気の項目(過去) |
| 天気の見通し | 気象会社の配信か担当者の入力 | 天気の項目(翌週・翌日) |
| 品目ごとの販売・売り切れ・廃棄 | 売店のPOSと廃棄の記録 | 品目ごとの販売の割合 |
過去の天気は、最初に3年分をまとめて取り、その後は毎週1週間分を足します。 地点は、園にいちばん近いアメダスの地点にします。見込みの資料には「出典:気象庁ホームページ」と、加工したことを書いておきます。
天気の見通しを担当者の入力で済ませる場合は、「晴れ・曇り・雨・雪」の4つと、最高気温と降水の確率の数字だけを入れてもらいます。 自由な文で書くと、プログラムが読めません。
AIへ渡す前に整形する
- 団体の分を引く … 日ごとに、ゲートの団体の券種の数を入園者数から引き、一般の入園者数を作ります
- 異常の日を外す … 臨時の休園、台風で早く閉めた日、ゲートの機械の止まりの日を印にします
- 催しの種類をそろえる … 予定表の自由な書き方を、「動物の公開の始まり」「ガイドの催し」「夜間の開園」「無料の日」「近くの行事」の5つの区分にそろえます
- 公開の始まりからの日数を作る … 動物の赤ちゃんの公開は、始まりの週に強く効き、その後に薄れていきます。始まりからの日数を項目にします
- 項目を作る … 曜日、祝日、連休の何日目か、年末年始、学校の長期休み、催しの区分、降水量、最高気温、前年の同じ週の一般の入園者数
- 入園の時刻の形を作る … 曜日の種類と天気の区分ごとに、直近12週の30分ごとの入園の割合を作ります
- 品目ごとの販売の割合を作る … 品目ごとに、一般と団体を合わせた入園者100人あたりの販売の数を、最高気温の帯と曜日の種類で出します。売り切れの日は外します
1番目を省かないでください。 第3章の(a)のとおり、団体を含めたまま学ばせると、団体の多い季節の平日に、一般の客が多い日だとモデルが覚えます。 引いた後の一般の入園者数を学ばせ、翌週の見込みに団体の予約の数を足します。7番目で最高気温の帯を使うのは、アイスと飲み物の売れ方が気温で大きく変わるからです。
AIに処理させる
させるのは、「開園日ごとの一般の入園者数」を、真ん中と5つの分位点で見込むことだけです。 団体の加算、30分ごとの入園の数、人数の案、仕入の数の案、印付けは、決まった計算で行います。
| 見込むもの | 使うもの | 判断できないときの扱い |
|---|---|---|
| 開園日ごとの一般の入園者数(真ん中) | 過去の一般の入園者数、曜日、祝日、連休、学校の休み、催しの区分、公開の始まりからの日数、天気、前年の同じ週 | 催しの区分が初めてなら new_event |
| 同(10・30・50・70・90の分位点) | 同上 | 90と10の差が真ん中の6割を超えたら wide |
| 団体の分 | 予約の人数 × 団体の種類ごとの雨の日に来た割合(決まった計算) | 予約の人数が多い日は group |
| 品目ごとの仕入の数 | 入園者数の分位点 × 品目ごとの販売の割合(決まった計算) | 販売の割合が前月から大きく動いたら mix_shift |
分位点を5つも作るのは、品目ごとに使う位置が違うからです。 売り切れたときの損を「売れたはずの利益」、売れ残ったときの損を「仕入の値段から戻る分を引いた額」とすると、仕入の数は、売り切れの損 ÷(売り切れの損 + 売れ残りの損)の分位点に置くのが筋です。 売店の責任者が品目ごとに2つの損を表に書けば、使う分位点が決まります。
| 品目の型 | 売れ残りの扱い | 使う分位点の目安の考え方 |
|---|---|---|
| 弁当・パン | 当日に捨てる | 売れ残りの損が大きいので、真ん中かそれより下 |
| アイス・飲み物 | 在庫として持てる | 売れ残りの損が小さいので、上側 |
| 土産の菓子 | 賞味期限まで持てる | 次の発注までの合計の上側。期限の近い在庫を先に数える |
| させないこと | 理由 | |
| :-- | :-- | |
| シフトの確定と、誰を入れるかの決定 | 働く人の都合と慣れは担当者が見る | |
| 仕入の発注そのもの | 業者の作れる数と前日の在庫を売店の責任者が見る | |
| 休園・開園時間の変更、入園の制限 | 来園者への約束で、園長と設置者が決める | |
| 動物の公開の可否と時間 | 動物の体調で飼育の担当と獣医が決める | |
| 天気の見通しの補正 | 見通しをそのまま使い、勝手に足し引きしない |
4行目を必ず守ってください。 入園者が多い見込みの日でも、赤ちゃんの公開の時間を延ばす判断に、見込みを使ってはいけません。
指示内容を固定する
この構成は生成AIを使わないので、プロンプトの代わりに、モデルの設定と計算の規則を書いておきます。
【モデル(一般の入園者数。団体の券種の分を引いた値を学ばせる)】
- scikit-learn の HistGradientBoostingRegressor
・真ん中 … loss="poisson"
・分位点 0.1〜0.9 … loss="quantile", quantile=0.1 / 0.3 / 0.5 / 0.7 / 0.9(5つのモデル)
・曜日の種類、催しの区分、天気の区分は pandas の Categorical にする
- 学ばせる記録 = 過去3年の開園日。臨時の休園・早い閉園・ゲートの止まりの日は外す
- 確かめ方 = TimeSeriesSplit(n_splits=4, test_size=56, gap=7)
・未来の記録で学ばせて過去を確かめることを防ぐ
・gap=7 は、水曜に翌週を見込むときに直近の1週の記録がまだ無いことに合わせる
- 学ばせ直しは月に1回
【団体の分】
- 団体の分 = Σ(予約の人数 × 団体の種類ごとの来園の割合)
- 来園の割合は、天気の見通しが雨なら「雨の日に来た割合」、それ以外は「晴れ・曇りの日に来た割合」
- 雨天の扱いが「中止」の団体は、雨の見通しなら0にする
【人数の案(配置の決まりの表から)】
- ゲート = 30分ごとの入園の数(一般の分位点0.9 + 団体の分)÷ ゲート1か所がさばける数(切り上げ)
- 売店 = 時間帯ごとの入園の数の真ん中 × 売店に寄る割合 ÷ レジ1人がさばける数(切り上げ)、最少1人
- 駐車場 = 開門から2時間の入園の数の分位点0.9 × 車で来る割合 ÷ 誘導1人が受け持つ台数(切り上げ)
- さばける数・寄る割合・車で来る割合は、担当者が決めて表に置く
【仕入の数の案】
- 品目ごとの使う分位点 = 売り切れの損 ÷(売り切れの損 + 売れ残りの損)に近い分位点
- 仕入の数 = (一般の入園者数の分位点 + 団体の分)÷ 100 × 気温の帯の販売の割合 - 持ち越せる在庫
- 何日分をまとめて出すかは、品目の表(弁当・パン=1日、アイス・飲み物=次の配送まで、菓子=次の発注まで)
【印を付ける条件】
- new_event … 催しの区分が初めて、または前回から1年以上空いた
- wide … 分位点0.9と0.1の差が、真ん中の6割を超える
- group … 団体の分が一般の真ん中の5割を超える
- weather … 翌日の見通しの最高気温が水曜の時点から5度以上違う、または雨・雪に変わった
- mix_shift … 品目の販売の割合が前月の同じ気温の帯から2割以上動いた
- 印の無い日は、人数と仕入の数の案をそのままシフトと発注の表の下書きに載せる
gap=7 を置くのは、使うときの条件で確かめるためです。 水曜に翌週を見込むときは見込む週との間に空きがあり、空きを置かずに確かめると、当たり方を良く見積もります。
ゲートに上側の分位点を使うのは、開門直後の行列がいちばん困るからです。 真ん中で人を置くと、10日に1日の混む日にゲートが足りません。さばける数と寄る割合は季節で変わるので、プログラムに書き込まず表に置きます。
出力形式を固定する
開園日ごとに、次の形のJSONを作り、表にしてシフトの表と発注の表の横に載せます。
{
"date": "",
"day_type": "weekday | saturday | holiday | long_holiday",
"events": [""],
"weather_input": { "sky": "", "tmax": 0, "pop": 0, "issued_at": "" },
"general": { "mean": 0, "q10": 0, "q30": 0, "q50": 0, "q70": 0, "q90": 0, "last_year_same_week": 0 },
"group": { "reserved": 0, "expected": 0, "rain_cancel": 0 },
"arrivals": [ { "time": "09:30", "q50": 0, "q90": 0 } ],
"staff_draft": [ { "time": "09:30", "gate": 0, "shop": 0, "parking": 0 } ],
"purchase_draft": [ { "item": "", "quantile_used": 0.5, "qty": 0, "carry_over": 0 } ],
"flags": ["new_event | wide | group | weather | mix_shift"],
"model_version": "",
"override": { "staff": null, "purchase": null, "by": "", "reason": "" }
}
1つ目の理由は、general と group を分けて残せることです。 外れたときに、一般の客の見込みが外れたのか、団体の予約が当日に変わったのかを分けられます。団体の外れは台帳の雨天の扱いを直す話で、モデルを直す話ではありません。
2つ目は、purchase_draft に quantile_used を残すことです。 どの分位点で数を出したかが分かれば、売れ残りが続いたときに、品目の損の表を直すべきか、見込みが外れているのかを分けられます。 同じ弁当でも、使う位置を変えれば数は変わります。
3つ目は、override で人の直しと理由が残り、次の同じ催しのときの材料になることです。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| ゲートの仕組み | 毎日の書き出しの受け取り | 30分ごと・券種ごとの入園の数 |
| 団体の予約の台帳 | 表の読み込み | 予定日、団体の種類、予定の人数、雨天の扱い |
| 売店のPOS | 毎日の書き出しの受け取り | 品目ごとの販売の数と売り切れの時刻 |
| 運営課の予定表 | 表の読み込み | 催し・動物の公開・休園の日 |
| 内閣府の祝日の表・気象庁のCSV | ファイルの読み込み | 祝日、過去の天気 |
| 見込みの表 | 共有フォルダへの書き出し | 見込み、人数の案、仕入の数の案、印 |
| 担当者への通知 | 庁内・社内の連絡の場 | 印の付いた日と、翌日分の作り直しの差 |
シフトの表と発注の表へは、書き込みません。 案は見込みの表に並べ、担当者がシフトの表に、売店の責任者が業者への連絡に、自分で写します。 業者に送る数を自動で送る作りにすると、前日の在庫を見ずに数が飛びます。
通知には、入園者数そのものを流しません。 流すのは「印の付いた日」と「見込みの表の場所」だけにします。入園者の数は、設置者への報告に使う数字でもあるからです。
人が確認する
担当者が見るのは、毎週の人数の案と、印の付いた日の理由です。 印の無い日は、人数の案を流し見てシフトに写します。全日を前の方法で足し引きし直す運用にすると、第10章の5.0時間には収まりません。
groupを先に見る … 団体の予約の多い日です。雨の見通しなら、学校に延期の連絡が来ていないかを台帳で確かめますnew_eventを見る … 初めての催しや公開の始まりの日です。担当者の見立てを並べ、どちらで組むかを決めますwideとweatherを見る … 見込みの幅が広い日と天気の変わり目です。ゲートを上側で組み、売店は品目の表のとおりにするかを決めます- 直したら理由を書く …
overrideに値と理由と直した人を残します
売店の責任者が見るのは、毎日13時の仕入の数の案です。 前日の売れ残りと、業者が作れる数を見て数を決めます。mix_shift が付いた品目は、売れ方が変わった理由(値段を変えた、新しい商品を置いた)を確かめてから数を決めます。
2番目で、見込みより担当者の見立てを採る日があって構いません。 見込みは、初めて公開する動物の人気を知りません。
例外に対処する
| 起きること | 対応 |
|---|---|
| ゲートの書き出しが届かない、前の開園日の入園が0 | 見込みを出さず、担当者に知らせる |
| 台風・大雪の予報 | 見込みを参考にとどめる。休園・早い閉園の判断は園長が行う |
| 臨時の休園・早い閉園 | その日を学ばせる記録から外し、翌週の見込みに印を付ける |
| 動物の体調で公開が取りやめになった | 公開の項目を外して作り直し、差を担当者に知らせる |
| テレビ・SNSで紹介された | 紹介の日の印を付け、翌週から2週間は担当者の見立てを並べる |
| 団体の予約が当日に取り消された | 台帳の取り消しを読み、団体の分を作り直す。雨の日の割合の記録に残す |
| 売店の品目が売り切れた | 売り切れの日として印を付け、その日の販売の数を学ばせる記録から外す |
| 天気の見通しが届かない | 平年並みの天気で見込み、weather を付けて担当者に確かめてもらう |
上から5行目の紹介の直後は、記録の傾向が当てはまりません。 この期間は見込みをゲートの人数の下限として使い、上側の判断は担当者に任せます。
7行目を忘れると、売り切れた日を「その数で足りた日」と覚え、仕入が減っていきます。
記録を残す
- 読み込んだ入園の記録の件数と、団体の券種の分を引いた後の一般の入園者数
- 開園日ごとの見込み(真ん中と5つの分位点)と、そのとき使った天気の見通し
- 団体の予約の数と、雨の日の割合で見込んだ団体の分
- 人数の案、品目ごとの仕入の数の案と使った分位点、印
- 担当者と売店の責任者が直した値と理由(
override) - 実際の一般の入園者数・団体の数、品目ごとの販売・売り切れの時刻・廃棄の数
- モデルの版、学ばせた期間、配置の決まりの表と品目の損の表の値
6つ目の廃棄と売り切れは、毎週品目ごとに数えます。 廃棄が続くなら使う分位点を下げ、売り切れが続くなら上げます。
04実装レベルの3段階
最小構成は、確かめるための段階です。 毎週の見込みの手間は減りません。 半自動化で、前年の数を書き出して足し引きを決める時間はほぼ無くなります。 ただし、人数と仕入の数への換算は手で残ります。本格構成で、担当者が見るのは人数の案と印の付いた日だけ、売店の責任者が見るのは仕入の数の案だけになり、この段階が本記事の想定です。 差が大きいのは、品目ごとの仕入の数を決める作業が、毎日の手作業だからです。 段階を飛ばさないでください。 半自動化の見込みを春の連休と夏休みまで並べ、外れやすい天気と催しの型を見てから本格構成に進むほうが、印の空振りが減ります。
05工数削減シミュレーション
導入後 25件 × 12分 ÷ 60 = 5 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 年間の入園者が数十万人規模の動物園・水族館・植物園で、券売機やゲートから入園の時刻と券種を書き出せる施設。翌週のゲートと売店のアルバイトの人数と、売店の弁当・パン・アイスの仕入の数を、担当者が前年の同じ日と天気予報を見た勘で決めていて、雨の週末に売れ残りが出たり、晴れた連休に売り切れたりしている場合。遠足や社会見学の団体の予約を台帳で受けている施設では、団体の分を分けて見込める。公営の施設を指定管理者が運営している場合にも使える。
- 入園者が1日数百人に満たず、担当者がその日の様子を見て足りる場合。入園の記録が日ごとの合計しか残っておらず、券種や時刻が分からない場合。開園から1年未満で、季節を一巡した記録が無い施設。なお、休園・開園時間の変更の判断、動物の公開の可否、シフトの確定と仕入の発注そのものは、この構成では代替できません。
07最小構成で試す方法
- ゲートの仕組みから、過去1年の日ごとの入園者数を券種ごとに書き出す
- 表計算で、団体の券種の数を引いた一般の入園者数の列を作る
- 気象庁の過去の気象データ・ダウンロードから、同じ期間の降水量と最高気温をCSVで取り、一般の入園者数と並べる
- 曜日の種類と天気(雨か、雨でないか)で一般の入園者数の平均を出し、催しの日に色を付ける
- 売店のPOSから、弁当とアイスの日ごとの販売の数を取り、入園者100人あたりの数を最高気温の帯で並べる
2番目を、必ず作ってください。 団体を引く前と後で5月と10月の平日の数がどれだけ変わるかで、いまの見込みが団体の多い日を基準にしていないかを確かめられます。
| 出てきた内容 | 判断 |
|---|---|
| 天気と催しで一般の入園者数がはっきり動き、アイスの販売が気温の帯で分かれる | Python で HistGradientBoostingRegressor の見込みに進む |
| 団体の券種の数がゲートで分けて記録されていない | ゲートでの団体の数え方を直すのが先 |
| 売り切れの日が多く、販売の数が仕入の数に張り付いている | 売り切れの時刻の記録から始める |
2行目と3行目が出ることは珍しくありません。 失敗ではなく、見込みが外れていた理由が1つ分かったということです。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 団体を含めたまま学ばせ、団体の多い季節の平日が多めに出る | 団体の券種の分を引き、一般の入園者数を学ばせる |
| 雨の日の遠足の予約をそのまま足す | 団体の種類ごとの雨の日の来園の割合を掛ける |
| 売り切れの日の販売の数を学ばせ、仕入が減っていく | 売り切れの日を印にして外す |
| 弁当も土産の菓子も同じ見込みで数を出す | 品目ごとに売り切れと売れ残りの損から使う分位点を決める |
| 書き出しの失敗を入園者0人の日として学ばせる | 0の日は動かさず、書き出しを確かめる |
| 普通の交差検証で確かめ、幅を狭く見積もる | TimeSeriesSplit に gap を置き、使うときの条件で確かめる |
| 公開の始まりの効き目が薄れていくことを入れない | 始まりからの日数を項目にする |
| 見込みが多い日に動物の公開の時間を延ばす | 延ばさない。 公開の可否は動物の体調で決める |
| 祝日の表の翌年分を入れ忘れる | 年に1回、内閣府のCSVを差し替える |
上の2行が、この構成の外れのほとんどです。 モデルを凝らすより、ゲートでの団体の数え方と台帳の雨天の扱いをそろえるほうが効きます。
下から2行目は、外れではなく使い方の失敗です。 見込みはゲートと売店の人数と仕入のためのもので、動物の扱いの判断には使わないと、飼育の担当と最初から決めておいてください。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 30分ごと・券種ごとの入園の数、団体の予約(学校名と人数)、催しの予定、天気、品目ごとの販売の数、シフトの人数です。年間パスポートの番号や氏名は書き出しませんが、団体の予約の台帳には学校名と引率の先生の連絡先が入っています。
- 年間パスポートの番号・氏名を書き出さない … ゲートの書き出しは、30分ごと・券種ごとの人数の集計だけにします。1人ずつの入園の記録を受け取りません
- 団体の予約は、必要な列だけを読む … 予定日、団体の種類、予定の人数、雨天の扱いだけを読み、学校名・連絡先の列は読み込みません
- 見られる人を絞る … 見込みの表と元の記録は、運営課の担当と売店の責任者に限り、外部の生成AIのサービスにも貼り付けません
- 気象庁のデータの利用の条件を守る … 出典を記載し、加工したことを書き、国が作ったかのように見せない
- 指定管理の協定と設置者への報告の決まりを守る … 入園者の数は設置者への報告の数字です。見込みの数を、実績の数と取り違えて報告に載せないよう、表の列を分けます
- 安全と動物の判断に見込みを使わない … 休園、入園の制限、動物の公開は、園長と飼育の担当が決めます
誤りが起きた場合のリスクは、混む日を少なく見込んでゲートと売店の人と商品が足りなくなることと、空く日を多く見込んで人を余らせ弁当を捨てることの2つです。 前者は真ん中だけで人を置くと起き、後者は団体を含めて学ばせると起きます。前者は開門直後の行列と熱中症の危険に関わるので、ゲートは上側で置きます。
10まず何から始めるか
1週目:催しと公開と休園の一覧を作る
過去3年の催し(動物の公開の始まり・ガイドの催し・夜間の開園・無料の日・近くの行事)と、臨時の休園・早い閉園の日を、日付と区分の一覧にします。この一覧が無いと、どのモデルも普通の日と催しの日を分けられません。
2週目:団体を引いた一般の入園者数を作る
第8章の手順で1年分の一般の入園者数を作り、あわせて団体の種類ごとに雨の日に実際に来た割合を数えます。
3週目:配置の決まりと品目の損の表を決める
担当者と一緒に、ゲート1か所がさばける数と売店に寄る割合を、売店の責任者と一緒に、品目ごとの売り切れの損と売れ残りの損を決めて表にします。ここが決まらないと、人数と仕入の数の案が出せません。
4週目:Python で翌週の見込みを出す
一般の入園者数を真ん中と5つの分位点で見込み、団体の分を足すところまで組みます。この時点では、前年の同じ週との比べだけを担当者に見せます。
2か月目以降: 人数の案、品目ごとの仕入の数の案、印付け、毎日の作り直しを足します。見込みと実際の入園者数、品目ごとの廃棄と売り切れを毎週並べて外れ方を数え、 1件36分が何分になったかを実測します。担当者が休む週も、売店の責任者が見込みの表と印を見てシフトを組めるようになった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
loss に poisson・quantile を選べ、poisson は目的の値が0以上である必要があること。quantile はピンボール損失で、quantile に0から1の値を指定すること。欠けた値(NaN)をそのまま扱えること。categorical_features の既定が from_dtype で、Categorical の型の列が区分として扱われること | scikit-learn: HistGradientBoostingRegressor | 2026-10-27 |
時系列の順に並んだ記録を、未来で学ばせて過去で確かめないように分けること。n_splits・test_size・gap(学ばせる記録の末尾から除く数)を指定できること | scikit-learn: TimeSeriesSplit | 2026-10-27 |
| 昨日までの気象観測のデータから、複数の地点の複数の項目を抽出でき、結果をCSVの形でダウンロードできること | 気象庁: 過去の気象データ・ダウンロード(使い方) | 2026-10-27 |
| 気象庁ホームページのコンテンツが公共データ利用規約(第1.0版)に準拠した利用条件で使えること。出典の記載、編集・加工した場合の記載、国が作成したかのような態様で公表・利用してはならないこと | 気象庁: ホームページについて(利用規約) | 2026-10-27 |
| 昭和30年(1955年)から令和9年(2027年)までの国民の祝日がCSV形式で公開されていること | 内閣府: 国民の祝日について | 2026-10-27 |
配置の決まり(さばける数・寄る割合)と、品目ごとの売り切れの損と売れ残りの損は、各施設の運営の担当と売店の責任者で決めてください。休園・入園の制限・動物の公開の判断は、園長・飼育の担当と設置者の決まりに従ってください。 本記事は上記の公開資料で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-2066)についてのご相談はこちらから。
