TECHNICAL REPORT — 配車最適化の設計

定期巡回型回収業務における配車設計

最適化・予測・転移という三つの問題への分解と、それぞれに対応する道具の選択

概要

定期巡回型の回収業務における配車設計を、三つの問題への分解として論じる。I. 最適化問題——何日おきに、どの順で回るか。II. 予測問題——いま各拠点にどれだけ溜まっているか。III. 転移問題——まったく別の地域に持ち出しても機能するか。三者は目的も道具も評価基準も異なり、混同すると設計を誤る。

主要な主張は次のとおりである。訪問頻度は予測問題ではなく在庫補充問題であり、基準間隔は蓄積速度から閉形式で定まる。気象と暦はその基準を歪めるのではなく、実効日数として時計の進み方を変える。目的関数の重みは設計するものではなく、熟練者の実走順を教師信号として実績から較正する。そして道具は問題の構造から選ぶ——本稿に現れる六つの最適化問題のうち、ブラックボックス最適化が正当化されるのは一つだけであり、残りは閉形式・最尤推定・混合整数計画・階層ベイズの領分である。

第III部の転移問題を独立に立てるのは、それが他の二つの検証方法を変えるからである。ここでいうマップとは一つの営業地域であり、問うのは既存地域への適合ではなく新規地域への転移である。所要時間は外部地図から任意の拠点対について得られるため、実績が担うのは絶対値ではなく残差の学習になる。新規拠点の蓄積速度は識別子ではなく属性から予測する。そして生成器で日次インスタンスを供給すれば方策そのものを学習でき、その価値は事例数ではなくマップ空間の被覆にある。この目的を採る以上、検証は日ではなく地域を丸ごと保留して行わなければならない。

1問題設定と三つの問題

対象とする業務は、多数の顧客拠点を定期的に巡回し、資源物を回収して処理施設へ運搬する事業である。規模は、稼働拠点が数百、車両が十台弱、巡回コースが曜日×地区の組み合わせで数十本という水準にある。この規模は、大手物流事業者向けの配送計画システムを導入するには小さく、しかし人手の勘だけで最適性を担保するには大きい、という中間帯にある。

計画は月次で更新される表計算ファイルとして存在する。地区ブロックと曜日の組で識別されるコースがあり、各コースに回収拠点が順序付きで列挙される。この表が唯一の計画表現であり、実績は長らく紙の伝票としてのみ残っていた。

1.1検討に用いるモデルケース

以降の議論は、次のパラメータを持つモデルケースを前提に進める。実在の事業を記述したものではなく、各手法の適否が規模のどこで切り替わるかを見るための、統制された設定である。数値は単一営業所として運用しうる規模の上限側に置いてある——本節冒頭で描いた車両十台前後の事業の、およそ倍にあたる。下限側ではなく上限側を採るのは、標本量に依存する手法(階層ベイズ、方策学習)がどこで成立し始めるかを見るのが目的だからである。これより小さい規模では成立しない手法があることは、その都度明示する。

記号設定値根拠
K車両・乗務員20単一営業所で管理しうる規模の上限付近
n稼働拠点約 103乗務員1名あたり50拠点前後
D蓄積期間の稼働日数約 9×102(3年・週6日)季節を3巡し、暦要因が識別可能になる長さ
M1乗務員・1日の訪問数15〜20作業時間と移動時間から定まる実務的な上限
R回収実績レコード数約 3×105K·D·M による
k拠点あたり観測数約 3×102R/n による
g訪問間隔1〜7日拠点ごと・訪問ごとに変動する

この設定を選ぶ理由は二つある。第一に、k ≈ 300 は拠点別の係数が識別可能になる水準であり(7.3)、統計モデルの選択肢が最も広がる点にあたる。第二に、D が3年に及ぶことで気象と季節の交絡が解ける。これより小さい規模では、本稿の後半で論じる手法の多くが標本の制約で成立しない。逆にこれより大きい規模では、単一営業所の配車という問題設定自体が複数拠点の階層問題に変わる。

なお、入力は専用のアプリケーションを通じて行われ、マスタは正規化されているものとする(第2節)。

1.2設計を規定する三つの性質

この問題群には、設計を規定する三つの性質がある。いずれも仕様書やコードからは導けず、実績を集計して初めて可視化される種類のものである。本節ではこれらを一般的な性質として述べ、以降の節はこの三点を前提に構成される。

性質1 — 訪問先は計画どおり、訪問順序は計画と乖離する。 計画表に列挙された拠点はほぼ確実に消化される。一方、実際に回る順序は計画表の記載順と体系的にずれる。両者の順位相関を曜日ごとに測ると、ほぼ一致する曜日と、ほぼ逆順に回る曜日とが同居しうる。すなわち計画表は「回る場所の集合」としては正確だが、「回る順序」としては形骸化している。順序は各乗務員の経験として保持されており、そこには渋滞傾向・搬入口の開放時刻・積載の積み下ろし順といった、表に書かれていない知識が織り込まれている。

性質2 — 担当の交代が日常的に発生する。 計画表の担当欄に記載のない乗務員が恒常的に稼働し、担当コースを相互に代走することも珍しくない。人員配置は月次の計画表より速く変動するため、計画表の担当欄は、実績を突合するための鍵として信頼できない

性質3 — 実績にコース識別子が残らないと、計画と実績を突合できない。 入力画面でドライバーがコースを選択していても、その選択値が実績レコードに保存されていなければ、後から曜日と担当者で推定するほかない。性質2により代走が常態である以上この推定は破綻し、実績の相当部分がコースに紐づけ不能となる。

設計上の含意

性質1は、最適化の目的関数を設計する上で最も重要な手がかりである。熟練ドライバーの実走順は、我々が明示的には知らない目的関数の(局所)最適解とみなせる。したがって計画表の記載順を最適化の制約として与えてはならない。むしろ逆に、実走順を「正解ラベル」として扱い、そこから目的関数を推定する方向に設計を反転させるべきである。第5節はこの反転を具体化する。

1.3三つの問題

本稿は配車の設計を三つの問題に分解する。三者は目的も道具も評価基準も異なり、混同すると設計を誤る。以降の構成はこの分解に従う。

I. 最適化問題
ルート・頻度設計
II. 予測問題
在庫推論
III. 転移問題
未知のマップへの適応
問い何日おきに、どの順で回るかいま各拠点にどれだけ溜まっているかまったく別の地域に持ち出しても機能するか
出力間隔 Ti*、曜日パターン、巡回路蓄積量の分布(λiσiβマップ不変な入力だけで動く関数と、多様なマップで学習した方策
道具閉形式・混合整数計画・ブラックボックス最適化最尤推定・階層ベイズ不変表現と正規化、外部地図+残差学習、マップの生成器と方策学習
評価目的関数値と制約充足ベースラインに対する予測精度保留した地域での性能
誤りの現れ方実行不能解。即座に現れる系統的な偏り。溢れとして遅れて現れる既存地域では良好、新規地域で破綻

接続は直列である。予測が供給する蓄積量の分布を、最適化がそのまま消費する。そして転移問題は、その両者を経験していない土地へ持ち出せるかを問う——外部の地図から任意の拠点対の所要時間が得られる以上、走行実績の欠如は障害ではなく、実績が担うのは一般的な所要時間と自社の実所要時間との残差の学習である。同様に、新規拠点の蓄積速度は識別子ではなく属性から予測する。

第三の問題を独立に立てる理由は、それが他の二つの検証方法を変えるからである。既存の運用への当てはまりを測るなら日で分割すれば足りるが、新規地域への転移を測るなら地域を丸ごと保留して分割しなければならない——日分割では同じ拠点・同じ区間が訓練側と検証側の双方に現れ、測っているのは記憶であって一般化ではない。この違いは第14節で改めて扱う。

2データモデル — 計画・実績・派生の三層

配車最適化の文脈でデータモデルを設計する際、最も陥りやすい誤りは、計画テーブルに実績を上書きしてしまうことである。「予定どおりに回れたか」を後から問えなくなり、第1節で述べた性質1のような知見は永久に得られない。計画と実績は別テーブルとして保持し、両者を突合する第三の層——派生テーブル——を明示的に置く。

マスタ層

customers取引先
locations回収拠点。座標・稼働曜日・作業可能時間帯・口数・単価
vehicles車両。積載量・燃料種別
drivers乗務員
items品目。単位・単位あたり重量

計画層

coursesコース。地区・曜日・担当・車両・適用月
course_stopsコース内の訪問順序と拠点。備考の原文

実績層

collections回収実績。作業日・拠点・品目・数量・時刻・位置・コース番号
work_sessions日次ヘッダ。出発/帰着時刻・走行距離計・天候
position_pings走行中の位置ログ(任意)

派生層(実績から生成)

travel_times拠点間所要時間の分位点。曜日・時間帯別
service_times拠点別の作業時間分布
demand_stats拠点×曜日×品目の発生量分布
location_constraints時間枠・作業条件などの構造化制約。入力時に構造化して保持する(10.1)
図1三層+派生層のデータモデル。実線枠は入力によって直接書き込まれるテーブル、破線枠は実績から定期バッチで再生成される派生テーブル。最適化ソルバが直接参照するのは主に派生層であり、マスタ層と実績層を直接読むことはない。

2.1実績テーブルの設計要件

実績テーブルは最も慎重に設計されなければならない。理由は単純で、記録されなかったデータは後から復元できないからである。機能は後から追加できるが、欠測は取り返しがつかない。最低限、以下の列を初期段階から持つべきである。

course_no
その作業がどのコースの遂行として行われたか。性質3が示すとおり、これが無いと代走日の突合が不可能になる。入力画面でコースを選択させているなら、その値を必ず実績側にも保存する。
work_start_time / work_end_time
作業の開始・終了時刻。連続する実績の時刻差から拠点間所要時間を導出するため、これが所要時間行列の唯一の情報源となる。端末入力での記録率は9割を超えうる項目であり、運用が定着すれば所要時間の推定に足る精度が得られる。
lat / lng / gps_accuracy
送信時点の測位結果。「回収したその場で送信する」という運用ルールを定めれば、この値は実質的に拠点座標そのものとなり、別途のジオコーディングが不要になる。技術的な補正機構を作るより、運用ルールを一行定める方が確実である。
item_id / quantity
品目を分けて記録する。品目マスタが貧弱だと、現場は複数品目の内訳を備考欄の自由記述に書き込むようになり、数量が集計に乗らなくなる。これは品目マスタの不足が必ず引き起こす帰結である。
is_spot
定期回収か臨時(スポット)回収かの区別。事後に判別する手段がないため、記録しなかった期間の区別は永久に失われる。請求にも配車分析にも影響する。

2.2計画層の版管理

計画表は月次で更新される。取り込みのたびに計画テーブルを全削除・再作成する実装は簡明だが、翌月分を取り込んだ瞬間に前月の計画が消える。計画対実績の比較を月をまたいで行えなくなり、コース改定の効果測定も不可能になる。主キーを(適用月, コース番号)とし、履歴を保持すべきである。

2.3派生層 — 所要時間行列

派生層の中核は拠点間所要時間である。同一ドライバー・同一日の連続する実績レコードの時刻差から算出する。

-- 連続する実績から区間所要時間を集計する
WITH seq AS (
  SELECT work_date, driver_id, location_id, work_end_time,
         LAG(location_id)   OVER w AS prev_location_id,
         LAG(work_end_time)  OVER w AS prev_end_time
  FROM collections
  WHERE source = 'field_input'
  WINDOW w AS (PARTITION BY work_date, driver_id ORDER BY work_end_time)
)
SELECT prev_location_id AS from_id, location_id AS to_id,
       strftime('%w', work_date)          AS weekday,
       COUNT(*)                          AS n_samples,
       MEDIAN(elapsed_min)              AS p50_min,
       MAX(elapsed_min)                 AS p_max_min
FROM seq
WHERE prev_location_id IS NOT NULL
  AND elapsed_min BETWEEN 1 AND 90   -- 休憩・給油等の外れ値を除外
GROUP BY 1, 2, 3;
図2実績から所要時間行列を生成する集計。区間の所要時間には移動と作業の両方が含まれる点に注意が必要で、作業時間を分離したい場合は開始時刻と終了時刻の差を別途 service_times として集計する。

この行列は疎である。実績が埋めるのは既存コースが通る区間だけであり、拠点数を n とすれば要素数 n(n−1) のごく一部にとどまる。しかしこれは決定的な制約ではない。任意の拠点対の所要時間は地図サービスの経路探索から得られるため、行列そのものは埋められる。実績が担うのは絶対値の推定ではなく、地図サービスの一般的な所要時間と自社の実際の所要時間との残差——搬入経路、荷扱い、当該拠点固有の事情——の学習である。強い事前分布の上の補正であるため、必要な標本は絶対値を推定する場合より桁で少ない。詳細は8.2、残差の未検証性の扱いは第14節で述べる。

第I部

最適化問題 — ルートと頻度の設計

何日おきに、どの順で回るか。本部の各節は、蓄積速度と所要時間が与えられたものとして扱う。それらをどう得るかは第II部・第III部が担う。

3定式化

対象は、時間枠付き容量制約配送計画問題(VRPTW)の変種である。標準的な定式化に、本業務に固有の項を加える。

ノード集合を V = {0} ∪ N とする。0 は車庫、N は当日訪問すべき拠点集合である。車両集合を K、決定変数を xijk ∈ {0,1}(車両 k が拠点 i から j へ移動するとき1)とする。各拠点 i には時間枠 [ei, li]、作業時間 si、発生量 qi が与えられ、各車両 k には積載上限 Qk が与えられる。

最小化
  w1·(総移動時間)  +  w2·(総走行距離)
 +  w3·Σi∈N max(0, aili)   時間枠超過
 +  w4·Σk∈K max(0, LkQk)   積載超過
 +  w5·(車両間の総作業時間の分散)   負荷平準化
 +  w6·Σk∈K d(πk, π̂k)   実走順からの乖離
図3目的関数。ai は拠点 i への到着時刻、Lk は車両 k の総積載量。第六項の πk は解の訪問順、π̂k は同一条件下で過去に観測された実走順、d は順列間の距離(ケンドールのτ距離等)である。重み w1..6 は設計者が決めるのではなく、第5節の手続きで実績から較正する。

3.1第六項について

第六項は標準的なVRPTWには現れない。これは第1節の性質1——実走順には表に書かれていない知識が織り込まれている——を目的関数に明示的に取り込むための項である。数理的に最適でも実走順から大きく外れた解は、現場が受け入れないか、モデル化されていない制約に抵触する可能性が高い。w6 を大きく取れば「現行運用の微修正」に、小さく取れば「白紙からの再設計」に近づく。この一つの重みが、提案の急進度を制御するつまみになる

ただし第六項には副作用がある。実走順を強く尊重するほど、現行運用に埋め込まれた非効率もまた再生産される。w6 の値そのものが、既存知識の尊重と改善余地の探索とのトレードオフを表す。第5節では、これを単一の値に決め打ちせず、パレート境界として提示する方法を採る。

4訪問頻度の決定 — 閉形式と週次割付

前節の定式化は、訪問すべき拠点集合が所与であることを前提としていた。しかし実務上より手前にある、そしてより効果の大きい問いは「その拠点には何日おきに行くべきか」である。本節はこれを、需要予測の問題ではなく在庫補充の問題として定式化する。

4.1問題の再定義

各拠点は、不確実な速度で満ちていく容器とみなせる。意思決定は「いつ空けるか」であり、費用構造は明快である。頻繁に行きすぎれば訪問費用の無駄になり、間隔を空けすぎれば容器が溢れる。この構造は定期発注方式の在庫管理そのものであり、経路選択と組み合わせた形は在庫配送問題(IRP)として知られる。

この再定義には実務上の利点が三つある。第一に、決定変数が数量 qi ではなく間隔 Ti になる。間隔は運用が直接操作できる量である。第二に、基準となる間隔は実績のみから決まり、気象データを一切必要としない。第三に、後述するとおり閉形式の解が存在する。気象と暦は、この基準間隔を微調整する第二層として位置づけられる。

4.2蓄積モデルと基準間隔

拠点 i の日次発生量を確率変数 Xi とし、平均 λi(袋/日)、分散 σi2 とする。日々の発生が独立と仮定すれば、T 日間の蓄積量 Ai(T) について次が成り立つ。

E[Ai(T)] = λi T
SD[Ai(T)] = σiT

溢れ確率をα以下に抑える制約:
P(Ai(T) > Ci) ≤ α  ⟺  λiT + z1−α σiTCi
図4蓄積の平均と標準偏差。Ci は容器容量、z1−α は標準正規分布の上側分位点(α=5%なら1.645)。平均は T に比例して増えるが、ばらつきは √T でしか増えない。したがって間隔が長いほど相対的なばらつき(変動係数)は 1/√T で縮む。長い間隔のほうが「読みやすい」という、直感に反するが重要な性質である。

この制約を等号で解く。u = √T と置けば λiu2 + z σi uCi = 0 という u の二次方程式となり、正の根から基準間隔が閉形式で得られる。

基準間隔(サービス水準基準):

  Ti* = [ ( −z1−α σi + √( z1−α2 σi2 + 4 λi Ci ) ) ⁄ ( 2 λi ) ]2

確認: σi → 0 のとき Ti* → Ci ⁄ λi (純粋な充填時間)
図5基準間隔の閉形式。この式に反復計算も最適化ソルバも要らないλiσiCi を実績から推定すれば、拠点ごとの間隔が直ちに定まる。σ が大きいほど T* は充填時間より短くなり、その差が安全余裕にあたる。 正規近似の適用範囲に注意する。この導出は蓄積量 Ai(T) の正規近似に依拠しており、T が1〜2日と短く λi も小さい拠点では裾が甘くなり、α が名目値からずれる。そのような拠点では、第8節で用いる過分散カウント分布の側で分位点を直接評価し、得られた T* を短縮側へ丸めるのが安全である。閉形式は間隔が数日以上の拠点で素直に働く近似であって、万能の式ではない

4.3サービス水準を費用から導く

閉形式は α(許容する溢れ確率)を外生的に与える必要がある。これを勘で決める代わりに、費用から導出できる。訪問1回の費用を cv、溢れ1回の費用(緊急対応・信用毀損)を co とすると、長期の日あたり費用は次で表される。

J(T) = [ cv + co · Pover(T) ] ⁄ T
Pover(T) = 1 − Φ( ( CiλiT ) ⁄ ( σiT ) )

minT>0 J(T) — 一次元の平滑な最小化。数値解で十分
図6費用最小化による間隔。閉形式にはならないが、変数は T のみの一次元問題であり、区間を切って数値的に最小化すれば確実に解ける。scipy.optimize.minimize_scalar の一行で足りる。ここでも汎用のブラックボックス最適化は不要である。

実務的には、co(溢れの費用)の見積もりが難しい。推奨する使い方は、費用版で一度 α を較正し、日々の運用は図5の閉形式で回すことである。co/cv の比だけが効くため、「溢れ1回は訪問何回分の損失か」という問いに答えられれば足りる。

4.4実効日数 — 気象と暦による調整

ここまでは蓄積速度 λi を定数として扱った。実際には気温や暦によって日々変動する。ここで基準間隔の枠組みを壊さずに調整を入れる方法が、実効日数の導入である。

d の蓄積速度を、拠点固有の基準速度と、その日の倍率の積として表す。

λi(d) = λi · m(xd),    m(xd) = exp( βxd ),    E[m] = 1 に正規化

暦日 T 日ぶんの蓄積は、実効日数 Teff ぶんの蓄積に等しい:

  Teff(t, T) = Σd=t+1t+T m(xd)

運用規則:   前回訪問からの累積 TeffTi* に達した日に訪問する
図7実効日数による調整。T* の閉形式はそのまま使い、時計の進み方だけを気象と暦で変える。猛暑日は1日が1.4日ぶんに進み、事業所拠点の休業日は0.2日ぶんしか進まない、という形になる。農業の積算温度と同じ発想である。

分散についても同様に TTeff で置き換えればよい。したがって図5の閉形式は一切変更せず、入力の「日数」を「実効日数」に読み替えるだけで調整が完了する。これが本節の構成上の要点である。基準は実績のみから決まり、気象は基準を歪めるのではなく時計の速度を変える。

倍率の係数 β の推定が、次節で扱う回帰の役割である。ここで重要なのは、β は拠点ごとではなく業態ごとに推定すれば足りるという点である。拠点固有の情報はすべて λi に吸収されており、β が担うのは「暑い日は何割増えるか」という業態共通の感応度だけである。これにより、拠点あたり観測数が少ないという制約が緩和される。

4.5週次パターンへの割付 — ここが組合せ問題

閉形式が返す Ti* は実数である。しかし運用は「3.7日おき」を実行できない。曜日パターン(毎日/月水金/火木/週1回・火 など)に割り付ける必要があり、同時に曜日ごとの作業量を平準化しなければならない。ここで初めて、閉形式では解けない組合せ最適化が現れる

パターン集合 P、拠点集合 N、曜日 d。yip = 1 ⟺ 拠点 i にパターン p を割り当てる

min   Σi∈N Σp∈P np yip   総訪問回数の最小化

s.t.   Σp yip = 1   ∀i   各拠点は1パターンに属する
     yip = 0   if maxgap(p) > Ti*   間隔制約を破るパターンは除外
     Σi Σp apd yip siWd   ∀d   曜日 d の総作業量が capacity 以内
     yip ∈ {0, 1}
図8週次パターン割付の混合整数計画。np はパターン p の週あたり訪問回数、apd は曜日 d に訪問するかの指示子、si は拠点の作業所要。制約が明示的な線形式で書けるため、混合整数計画ソルバが最適性を保証して解く。地理的なまとまりを加味するなら、既存コースからの移動を penalize する項を目的関数に加える。

この問題は、拠点数が数百・パターン数が十数であれば、標準的なソルバで実用時間内に解ける規模である。そしてこれはブラックボックス最適化の問題ではない。目的関数も制約もすべて明示的に書けており、その構造を利用できるソルバを使わない理由がない。道具の選択については次々節で改めて整理する。

本節の構成上の含意

訪問間隔の決定は三段に分かれ、それぞれ必要なデータと道具が異なる。(1)基準間隔 Ti*——実績のみ、閉形式。気象データを待つ必要がない。(2)実効日数による調整——気象・暦データと回帰係数 β。通年データが揃ってから。(3)週次パターンへの割付——混合整数計画。第一段だけでも実務価値があり、しかも今日のデータで実行できる

5目的関数の重みの較正

本節が本稿の中心である。構成は二重ループになる——内側で専用ソルバが巡回路を構築し、外側でその目的関数の重みを探索する。内側と外側で道具が異なる点が要諦であり、その整理は第6節で行う。まず外側、すなわち重み w1..6 をどう決めるかという問いに対し、実績を教師信号とする逆問題として解くという答えを与える。

5.1着想

我々は真の目的関数を知らない。しかし、熟練ドライバーが日々選んだ巡回路は観測できる。彼らの選択が(局所的にせよ)合理的であると仮定するなら、ソルバの出力が実績とよく一致するような重みこそが、現場が実際に最小化している目的関数の近似である。これは選好の逆推定にあたる考え方であり、評価に時間のかかる関数(=一日分をソルバで解く)を少ない試行で探索するという構造は、ブラックボックス最適化の典型的な適用対象である。

5.2目的関数の実装

import optuna

VALID_DAYS = load_days(# 実績が揃っている過去の稼働日)

def objective(trial):
    w = {
        # 移動時間を基準(1.0固定)に、他を相対値として探索する。
        # 全係数を自由にすると目的関数がスケール不定になるため。
        "dist":     trial.suggest_float("w_dist",     0.0, 2.0),
        "tw":       trial.suggest_float("w_timewindow", 0.1, 50.0, log=True),
        "cap":      trial.suggest_float("w_capacity",   0.1, 50.0, log=True),
        "balance":  trial.suggest_float("w_balance",    0.0, 5.0),
        # w_order は単一目的の較正では固定する(5.5 の退化解を参照)
        "order":    W_ORDER_FIXED,
        # ソルバ側のメタパラメータも同時に探索対象に含める
        "meta":     trial.suggest_categorical(
                        "local_search", ["guided_local_search",
                                        "tabu_search",
                                        "simulated_annealing"]),
        "limit_s":  trial.suggest_int("time_limit_s", 5, 60),
    }

    losses = []
    for step, day in enumerate(VALID_DAYS):
        plan   = solve_vrptw(day, weights=w)      # 内側: 専用ソルバ
        actual = observed_route(day)              # 実績
        losses.append(divergence(plan, actual))

        # 見込みのない試行を早期に打ち切る
        trial.report(sum(losses) / len(losses), step)
        if trial.should_prune():
            raise optuna.TrialPruned()

    return sum(losses) / len(losses)

study = optuna.create_study(
    direction="minimize",
    sampler=optuna.samplers.TPESampler(seed=42),
    pruner=optuna.pruners.MedianPruner(n_warmup_steps=5),
    storage="sqlite:///calibration.db",     # 中断・再開・並列化のため
    study_name="weights_v1", load_if_exists=True,
)
study.optimize(objective, n_trials=300, n_jobs=4)
図9重み較正の骨格。実走順との乖離を目的にしている以上、実走順を尊重する重み w6 を同じ探索に入れてはならない(5.5)。内側のソルバ呼び出しが計算量の大半を占めるため、枝刈りの効果が大きい。試行結果を永続化しておくと、実績が増えるたびに load_if_exists で探索を継続できる。

5.3乖離度の定義

divergence() の設計が結果を大きく左右する。単一の指標では捉えきれないため、三成分の重み付き和として定義する。

成分定義捉えるもの
集合差訪問拠点集合のジャッカード距離そもそも同じ拠点群を回っているか
順序差共通拠点上のケンドールのτ距離回る順序が一致しているか
時刻差各拠点への到着時刻の平均絶対誤差(分)所要時間モデルが現実に合っているか

三成分のうち時刻差が突出して大きい場合、それは重みの問題ではなく所要時間行列の推定精度の問題である。較正の前に派生層の品質を疑うべきであり、この切り分けが可能な点も三成分に分ける利点である。

5.4単一目的から多目的へ

実務では「実績の再現」と「効率の改善」は対立する。実績を完全に再現する重みは、定義上、現行運用と同じ効率しか生まない。したがって単一目的での最小化は、較正の第一段階としては正しいが、提案生成としては不十分である。

study = optuna.create_study(
    directions=["minimize", "minimize"],      # 実績乖離, 総移動時間
    sampler=optuna.samplers.NSGAIISampler(seed=42),
)

def objective(trial):
    w = suggest_weights(trial)
    div, total_time = evaluate(w, VALID_DAYS)
    return div, total_time

study.optimize(objective, n_trials=500)

# パレート境界: 「現行に近い解」から「効率重視の解」までの連続体
for t in study.best_trials:
    print(t.values, t.params)
図10多目的化。得られるのは単一の推奨案ではなくパレート境界であり、「現行から15分短縮する案は実績からこの程度離れる」という選択肢の連続体を配車担当者に提示できる。最終判断を人間に残す点で、実務への導入障壁が低い。

5.5探索空間設計の注意点

退化解 — w6 を探索に入れてはならない

目的関数の第六項は実走順からの乖離への罰則であり(3.1)、一方で較正の目的関数は実走順との乖離の最小化である。両者は同じ量を指しているため、w6 を探索空間に含めると、探索は単に w6 を上げるだけで評価値を下げられてしまう。得られるのは「実績をなぞれ」という自明な解であり、他の重みは推定されない。

対処は明快である。単一目的の較正段階では w6 を固定し、探索から除外する。これにより残る重み w1..5 は、実走順という制約の下で実績を説明する係数として推定される。w6 を可変にするのは多目的化(5.4)以降であり、そこでは「実績への近さ」と「効率」が別の目的として立つため、w6 を上げることが一方の目的を改善しつつ他方を悪化させる——退化しない。提案の急進度を制御するつまみとしての w6 は、パレート境界の上でこそ意味を持つ

6最適化手法の選択 — 何にどの道具を使うか

ここまでに、性質の異なる六つの最適化問題が現れた。同じ「最適化」という語で括られるが、要求される道具はまったく異なる。本節はその対応を整理する。実務上、最も費用のかかる誤りは構造が分かっている問題にブラックボックス最適化を使うことである。

6.1最初に問うべきこと — それは本当にブラックボックスか

ブラックボックス最適化が正当化されるのは、目的関数について評価しかできない場合に限られる。すなわち、閉形式がなく、勾配が取れず、線形・凸などの利用可能な構造もなく、評価そのものが高価(シミュレーションやソルバ呼び出し)である場合である。この四条件のいずれかが崩れていれば、より良い道具が存在する。

構造があるのにブラックボックス最適化を使うと、四つの損失が生じる。最適性の保証を失う(近傍の良い点を返すだけで、それが最適である証明はない)。再現性を失う(乱数種と試行数に依存する)。説明性を失う(なぜその値かを式で説明できない)。そして単純に遅い(構造を使えば一発で解ける問題に数百回の評価を費やす)。

6.2本稿に現れた六つの問題と、その道具

問題性質適切な道具ブラックボックス最適化
基準訪問間隔 Ti*
(4.2)
二次方程式に帰着。閉形式解あり 式をそのまま評価する 不要。解があるものに探索を使う理由がない
費用最適な間隔
(4.3)
一次元・平滑・単峰 一次元数値最小化
minimize_scalar
過剰。区間を切って走査すれば確実
気象・暦の係数 β
(第8節)
対数尤度が凸。勾配が解析的に得られる 最尤推定・一般化線形モデル
小標本なら階層ベイズ
不適。勾配が使えるのに使わない選択になる。標準誤差も得られなくなる
週次パターン割付
(4.5)
離散変数+線形制約。実行可能性が本質 混合整数計画/制約プログラミング 不適。制約充足の保証がなく、実行不能解を返しうる
方策の学習
(第12節)
生成器で事例を無限に供給でき、微分可能 方策勾配法(深層学習) 不適。勾配が使える以上、勾配を使う
目的関数の重み較正
(第5節)
評価にソルバ呼び出しを含む。勾配なし。連続+カテゴリ混在 ブラックボックス最適化 。本稿で唯一、正当化される用途

六つのうち五つで、ブラックボックス最適化は不要である。この事実自体が、道具を先に決めてから問題を眺めることの危うさを示している。

階層ベイズという第三の選択肢

拠点あたりの観測数が乏しい段階では、λi の点推定を信じること自体が危うい。サービス水準の計算に必要なのは点推定ではなく予測分布であり、階層ベイズモデルはこれを直接与える。同時に、観測の乏しい拠点を業態平均へ縮小する働き(7.2の縮小推定を、恣意的な重みなしに実現する)も持つ。確率的プログラミング言語による事後分布のサンプリングは、最適化とは別系統の道具であり、「不確実性を伝播させたい」場合の第一選択である

6.3ブラックボックス最適化ツールの比較

6.2 でブラックボックス最適化が適するとされた問題に限って、どのツールを選ぶかを検討する。まず中核となるアルゴリズムの系統を押さえると、ツールの違いは理解しやすい。

アルゴリズム系統考え方得意不得意
ランダム探索/準乱数 一様に振る 実装ゼロ、並列が自明、有効次元が低ければ意外に強い 試行数が必要
TPE
(木構造Parzen推定)
良い群と悪い群の入力分布を別々にモデル化し、比が大きい点を選ぶ カテゴリ変数・条件付き空間。数百〜千試行で安定 変数間の相互作用の捕捉が弱い
ガウス過程ベイズ最適化 目的関数そのものを確率過程でモデル化し、獲得関数で次点を決める 試行数が数十しか取れない高価な評価。不確実性を明示 試行数の3乗で重くなる。高次元・カテゴリに弱い
進化戦略(CMA-ES 等) 探索分布の共分散を適応させる 連続変数、悪条件、評価値に雑音がある場合 試行数を要する。カテゴリ変数を扱えない
遺伝的多目的(NSGA-II 等) 非劣解の集団を進化させる パレート境界を面として得たい場合 単一目的なら他手法が効率的
ランダムフォレスト代理 木モデルで目的関数を近似 条件付き・カテゴリ混在の構造化空間 連続変数の細かい最適化は苦手

主要なツールは、これらのアルゴリズムをどう束ねるかで性格が分かれる。

ツール中核特徴選ぶ理由
Optuna TPE(既定)、CMA-ES、NSGA-II、GP、QMC を切替可能 実行しながら探索空間を定義できる記法。枝刈り機構。試行のデータベース永続化。多目的対応 汎用の第一選択。試行数100〜1000、変数が混在、中断再開が要る場合
Hyperopt TPE TPEの原典実装。軽量 保守が停滞しており、新規に選ぶ積極的理由は薄い
scikit-optimize ガウス過程ほか scikit-learn 風の簡潔なAPI 評価が非常に高価で試行数が数十のとき
Ax / BoTorch ガウス過程+獲得関数 多目的・制約付き・バッチ提案が体系的。実験計画としての設計 制約付き多目的を厳密に扱いたい場合。学習コストは高い
SMAC3 ランダムフォレスト代理 条件付き探索空間の扱いに強い 「Aを選んだときだけBが現れる」型の構造化空間
Nevergrad 進化戦略・微分不要手法の詰め合わせ 手法の比較実験がしやすい 評価値に雑音が乗る問題
Ray Tune 実行基盤(探索器は他を利用) 分散実行と打ち切りスケジューリング 複数ノードで大規模に回す場合。単一機なら過剰

6.4選択の指針

6.5本稿の問題設定における結論

本稿の六問題のうち、ブラックボックス最適化が適するのは目的関数の重み較正のみである。そしてその一つについては、Optuna が要件によく合う。理由は探索性能そのものではなく、周辺機能にある。すなわち、(a)連続変数とカテゴリ変数が混在する空間を素直に書ける、(b)評価が日ごとに途中経過を出せるため枝刈りが効く、(c)試行をデータベースに永続化でき、実績が増えるたびに探索を継続できる、(d)単一目的から多目的への移行がサンプラの差し替えだけで済む。

逆に言えば、これらの要件が無ければ他のツールでも構わない。探索アルゴリズムの選択が結果を左右する場面は、実務では思われているほど多くない。多くの場合、探索空間の設計(スケールの固定、対数スケールの採用、無意味な範囲の除外)と評価関数の定義のほうが、サンプラの違いより桁違いに効く。

最も重要な指針

道具から問題を選ばず、問題から道具を選ぶ。「ブラックボックス最適化の事例を作る」ことを目的に据えると、閉形式で解ける訪問間隔を数百回の試行で近似するような、遅く・不正確で・説明できない実装が生まれる。本稿の訪問間隔の式(図5)は、その最も分かりやすい反例である——最良の最適化とは、最適化を必要としない定式化に到達することである

第II部

予測問題 — 在庫推論

いま各拠点にどれだけ溜まっているか。第I部が消費する蓄積量の分布を供給する。

7蓄積速度の推定

7.1予測対象の定義 — 流量ではなく累積量

設計を誤りやすい第一の点がここにある。回収時に得られる数量は、その日に発生した量ではなく、前回訪問以降に蓄積した量である。したがって被説明変数は流量ではなく累積量であり、支配的な説明変数は気象ではなく前回訪問からの経過日数である。

この定義から、二つの帰結が導かれる。第一に、気象変数は回収日当日の値ではなく、前回訪問日の翌日から当日までの区間で集約した値でなければならない。当日の気温を特徴量に入れる実装は、蓄積の物理と整合しない。第二に、経過日数の効果は線形とは限らない。容器が満杯になれば、それ以上は蓄積しない。

訪問間隔は拠点ごとにも訪問ごとにも一定でない。経過日数を明示的に扱わない限り、拠点間・訪問間の数量は比較不能である。

飽和と打ち切り

容器容量に達した拠点では、観測される数量は真の発生量ではなく容量そのものになる。これは統計学でいう右側打ち切りであり、通常の回帰は係数を系統的に過小推定する。ある拠点の全観測で数量が同一値に張り付く、変動係数がゼロという状態が現れたなら、それは需要が完全に一定なのではなく、容量で頭打ちになっているか、単位が固定されていることを強く示唆する。打ち切りの疑いがある拠点を識別し、別扱いにするか打ち切り回帰(Tobit型)を用いる必要がある。

7.2実績からの推定

拠点 i の連続する訪問について、経過日数 gk と回収量 qk の対が得られる。推定量は次のとおりである。

λ̂i = ( Σk qk ) ⁄ ( Σk gk )   総回収量 ÷ 総経過日数(曝露で重み付けた比推定量)

σ̂i2 = ( 1 ⁄ (K−1) ) Σk ( qkλ̂i gk )2gk   Var(qk) = σ²gk に対応した分散推定

SE( λ̂i ) ≈ σ̂i ⁄ √( Σk gk )
図11蓄積速度とその不確実性の推定。単純な「回収量の平均」ではなく総量を総日数で割る比推定量を用いるのは、訪問間隔が一定でないためである。訪問間隔は通常1日から1週間程度まで分布するため、単純平均は間隔の長い観測に引きずられる。

打ち切りの補正。 容器が満杯だった回の qk は真の発生量ではなく容量である。これを素直に平均すると λ̂i は下振れし、間隔がさらに長く算出され、溢れが増えるという悪循環に入る。実務的な処理は、観測の一定割合(たとえば2割)以上が最大値に張り付いている拠点を「打ち切り疑い」として識別し、その λ̂i下限値として扱う——すなわち算出された T* をそのまま採用せず、短めに丸めることである。

小標本の縮小推定。 拠点あたりの観測数が十分でない段階では、λ̂i の標準誤差は無視できない。点推定をそのまま閉形式に入れると、たまたま少なく観測された拠点の間隔が過大に算出される。同一業態の全体平均 λ̄ へ縮小させる。

λ̃i = wi λ̂i + (1 − wi) λ̄,    wi = τ2 ⁄ ( τ2 + SE(λ̂i)2 )
τ² = 業態内における拠点間の真の分散。観測が少ない拠点ほど w が小さく、全体平均に寄る
図12経験ベイズによる縮小推定。観測が十分な拠点は自身の推定値をほぼそのまま使い、観測の乏しい拠点は業態平均へ寄せられる。この重み wi は手で決めるものではなく、データから τ2 を推定して定まる。

7.3識別可能性と必要標本量

手法を論じる前に、標本がその推定を支えるかを問う必要がある。ここで効くのは総観測数ではなく、推定したい係数の階層と、観測が張る範囲である。三つの独立した条件を順に確認する。

条件1: 階層に応じた観測数。 目安として、推定するパラメータ1個あたり10〜20観測を要する。拠点数を n、拠点あたり観測数を k とすると、推定できるモデルの階層は次のように分かれる。

推定したいもの必要な条件成立しない場合の代替
全体で共通の係数nk が係数の10〜20倍—(最も緩い)
業態別の係数各業態内で同上業態を粗く束ねる
拠点別の水準(切片)k ≳ 5〜10業態平均への縮小推定(7.2)
拠点別の係数(感応度)k ≳ 30〜50共通係数+拠点別切片で代用

実務上ほぼ常に成り立つのは上二段であり、拠点別の感応度が推定できるのは長期の蓄積を経てからである。この段差を認識せずに拠点別モデルを組むと、雑音を係数として読み取ることになる

条件2: 説明変数が十分な範囲を張っているか。 これは総観測数では代替できない、より厳しい条件である。観測期間が一年に満たない場合、気温の係数は季節に伴う他のすべての変化——学校の在学期間、行楽期、来客構成、日照時間——と本質的に分離できない。標本を増やしても、期間が偏っていれば交絡は解けない。同様に、祝日の効果を業態別に推定するには、各業態が十分な数の祝日を経験している必要がある。

したがって推奨される順序は、暦だけのモデルから始めることである。曜日と祝日の効果は同一季節内でも識別できるため、通年データを待たずに推定できる。気象変数の追加は季節を一巡してからでよい。この順序を守れば、交絡した係数を早期に信じてしまう事故を避けられる。

条件3: 説明すべき変動が実在するか。 逆方向の確認も要る。拠点内の変動係数がゼロに近ければ、その拠点は定数で足り、回帰は不要である。回帰が意味を持つのは、蓄積速度に説明可能なばらつきが存在する場合に限られる。加えて、データが複数の測定系(紙伝票の転記と端末入力など)から来ている場合は、系統差を吸収する指示変数を必ず入れる。丸め方や欠測の癖が系統ごとに異なるため、これを入れないと測定系の差が気象の効果として現れうる。

8気象と暦による調整

前節は、基準間隔 Ti* を実績のみから閉形式で定め、気象と暦は実効日数の倍率 m(xd) = exp(βxd) として時計の速度を変える、という二層構成を示した。本節はその第二層、すなわち係数 β をどう推定するかを扱う。あわせて、推定に必要な外部データの取得と保持を設計する。β は拠点ごとではなく業態ごとに推定すれば足りるため、拠点あたり観測数が少ないという制約は第一層ほど厳しくない。

8.1外部データの取得と保持

気象と暦は業務システムの外にあるデータであり、取得方法と保持形式を先に決める必要がある。要件は三つ、過去に遡って取得できること(蓄積済みの実績を後から特徴量つきにするため)、自動取得できること(手作業では継続しない)、再配布・保存が許諾されていることである。

データ取得元の性質用途と留意点
過去の気象実況 気象庁の過去データ配布ページ。観測地点×日次/時別のCSVを無償で取得できる。文字コードはShift-JIS 学習用の正解値はここから取る。公的機関の一次データであり、保存・加工の制約が最も少ない
過去の気象実況(API) 緯度経度を指定して過去実況をJSONで返す無償APIが複数存在する。認証キー不要のものもある プログラムからの一括遡及取得に向く。拠点座標が未整備なら地区の代表点で代用する
気象予報 気象庁の防災情報配信、および民間気象サービス 運用時の入力はこちら。学習は実況、推論は予報という不一致に注意(下記)
祝日 内閣府が公開する祝日一覧CSV。1955年以降の全祝日を収録 振替休日を含む。年末年始・お盆は法定祝日でないため別途定義が要る
民間の天気表示サービス 画面表示を目的としたサービス 過去実況の一括取得や再保存は利用規約の確認が必須。学習データの供給元としては公的一次データを優先すべき

保持は二つの独立したテーブルに分ける。実績テーブルには一切の気象列を持たせない。気象は後から遡って修正されることがあり、また同じ日の値を複数拠点が共有するためである。

-- 気象観測: 地点×日。実績テーブルとは独立に日次バッチで積む
CREATE TABLE weather_daily (
  obs_point   TEXT    NOT NULL,   -- 観測地点コード
  obs_date    TEXT    NOT NULL,
  temp_mean   REAL,   temp_max REAL,  temp_min REAL,
  precip_mm   REAL,   sunshine_h REAL, humidity REAL,
  is_forecast INTEGER NOT NULL DEFAULT 0,   -- 予報値か実況値か
  fetched_at  TEXT    NOT NULL,
  PRIMARY KEY (obs_point, obs_date, is_forecast)
);

-- 暦: 日ごとに1行。祝日CSVと自社の稼働規則から生成
CREATE TABLE calendar_days (
  cal_date        TEXT PRIMARY KEY,
  weekday         INTEGER NOT NULL,        -- 0=日 … 6=土
  is_holiday      INTEGER NOT NULL,        -- 法定祝日・振替休日
  holiday_name    TEXT,
  is_company_off  INTEGER NOT NULL,        -- 自社休業日(年末年始・お盆等)
  run_length_off  INTEGER NOT NULL,        -- その日が属する連休の長さ
  days_since_off  INTEGER,                 -- 直前の休業日からの経過日数
  school_term     TEXT                     -- 'term' | 'vacation'(学校拠点用)
);

-- 拠点と観測地点の対応。座標が無い間は地区で代用する
CREATE TABLE location_obs_point (
  location_id INTEGER PRIMARY KEY,
  obs_point   TEXT NOT NULL,
  mapping     TEXT NOT NULL              -- 'nearest' | 'region_default'
);
図13外部データの保持設計。is_forecast を主キーに含めることで、同一日について予報値と後日確定した実況値の両方を保持できる。これは学習・推論の不一致(4.2末尾)を定量化するために必要である。

学習と推論の不一致。 モデルは実況値で学習されるが、運用時に入力できるのは予報値である。予報には誤差があるため、実況で学習したモデルに予報を与えると精度は必ず劣化する。対処は二通りある。(a)予報値でも学習し、予報の誤差込みで係数を推定する。(b)実況で学習した上で、予報誤差の分だけ予測区間を広げる。実装が簡単なのは(b)だが、is_forecast の両方を保持しておけば、後から(a)に移行できる。

8.2特徴量の設計

特徴量は、経過日数・気象・暦・拠点属性の四群に整理される。気象と暦はいずれも訪問区間で集約する点が要点である。

特徴量設計意図
経過gap_days の対数蓄積量の主因。対数で入れると係数が「蓄積の逓減度」として解釈できる
前回の数量持ち越し・容器状態の代理変数
気象
(区間集約)
平均気温・最高気温の最大値飲料消費の主要因という仮説。暑いほど容器が増える
降水日数・総降水量屋外・集客施設の来訪減を捉える
猛暑日・真夏日の日数気温の非線形効果。閾値を超えた日数として入れる

(区間集約)
区間内の曜日構成平日・土日の日数。単純な「回収日の曜日」より情報量が多い
区間内の祝日数・連休長業態により符号が逆転する(下記)
学校の長期休暇フラグ教育機関拠点の需要が消える期間
拠点業態区分暦・気象の効果の符号と大きさを決める最重要の分岐
口数・容器容量スケール調整と打ち切り判定に用いる

業態による効果の符号反転。 祝日の効果は業態によって逆向きである。教育機関・事業所・官公庁の拠点は休日に人がいなくなるため発生量が減る。一方、遊技場・商業施設・宿泊施設は休日に来客が増えるため発生量が増える。両者を混ぜた単一の祝日係数はゼロ付近に打ち消し合い、「祝日は効かない」という誤った結論を導く。業態区分と暦特徴量の交互作用項は必須である。気温についても、屋内空調の効いた事業所と屋外施設では効き方が異なる。

8.3モデルの選択

被説明変数は非負の整数(袋数)であり、右に裾を引き、ゼロを含む。通常の最小二乗法は前提を満たさない。加えて、拠点数に対して拠点あたり観測数が少ない階層構造を扱う必要がある。

import statsmodels.formula.api as smf
import statsmodels.api as sm

# 負の二項回帰。対数リンクにより、各係数は「発生量の倍率」として解釈できる
#   log_base_rate = log(拠点の過去平均日次発生量) をオフセットに置き、
#   拠点ぶんのダミー変数を推定せずに拠点差を吸収する(簡易的な部分プーリング)
model = smf.glm(
    formula=(
        "quantity ~ np.log(gap_days)"
        " + C(segment) * (holidays_in_gap + weekend_days_in_gap)"
        " + C(segment) * temp_max_in_gap"
        " + rain_days_in_gap + hot_days_in_gap"
        " + C(source)"            # 伝票OCR / 端末入力 の測定系の差を吸収
    ),
    data=df,
    family=sm.families.NegativeBinomial(),
    offset=df["log_base_rate"],
).fit()

print(model.summary())
図14出発点となるモデル。拠点を固定効果(ダミー変数)として入れると、拠点数に対して拠点あたり観測数が乏しい段階では推定が破綻する。過去平均をオフセットに置く方法は、統計的には粗いが、この段階では最も安定した実務的解である。

log(gap_days) の係数は診断値として読む。 蓄積が経過日数に比例するなら、この係数は1付近になるはずである。実測値が明確に1を下回る拠点群があれば、それは容量による飽和が起きている証拠であり、4.1で述べた打ち切りの扱いが必要になる。係数を予測精度のためだけでなく、モデルの前提が成り立っているかの検査に使う

データが増えた段階では、次の順に高度化する。(1)拠点をランダム切片とする混合効果モデルへ移行し、観測の少ない拠点は全体平均へ縮小(shrinkage)させる。(2)勾配ブースティング木で非線形性と交互作用を自動的に捉える。ただし拠点あたり観測が少ない段階で木モデルを使うと、拠点IDに過適合しやすい。(3)ゼロ過剰(「回収物なし」の記録)が無視できないなら、ゼロ過剰モデルを検討する。

8.4評価とベースライン

予測モデルの評価で最も重要なのは、越えるべきベースラインを先に決めておくことである。気象と暦を投入したモデルが、素朴な代替案に勝てないことは珍しくない。

検証の分割は目的によって変える。既存拠点での性能を測るなら時系列で分割する——無作為分割は同一拠点の未来の観測が学習側に混入し、精度を過大評価する。未知拠点への一般化を測るなら拠点で分割する(9.4)。両者は別の量であり、前者が良くても後者が悪いことは普通に起きる。指標は数量の平均絶対誤差(袋)に加え、業務上の判断に直結する指標を併置する。すなわち「その日の当該コースが車両の積載上限を超えるか」という二値判定の正解率である。数量の誤差が小さくても積載超過の判定を外すなら、配車には使えない。

気象変数がB1に勝てないなら、投入しない。 特徴量が増えるほど、取得・保持・監視のコストが恒常的に発生する。効果が確認できない特徴量を残すのは、精度ではなく運用負債を増やす行為である。

8.5予測の使い道と、自己成就のわな

回収量予測の用途は二つある。第一は前節の qi として最適化に入力し、積載制約の実行可能性を判定すること。第二は訪問頻度の見直しである。予測発生量が恒常的に小さい拠点は、訪問間隔を延ばせる可能性がある。回収一回ごとに費用が発生する業態では、後者のほうが経路最適化より直接的に効く

ただし第二の用途には固有の危険がある。予測が小さい拠点の訪問を減らすと、その拠点の観測が減り、モデルを更新する材料が失われる。予測が外れていても、それを検知する機会が消える。これは自己成就的な予測であり、機械学習系のシステムが運用判断に組み込まれたときの典型的な失敗である。

対処は、意図的に予測に反する観測を残すことである。一定割合の訪問を、予測にかかわらず従来頻度で実施し、真の発生量を観測し続ける。実務的には、「回収物なし」の記録が蓄積されること自体が頻度見直しの根拠になるため、ゼロを正しく記録する運用——訪問したが回収物がなかった事実を、入力漏れと区別して残すこと——が、この探索の役割を部分的に果たす。

第III部

転移問題 — 未知のマップへの適応

マップ——一つの営業地域、すなわちその土地の道路網・拠点の空間配置・顧客構成・気候・交通事情の総体——を単位として考える。第I部・第II部は、手元のマップに対して良い解と良い推定を与えた。第III部が問うのは、まったく別の地域に持ち出しても同じ性能が出るかである。新しい土地で数年の実績が溜まるのを待たずに展開できるかは、この一点にかかっている。

9マップ不変な表現 — 転移の前提条件

第III部が目指すのは、ある地域で学習した模型が、まったく別の地域でそのまま使えることである。道路網も顧客構成も気候も交通事情も異なる土地へ事業を広げるとき、そこで数年の実績が溜まるのを待つのでは遅い。

この目標は、模型の入力に何を許すかによってほぼ決まる。本節はその制約を先に定める。以降の各節——移動時間、需要、方策——はいずれもこの制約の下で設計される。

9.1転移が壊れる原因

転移が成立しない模型には共通の特徴がある。他のマップに存在しない量を入力にしていることである。拠点識別子、区間識別子、絶対緯度経度、地域名、コース番号——いずれも別の土地には対応物がない。これらを入力に取った模型は、学習した地域の索引表として振る舞い、新しいマップに対して何も言えない。

厄介なのは、この種の模型は既存地域の検証では極めて良い成績を出すことである。索引表は自分が索引している対象に対しては完璧に答える。日で分割した検証は、この失敗を検出できない。

9.2何が不変で、何が不変でないか

入力にしてよい(マップ不変)入力にしてはならない(マップ固有)
幾何 拠点間の相対距離・方位、近傍密度、クラスタ規模、集合の広がり 絶対緯度経度、地域名、行政区分
拠点 業態区分、容器容量、口数、時間枠の幅、搬入条件 拠点識別子、取引先識別子
区間 距離帯、道路種別の構成、市街地度、時間帯 区間識別子、路線名
暦・気象 気温・降水量そのもの、曜日、祝日、連休長 月のダミー変数、季節区分
運用 車格、積載量、稼働時間の上限 コース番号、乗務員識別子

四行目が最も見落とされやすい。「7月」という月のダミー変数は、地域が変われば意味が変わる——同じ7月でも気候レジームが異なるからである。一方、気温そのものは物理量であり、どのマップでも同じ意味を持つ。業態ごとの感応度——暑いほど飲料容器が増える、雨天は集客施設の来訪が減る——は土地に依存しない機構であり、これは転移する。したがって暦の効果は月ではなく気象で表現しなければならない。この置き換えは、第II部で「気象変数の追加は季節を一巡してから」と述べた順序とも整合する——月ダミーで代用したままでは、そもそも転移可能な模型にならない。

9.3スケールの正規化

不変な量を選んでも、その尺度が地域で異なれば模型は転移しない。都市部と郊外では拠点間距離の分布が桁で違い、事業規模が違えば1日の訪問数も違う。入力は無次元化して与える

正規化により、模型が学ぶのは「何キロメートル」ではなく「その土地の標準的な移動距離の何倍か」になる。この変換が、密な都市部で学んだ方策を疎な地方部へ持ち出すことを可能にする

9.4検証はマップを保留して行う

転移可能性を測る方法は一つしかない。地域を丸ごと保留することである。ある地域の実績を一切見ずに学習し、その地域で評価する。

分割の単位測っているもの使う場面
既存の運用における当てはまり推定精度の確認
拠点新規顧客への冷始動性能営業時の見積
地域(マップ)新規展開地への転移性能事業展開の判断

三者は別の量であり、上から順に厳しい。日で良好、拠点で良好、しかしマップで破綻するという事態は普通に起きる——それは模型がマップ固有の量を学んでいたことの証拠であり、9.2の制約に戻って入力を見直すことになる。既存地域が複数あるなら、そのうち一つを保留する交差検証が実施可能である。単一地域しかない段階では、地理的に離れた部分集合を人為的に切り出して代用する。

10移動時間の転移 — 外部地図と残差の一般化

実績が埋める所要時間行列は疎である(2.3)。しかし任意の拠点対の所要時間は外部の地図サービスから得られる。したがって欠けているのは所要時間の絶対値ではなく、一般的な所要時間と自社の実所要時間との差である。この差を残差として定義し、学習の対象を絞り込む。

τ(i,j) = τ地図(i,j) + δ(i,j) + ε

δ に入るもの: 車格による通行制約、搬入口の位置、駐車と待機、 時間帯の混雑、乗務員の習熟
ε: 日々の変動(信号、天候、荷量)
図15所要時間の分解。地図サービスの値を事前分布とし、実績は残差 δ の学習にのみ用いる。強い事前分布の上の補正であるため、必要な標本は絶対値を推定する場合より桁で少ない

10.1残差を区間ではなく特徴で学習する

残差を区間ごとに推定することはできない。区間数は拠点数の二乗であり、実績はそのごく一部しか埋めないからである。ここが地域をまたいで転移するための要点である——区間の識別子ではなく、区間の特徴を入力として残差を予測する関数を学習する。

特徴捉えるもの
距離帯・道路種別の構成地図サービスの推定が系統的にずれる領域
市街地/郊外の別、時間帯混雑による乖離
発地・着地の拠点属性
業態、口数、搬入条件
荷扱いと駐車に伴う付加時間
車格通行可能経路の制約

この定式化により、一度も走ったことのない区間についても残差を予測できる。予測には分散が伴い、その分散は特徴空間における学習データからの距離とともに増大する。走行実績の多い領域では残差の予測は鋭く、経験のない領域では広い——これがそのまま次節以降の不確実性の扱いへ接続する。

10.2未検証な区間の扱い

残差の予測分散は、提案経路の信頼性を測る指標として直接使える。計量は、提案経路が使う区間について予測分散を集計した値である。これが大きい提案は、残差の事前分布を広く取って再求解するか、当該区間を試走して残差を確認する。12.3の領域ランダム化は、この不確実性を方策の学習段階で扱う対応物である——残差の事後分布から抽出して学習すれば、経験のない領域に対して自動的に保守的な方策が得られる。

検証は区間を保留して行う。実績のある区間を訓練と検証に無作為分割すると、同じ区間が両側に現れて残差の記憶を測ってしまう。区間——あるいは地域——を丸ごと保留し、その残差を一切見ずに所要時間を予測して実績と比較する。これが未経験の土地に展開したときの精度の推定値になる。

11需要の転移 — 属性による冷始動

ここで目的を明確にしておく。このパイプラインが生むべきものは現在の拠点集合に適合した重みではなく、まだ存在しない拠点にも適用できる関数である。新規顧客を獲得したとき、実績が一件もない状態で「この拠点は何日おきに回り、どのコースに入り、限界費用はいくらか」に答えられなければ、模型は運用に追随できない。

これが生成の本質的な価値である。12.1では生成の利点を事例数として述べたが、より重要なのは被覆である。実績のリプレイから学べるのは、自社が現に経験したマップだけである。生成器はマップの空間統計を意図的に走査でき、実在しない配置——密集した都市部、離れた郊外、狭い時間枠が重なった日——も作れる。量ではなく、経験していない状況を作れることが効いている

表現の要件。 方策も推定も、入力を拠点識別子ではなく属性ベクトルに取らなければならない。識別子を入力にした瞬間、その模型は既存拠点の索引表になり、新規拠点に対して何も言えなくなる。

属性用途新規拠点での取得
座標(他拠点との相対位置)経路構成・割付住所から即座に
業態区分暦・気象の感応度、発生量の水準契約時に判明
容器容量・口数閉形式の Ci、打ち切りの判定契約時に判明
時間枠・作業条件制約契約時に判明
周辺の同業態拠点の実績発生量の事前分布既存データから計算

冷始動の手順。 新規拠点について、蓄積速度は属性からの回帰で与える——λi = f(属性i) + 拠点固有効果。実績のない拠点は f(属性) とその予測分散を用いる。移動時間は地図サービスから即座に得られる。したがって新規拠点は初日から間隔と割付が決まる。実績が蓄積するにつれ、拠点固有効果が f からの乖離として推定され、予測が個別化していく。7.2の縮小推定は、この個別化の速度を制御する装置として読み直せる——観測が乏しいうちは f(属性) に寄り、増えるにつれ自身の実績に寄る。

検証は日ではなく拠点で分割する

一般化を目的に据えるなら、検証の分割方法が変わる。日で分割してはならない。同一拠点が訓練側と検証側の両方に現れ、測っているのは記憶であって転移ではなくなる。拠点を丸ごと保留し、その拠点の実績を一切見ずに間隔と経路を決め、実績と比較する——これが冷始動の再現であり、新規顧客に対する性能の推定値になる。さらに業態単位で保留すれば、未知の業態への外挿能力が測れる。

12マップの生成と方策学習

前三節は、不変な表現・移動時間・需要のそれぞれについて転移の手立てを述べた。本節はそれらを束ね、マップそのものを生成し、机上で走らせ、方策を学習する。盤上遊戯の探索エンジンが自己対局で局面を無限に供給するのと同じ構造である。

12.1実績の役割は方策の学習ではなく生成器の較正である

この道筋を検討するにあたり、最初に整理すべきは実績データが何に使われるかである。学習に必要な事例数と、手元にある実績件数を直接比べるのは誤りである。

用途必要な実績供給元
生成器の較正
λ・σ・時間枠・作業時間の分布
104〜105 レコード実績データベース
移動時間地図サービスの経路探索(任意の拠点対について取得可能)
方策の学習不要生成器から無限に供給
検証102〜103 稼働日実績データベース(生成器を通さない)

要点は二行目と三行目である。移動時間は実走の有無に依存しない——地図サービスの経路探索は任意の拠点対について所要時間を返すため、実績が疎であることは行列の穴を意味しない(この含意は第10節で扱う)。そして方策の学習に実績は要らない。必要なのは実績で較正された生成器であり、そこから事例は望むだけ得られる。

12.2生成器の構成

生成器は、一日分の配車問題インスタンスを確率的に生成する。構成要素と較正元は次のとおりである。

要素生成方法較正元
当日の訪問対象各拠点の間隔と経過日数から、訪問すべき集合を決めるTi*(第4節)
発生量Ai ~ 蓄積分布(平均 λiTeff、分散 σi2Teffλiσi(4.3)
気象・暦実効日数の倍率 m(xd) を暦から生成係数 β(第8節)
移動時間地図サービスの所要時間 + 実績との残差分布実績(残差のみ)
作業時間拠点別の分布から抽出実績(作業開始・終了時刻)
制約時間枠・容量・稼働曜日マスタ

移動時間の行が要点である。地図サービスが返すのは一般的な所要時間であり、当該拠点での搬入経路や荷扱いの癖は含まない。したがって地図サービスの値を事前分布とし、実績との残差だけを学習する。残差は強い事前分布の上の補正であるため、必要な標本は絶対値を推定する場合より桁で少ない。

12.3不確実性の扱い — 領域ランダム化

「シミュレータは世界モデルの精度までしか正しくない」という懸念は正当だが、それは方策を点推定の世界に固定した場合の話である。標準的な対処は逆で、パラメータの不確実性そのものを分布として与え、その上で頑健な方策を学ぶ

各エピソードの開始時に、パラメータを事後分布から抽出する:

  λi ~ pi | 実績),   σi ~ pi | 実績),   τij ~ 地図サービス値 + p(残差)

目的:   maxπ   Eθ~p(θ|実績) [ E軌跡~π,θ [ 報酬 ] ]
図16領域ランダム化。パラメータ θ を固定せず、推定の事後分布から毎エピソード抽出する。得られる方策は、特定のパラメータ値に最適化された脆い方策ではなく、推定の不確実性の範囲全体で妥当に動く方策になる。標本が乏しく事後分布が広ければ、方策は自動的に保守的になる——これは7.2の縮小推定が果たす役割の、方策水準での対応物である。

この構成により、推定の誤差は方策を壊す要因ではなく方策が備えるべき環境の一部になる。事後分布が狭まれば方策はより積極的になり、広ければ保守的になる。推定と決定の関係が、パラメータの受け渡しではなく分布の受け渡しへ変わる。

12.4何を学習するか — 三つの水準

(a) 経路構成の方策。 訪問集合を入力として巡回順を構成する。注意機構による符号化・復号が標準的な構成で、1日1車両あたりの訪問数は20前後、全体でも数百の水準にとどまるため、この規模は近年の研究が扱う範囲の下限に位置する。既存の求解器を明確に上回るかは検証を要するが、推論が一回の順伝播で終わるため、後述の(c)の内側で何万回も呼ぶ用途では決定的に有利である

(b) 近傍選択。 大規模近傍探索において、どの拠点群を破壊・再構築すれば改善が見込めるかを予測する。求解器を置き換えず内側に差し込めるため導入が容易で、標本要求も緩い。

(c) 訪問間隔と割付の方策。 ここが本質的に重要である。第4節の閉形式は、各拠点を独立に扱っている。しかし現実には経路費用が拠点を結合する——隣接する拠点は「ついでに」回れば限界費用がほぼゼロであり、単独で最適な間隔とは異なる間隔で回るほうが全体では安い。

間隔と経路を同時に決める問題は在庫配送問題として知られ、閉形式は存在しない。逐次的な意思決定であり、状態(各拠点の蓄積量)が確率的に遷移し、行動(今日どこへ行くか)が将来の状態を変える。これは強化学習が本来対象とする構造そのものである。第4節の閉形式は、この結合を無視する分解ヒューリスティクスとして位置づけられる——実用上は良い近似だが、上限ではない。

閉形式と方策学習の関係

閉形式(4.2)と学習された方策は競合しない。閉形式は方策の初期値であり、比較対象であり、安全網である。学習された方策が閉形式を上回らないなら採用しない。上回るとしても、その差が結合の効果——「ついでに回る」ことによる節約——として説明できるかを確認する。説明できない改善は、シミュレータの欠陥を突いている可能性が高い

12.5学習の設計と計算量

報酬は図3の目的関数をそのまま用いる。報酬設計に恣意性が入らない点は、この問題の際立った利点である——多くの応用では報酬の定義自体が難題だが、ここでは走行時間・時間枠違反・積載超過・平準化がすべて明示的に計算できる。

学習は方策勾配法による。同一インスタンスから複数の軌跡を生成し、その平均を基準値として用いれば、価値関数を別に学習せずに分散を抑えられる。訪問数の小さいインスタンスから開始し、実規模へ段階的に広げる。

項目概算
1インスタンスの順伝播+逆伝播108 FLOP 規模
符号化 O(n2d) × 層数、n は日次の訪問数
学習全体(105 反復 × バッチ 1021015〜1016 FLOP
実時間数時間〜1日
復号が逐次的で演算装置の利用率が上がらないため、理論値より大きく見積もる
必要な計算資源単一の高性能GPU で十分

この規模は、第13節で述べる階層ベイズと同程度である。本稿の問題群において、演算加速を要する処理は統計推論と方策学習の二つであり、いずれも数時間から一日の水準に収まる。分散環境を要する規模ではない。

12.6シミュレータを信じないための検証

生成した世界で学んだ方策が現実で機能する保証はない。検証は三段で行う。

  1. 生成器の妥当性検定。 生成した日の統計量——訪問数、総発生量、稼働時間、時間枠違反率の分布——が、実績の分布と整合するかを検定する。生成器が現実の日を再現できないなら、その上で学んだ方策を論じる意味はない。ここが最初の関門である。
  2. 実績日でのリプレイ。 生成器を通さず、実際にあった日の訪問集合と制約を入力として方策を走らせ、実績と比較する(第14節)。このとき拠点を保留した分割で行う(9.4)——保留拠点での性能が、新規顧客に対する性能の推定値になる。学習した方策が閉形式および較正済み求解器を上回るかを、この土俵で判定する。
  3. 運用後の閉ループ照合。 溢れ発生率の実測が設計値と整合するか(第14節)。シミュレータの欠陥は最終的にここで露見する。

12.7学習させない部分

すべてを学習に委ねる必要はない。厳密に計算できるものは厳密に計算する。距離、時間枠違反量、積載超過量は式で求まり、その計算は数個の加減算で終わる。これらを近似する模型は、置き換える算術より遅く、かつ不正確である。

学習が担うのは二つに限られる。方策——どの順で回るか、今日どこへ行くか——と、書き下せない選好——図3の第六項が単一のスカラーで代理していた、乗務員の暗黙知である。探索と評価の厳密な部分を保ったまま、書けない部分だけを学習する。これは学習済み評価関数を採用した探索エンジンが辿った分業と同じ構造である。

第IV部

実装と運用

三つの問題を一つの系として動かすために必要な事柄。

13計算資源の配置

前節は「どのアルゴリズムを使うか」を論じた。本節は「どの計算機に載せるか」を論じる。とりわけ、汎用GPUによる並列演算が有効な処理と無効な処理を判別する。結論を先に述べれば、本稿の最適化パイプラインにおいて、GPUが効くのは統計推論とシミュレーションであって、最適化そのものではない

13.1まず桁を見積もる

加速の検討は、対象の計算量が何桁かを確認することから始めるべきである。この問題群の主要な計算は、拠点数 n、実績件数 R、特徴量数 F で概ね記述できる。

距離・所要時間行列:   n2 要素  (倍精度で 8n2 バイト)
基準間隔の閉形式:   O(n)  — 拠点ごとに定数回の演算
一般化線形モデル(IRLS t 反復):   O(t · R · F2) FLOP
階層ベイズ(NUTS):   O(chains · samples · L · R · P) FLOP
モンテカルロ方策評価:   O(n · S · D) 状態更新
重み較正ループ:   O(trials · D · Tsolve) 秒
図17主要な計算の規模。P は推定パラメータ数、L は1サンプルあたりの leapfrog ステップ数、S はシナリオ数、D は日数、Tsolve は1日分の求解時間。指数の位置が異なることに注意——FP は二乗ないし線形で効き、R は線形で効く。どの変数が伸びるかで、ボトルネックの所在が移動する。

ここで決定的なのは、拠点数 n は事業規模に対してほとんど伸びないという事実である。数百から数千の範囲に収まり、距離行列は倍精度でも数MBから数十MBにすぎない。これは現代のCPUのキャッシュ階層で扱える大きさであり、行列そのものの大きさが加速の理由になることはない。伸びるのは実績件数 R であり、時間とともに線形に増える。

13.2二つの規模での比較

規模によって答えが変わるため、二つの水準で比較する。小規模は実績 R ~ 103、拠点 n ~ 102。中規模は乗務員20名・3年程度の蓄積を想定し、R ~ 3×105n ~ 103、拠点あたり観測数 k ~ 300 とする。

処理小規模 R~10³中規模 R~3×10⁵GPUの要否
基準間隔の閉形式 マイクロ秒 マイクロ秒 不要(規模に依存しない)
一般化線形モデル ~10-2 GFLOP ~102 GFLOP/数秒 不要。数秒が0.1秒になっても意思決定は変わらない
階層ベイズ MCMC 秒〜分 ~1015 FLOP/CPUで十数時間 必須級。GPU実装で分単位に落ちる
モンテカルロ方策評価 入力分布の推定誤差が支配的で意味が薄い 1010 規模の状態更新 。完全に並列で、GPUの典型的な適用対象
方策の学習(第12節) 生成器の較正が先に必要 1015〜1016 FLOP/数時間〜1日 。深層学習の訓練そのもの
配送計画の求解 1日あたり数十秒 不適(下記 13.3)
重み較正ループ 時間単位 103 CPU時間規模 不適。CPUコア数と枝刈りが効く

この表から二つのことが読み取れる。第一に、規模を上げても最大の計算負荷は依然としてGPUの問題ではない。重み較正ループは trials × D 回の求解を要し、中規模では103 CPU時間の水準に達するが、これは試行間・日ごとが独立な粗粒度並列であり、加速手段はコア数・ノード数・枝刈りである。

第二に、質的に変化するのは階層ベイズと方策学習である。前者から述べる。拠点あたり観測数 k が30〜50を超えると、7.3節の条件1により拠点別の係数が推定可能になる。すると推定パラメータ数 P が拠点数に比例して増え、勾配評価が R × P のオーダーになる。統計的により正しいモデルを選べるようになった瞬間に、計算量が跳ね上がる——ここが演算加速の出番である。方策学習(第12節)も同じ帯域にあり、こちらは規模によらず訓練そのものが並列演算を要する。ただし両者とも数時間から一日の水準に収まり、単一の高性能GPUを超える設備は要らない

計算資源が可能にするのは、速度ではなく手法の選択

階層ベイズがCPUで十数時間かかるなら、モデルの試行錯誤は事実上できない。一日に一度しか回せないものは、設計の道具にならない。これが分単位に落ちれば、事前分布の検討・モデル比較・診断を反復できる。演算加速の価値は「同じ答えを速く得ること」ではなく、「点推定で妥協せず、不確実性を伝播させた正しい推論を実務の反復速度で回せること」にある。

13.3GPUが効く処理・効かない処理の判別

個別の事例に当たる前に、判別の原則を述べる。GPUは同一の演算を大量の独立したデータへ一斉に適用する構造でのみ性能を発揮する。したがって次の三条件がそろう必要がある。

この三条件に照らせば、配送計画の求解がGPUに向かない理由は明白である。分枝限定と制約伝播は本質的に分岐が多く、逐次的で、メモリアクセスが不規則である。探索木の各ノードで異なる制約が発火し、異なる枝が刈られる。これはGPUが最も苦手とする形であり、実用的な求解器がCPUベースであるのは実装上の都合ではなく問題の構造による。

ただし、規模が上がると一つだけ検討に値する例外が現れる。大規模近傍探索における候補手の一括評価である。1日あたりの訪問数を M とすると、2-opt 近傍の候補は O(M2) 個あり、各候補の改善量は独立に O(1) で計算できる。M が数百に達すればこれは数万件の独立な評価となり、データ並列性の条件を満たす。既存の求解器を上回るかは実証を要するが、「明確に不適」から「実験に値する」へ位置づけが変わる

13.4周辺処理

最適化パイプラインの外側の処理は、演算資源を規定しない。入力が構造化された系では、自由記述の解釈や表記ゆれの突合といった処理そのものが発生しない。大量処理が生じるのは既存帳票からデータを起こす移行期のみであり、一度きりの作業は定常状態の設備を規定する根拠にならない

13.5本節の結論

  1. 行列の大きさは加速の理由にならない。 拠点数は事業規模に対して伸びず、距離行列は数MB規模にとどまる。
  2. 最大の計算負荷は粗粒度並列である。 重み較正ループはCPUコア数・ノード数・枝刈りで対処する問題であり、GPUは寄与しない。
  3. 組合せ探索は規模によらずGPUに向かない。 ただし大規模近傍の一括評価は、規模が上がれば実験に値する。
  4. 質的に変化するのは統計推論と方策学習である。 前者は拠点別係数が識別可能になる規模で計算量が跳ね上がる。後者は生成器さえ較正できれば規模によらず訓練を要する。いずれも単一の高性能GPUで数時間から一日の水準に収まる
  5. 周辺処理は演算資源を規定しない。 大量処理が生じるのは移行期の一度きりである。

この節の含意は、第6節の原則の系である。道具から問題を選ばないという原則は、アルゴリズムだけでなく計算機にも当てはまる。演算資源があるから最適化を重くするのではなく、問題の構造が要求する計算に資源を割り当てる。

14評価と監視

配車最適化は本番投入前の検証が難しい。実際に走らせてみるまで真の所要時間が分からないためである。したがって、過去実績に対するオフライン再現(リプレイ)を主たる評価手段とする。

評価は1.3の二軸に分けて行う。推定の評価は、蓄積速度と調整係数がどれだけ現実を再現するかを、素朴なベースラインとの差で測る(8.4)。決定の評価は、それらを入力として生成した計画が、実績と比べてどうかを測る。両者を混ぜてはならない——推定が正確でも決定が悪いことはあり、その逆もある。以下は決定の評価を扱う。

手続きは次のとおりである。実績のある期間を時系列で分割し、前半で重みを較正し、後半で評価する。後半の各日について、その日の訪問拠点集合と車両制約を入力としてソルバに巡回路を生成させ、実績と比較する。

指標意味望ましい方向
順序一致度(τ)生成した順序が実績とどれだけ一致するか較正の妥当性として高い方が良い
到着時刻MAE予測到着時刻と実績の平均絶対誤差小さいほど所要時間モデルが正確
推定総移動時間生成案の総移動時間実績より小さければ改善余地
時間枠違反率制約を破る拠点の割合ゼロに近いこと
作業時間のジニ係数ドライバー間の負荷の偏り小さいほど平準化

加えて、要素の寄与を切り分けるアブレーションを行う。(a)重みを手で決めた場合と較正した場合、(b)実効日数による調整を有効化した場合と無効化した場合、(c)第六項(実走順の尊重)の有無。それぞれで上記指標を比較する。これにより、どの要素が実際に効いているかを定量化できる。

評価上の落とし穴

順序一致度が高いことは、必ずしも良い最適化を意味しない。w6 を極端に大きく取れば一致度は上がるが、それは実績をなぞっているだけで改善は生まない。順序一致度は較正の妥当性検証に用い、改善効果の指標としては用いない。改善は総移動時間と平準化指標で測る。

設計上の限界は、散文の但し書きとして書き残しても機能しない。読まれず、更新されず、実際にその限界に触れたときに誰も気づかないからである。限界は計算可能な量として定義し、閾値を決め、超えたときに系が何をするかまで書いて初めて設計に組み込まれる。本節は各限界について〈計量・閾値・フィードバック先〉の三つ組を与える。

整理は1.3の二軸に従う。推定側の限界は入力パラメータの信頼性に、決定側の限界は解の妥当性に関わる。そして両者を繋ぐ閉ループが一つ存在し、これが系全体の健全性を担保する。

14.1推定側の限界

標本の偏り。 実績の記録は一部の乗務員・一部のコースから始まるため、初期の標本は特定地区に偏る。この偏りは「注意する」ものではなく測るものである。計量は拠点ごとの観測数 ki と、そこから定まる標準誤差 SE(λ̂i) = σ̂i/√(Σgk) である。フィードバックは二経路ある。第一に、7.2の縮小推定の重み wi が SE の関数として定義されているため、偏りは自動的に推定へ織り込まれる。第二に、SE の大きい拠点を次の観測対象として優先する——これは能動的な標本設計であり、偏りの是正をループに戻す唯一の手段である。

識別可能性の欠如。 観測期間が短ければ、気温の係数は季節に伴う他の変化と分離できない(7.3)。これも計量できる。説明変数間の相関行列、あるいは分散拡大係数を計算し、閾値を超える変数群は係数を推定せずモデルから落とす。人間が「交絡に注意する」のではなく、共線性の指標が自動的に変数を除外する構成にする。除外された変数は、期間が伸びて共線性が下がった時点で自動的に復帰する。

打ち切り。 容器容量に達した観測は真の発生量ではない(4.1)。計量は拠点ごとの最大値張り付き率——観測のうち当該拠点の最大値と一致するものの割合である。閾値を超えた拠点は λ̂i を下限値として扱い、閉形式が返す Ti* を短縮側へ丸める。打ち切りの検出そのものが、間隔の安全側への補正として作用する

14.2決定側の限界

残差が未検証な区間への依存。 任意の拠点対の所要時間は地図サービスから得られるため、行列に穴は空かない(2.3)。残る不確実性は、地図サービスの値と自社の実所要時間との残差——その区間や拠点に固有の事情——であり、これは実際に走った区間でしか検証されていない。したがって計量すべきは「観測済みか」ではなく残差の検証済み度である。提案経路が使う区間のうち、残差が実績で確認されている割合を測る。

検証済み度解釈フィードバック
実所要時間が確認済みの区間で構成そのまま提示できる
一部が地図サービスの値のみに依存当該区間を明示し、残差分布の幅を所要時間の不確実性として併記する
提案の大半が未検証の残差に依存残差の事前分布を広く取って再求解する、または当該区間を試走して残差を確認する

最後の行が重要である。未検証の区間は制約であると同時に、次に何を観測すべきかの指示でもある。有望に見えるが未検証の区間を意図的に走らせて残差を得れば、以降の推定精度が上がる。限界を静的な制約として受け入れるか、能動的に解消していくかの分岐点がここにある。なお12.3の領域ランダム化は、この不確実性を方策の学習段階で扱う対応物である——残差の事後分布から抽出して学習すれば、未検証区間に対して自動的に保守的な方策が得られる。

最適性ギャップ。 求解は時間制限つきで打ち切られるため、返る解は最適とは限らない。混合整数計画・制約プログラミングのソルバは残余ギャップ——現在の解と下界の隔たり——を返す。これを記録し、ギャップが常態的に大きいなら制限時間を延ばすか定式化を見直す。「最適化した」と称しながらギャップを記録していない実装は、何を達成したか主張できない

14.3二つの問題を繋ぐ閉ループ

ここまでの計量は、それぞれの問題の内部で完結している。しかし系全体の健全性を測る指標は、推定と決定の境界をまたいだところにある

閉形式(4.2)は、溢れ確率が α 以下になるよう間隔を定めた。この α は設計値である。運用を開始すれば、実際の溢れ発生率が観測される。両者を比較することが、系全体に対する唯一の実地検証である

設計値: α   (4.2 で与えた許容溢れ確率)
実測値: α̂ = (溢れ観測回数) ⁄ (訪問回数)

α̂ ≫ α  ⟹  λ または σ の過小推定  推定側へ差し戻す
α̂ ≪ α  ⟹  過剰訪問  間隔を延ばす余地がある
図18推定と決定を繋ぐ閉ループ。溢れ発生率は決定の結果として観測され、推定の誤りを指し示す。この一つの量が、二つの問題を接続する。実測が設計を大きく上回るなら、それは間隔の決め方の問題ではなく蓄積速度の推定の問題であり、打ち切りの見落とし(7.2)を疑うのが定石である。

乖離度の三成分による切り分け。 同様の切り分けは重み較正にも組み込まれている。5.3の乖離度を集合差・順序差・時刻差の三成分に分けたのは、どちらの問題に原因があるかを判別するためである。時刻差だけが突出して大きければ、それは重みの問題ではなく所要時間行列の推定精度の問題であり、修正すべきは決定側ではなく推定側である。指標を分解しておくことが、そのまま原因の切り分けになる

自己成就の遮断。 予測に基づいて訪問頻度を下げると、その拠点の観測が減り、推定を更新する材料が失われる(8.5)。計量は、頻度を変更した拠点群の観測数の推移である。これが減少し続ける場合、一定割合の訪問を予測にかかわらず従来頻度で実施し、観測を確保する。予測を運用判断に使う系は、必ず予測に反する観測を意図的に残さなければならない

14.4監視量の一覧

監視量計算属する問題フィードバック先
SE(λ̂i)σ̂i/√(Σgk)推定縮小重み wi/観測の優先順位
共線性指標説明変数の相関・分散拡大係数推定変数の自動除外と復帰
最大値張り付き率最大値と一致する観測の割合推定λ̂ を下限扱い/T* の短縮
残差の検証済み度残差確認済み区間 ⁄ 提案が使う区間決定残差事前分布の拡大/試走の指示
残余ギャップソルバの上界と下界の差決定制限時間・定式化の見直し
溢れ発生率 α̂溢れ回数 ⁄ 訪問回数両者を接続推定パラメータの再推定
乖離度の三成分集合差・順序差・時刻差(5.3)両者を接続原因が推定側か決定側かの判別
変更拠点の観測数推移頻度変更前後の観測件数両者を接続探索的訪問の割合

この表が本節の成果物である。各行は計算可能であり、閾値を持ち、行き先を持つ。限界とは、監視されていない量のことである。計量してループに戻した時点で、それは限界ではなく制御量になる。

15段階的導入

本設計は、データの成熟度に応じた段階を踏む。各段階を飛ばすと、後段が成立しない。

段階やること先行条件
0. 記録粒度の確保 実績へのコース識別子の記録、品目マスタの整備、スポット区分、その場送信の運用周知 なし。最優先。この段階を怠った期間のデータは後から復元できない
1. 派生層の構築 所要時間行列・作業時間分布の生成。蓄積速度 λ・σ の推定と基準間隔 T* の算出(実績のみで可能)。気象・祝日暦の取得基盤の構築と過去分の遡及付与。記述的レポートの提供 段階0の実績が数百件
2. 重みの較正 実効日数の係数 β の推定。週次パターン割付の求解。目的関数の重みのオフライン較正とパレート境界の取得 複数コース・複数ドライバーの実績が二〜三か月分
3. 提案生成 コース組み替え案の生成と説明。採否は人間が判断 段階2の較正が評価に耐えること
4. 部分自動化 日次の割当補助、欠員時の再計画支援 段階3の提案が継続的に採用されていること

段階1で得られる記述的レポート——予定と実績の消化率、区間所要時間、拠点別の発生量——は、最適化に到達する前であっても実務価値がある。むしろ、この段階のレポートを配車担当者が日常的に見る状態を作ることが、後段の提案を受け入れてもらうための最良の準備になる

16結論

本稿は、定期巡回型回収業務における配車最適化を、データモデル・定式化・解法・評価の四面から設計した。主要な主張を再掲する。

  1. データモデルが成否を決める。 計画と実績を分離し、実績にコース識別子を残し、派生層を明示的に置く。記録されなかったデータは後から復元できないため、記録粒度の確保は他のあらゆる機能追加に優先する。
  2. 計画表の順序を制約にしてはならない。 実測された順位相関は、計画表の順序が実態から乖離していることを示す。実走順こそが、明文化されていない知識を含む信号である。
  3. 目的関数の重みは実績から較正する。 ブラックボックス最適化の最も価値ある適用先は、巡回路の探索ではなく、この逆問題である。多目的化すれば、単一の推奨案ではなく選択肢の連続体を実務者に提示できる。
  4. 移動時間は外部の地図サービスから得られる。 実績が担うのは絶対値の推定ではなく、地図サービスの値と実所要時間との残差の学習である。その残差もまた区間識別子ではなく区間の特徴から予測する——そうして初めて、走ったことのない土地の区間にも適用できる。
  5. 計算資源の配置も、問題の構造から決まる。 行列の大きさは加速の理由にならず、組合せ探索は規模によらず並列演算装置に向かない。質的に変化するのは統計推論であり、拠点別の係数が識別可能になる規模で階層ベイズの計算量が跳ね上がる。演算加速の価値は速度ではなく、点推定で妥協せずに不確実性を伝播させた推論を、実務の反復速度で回せるようになることにある。
  6. 閉形式は上限ではない。 拠点を独立に扱う閉形式は、経路費用による拠点間の結合を無視している。間隔と経路を同時に決める問題に閉形式はなく、そこは生成器で事例を供給した方策学習の対象になる。実績が足りないことは学習の障害ではない——局面は生成できる
  7. 目的は既存地域への適合ではなく、新規地域への転移である。 模型の入力から拠点識別子・絶対座標・月ダミーといったマップ固有の量を排し、相対幾何・業態属性・気温といった不変量に置き換える。そのうえで多様なマップを生成して学習すれば、実績のない土地でも初日から間隔と経路が決まる。生成の価値は事例数ではなく、経験していない土地の空間統計を作れることにある。この目的を採るなら、検証は日でも拠点でもなく地域を丸ごと保留して行わなければならない。
  8. 限界は但し書きではなく監視量として定義する。 標本の偏りは標準誤差として、識別可能性は共線性指標として、打ち切りは張り付き率として、未観測区間への依存は被覆率として計算できる。そして溢れ発生率の実測と設計値の差が、推定と決定を繋ぐ唯一の閉ループを成す。計量して行き先を決めた時点で、限界は制御量になる。

最後に、方法論上の一点を付言する。本稿が挙げた設計上の要点の多くは、仕様書やコードからは導けない種類のものである。計画順序と実走順序の乖離、担当交代の常態性、記録粒度の不足が生む情報の逃避——いずれも、実績を集計して初めて可視化される。設計の妥当性は、業務の記述ではなく実績の分布によって検証される。最適化の設計に着手する前に、まず実績を取り、その分布を眺めることに尽きる。