タクシー会社の乗車記録から翌日の時間帯・エリアごとの乗車の需要を予測し、乗務員の出庫の枠と待機場所の案を出す
乗車記録と配車の依頼の記録から、翌日の1時間ごと・エリアごとの乗車の件数を幅で見込みます。それを、乗務員の出庫の枠の割り当てと、時間帯ごとの待機場所の案に直して、前日の夕方に運行管理者へ渡します。
- 連携・自動化
- Python
- 対象業界
- その他/物流
- 対象部門
- 営業
- 対象業務
- 比較検討/集計・分析
- 主な課題
- データ分析に時間がかかる/判断に時間がかかる/属人化している
- AIで行う処理
- 予測
- 主な効果
- 判断支援/属人化解消/機会損失防止
- 導入難易度
- ★★★★☆
- 実装レベル
- 本格構成
- 費用感
- 個別開発(大)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 運行管理者が、翌日の勤務表で出勤する乗務員の一覧を見る
- 翌日の曜日・天気予報・地域の催しを調べる
- 去年と先週の同じ曜日の乗車件数を、メーターの記録の集計から時間帯別に拾う
- 時間帯ごとに何台要るかを見当を付け、早番・通常・遅番に乗務員を割り振る
- 割り振った乗務員の前日の終業時刻を勤務の実績で確かめ、早番に入れられるかを見る
- 主な待機場所(駅の乗り場、病院、繁華街)の時間帯ごとの台数の目安を書き、配車センターに渡す
- 自動毎日15時、配車システムとメーターの記録から前日までの乗車と配車の依頼を書き出す
- 自動Python が、1時間ごと・エリアごとに乗車件数と応えられなかった依頼の件数を集計する
- 自動翌日の天気予報と、催しの表、暦を特徴に加える
- 自動モデルが、翌日の1時間ごと・エリアごとの需要を中央の値と上側の値で見込む
- 自動見込みを時間帯ごとの必要台数に直し、出庫の枠ごとの台数の案を出す
- 自動勤務の実績から休息期間を計算し、早番の枠に入れられない乗務員を候補から外して、枠の割り当ての案を作る
- 自動時間帯ごとの待機場所の台数の案を出す
- 人運行管理者が案を見て、割り当てと待機場所を決め、勤務の指示に反映する
- 自動翌日が過ぎたら、見込みと実際の乗車・応えられなかった依頼の件数を突き合わせて記録する
各工程の詳しい説明を読む
- 運行管理者が、翌日の勤務表で出勤する乗務員の一覧を見る
- 翌日の曜日・天気予報・地域の催しを調べる
- 去年と先週の同じ曜日の乗車件数を、メーターの記録の集計から時間帯別に拾う
- 時間帯ごとに何台要るかを見当を付け、早番・通常・遅番に乗務員を割り振る
- 割り振った乗務員の前日の終業時刻を勤務の実績で確かめ、早番に入れられるかを見る
- 主な待機場所(駅の乗り場、病院、繁華街)の時間帯ごとの台数の目安を書き、配車センターに渡す
(a)見ている数字が需要ではない。 3番目で拾うのは乗車件数です。車が足りずに配車の依頼を断った時間帯は、乗車件数が少なく残っています。 その数字で翌年の配置を決めると、足りなかった時間帯にまた車が足りません。
(b)担当者でないと決められない。 「月末の金曜の22時台は繁華街に10台」「雨の朝は駅と病院」といった経験則があり、運行管理者が休んだ日は、前の週と同じ割り振りが使われます。
(c)休息期間の確かめが手作業。 5番目で、早番に入れる乗務員の前日の終業時刻を1人ずつ確かめます。急いでいる日ほど見落としやすく、見落とせば改善基準告示の休息期間を割ることになります。
(d)天気と催しの見当が人によって違う。 雨の予報でどれだけ増えるかは、運行管理者ごとに見方が違います。同じ雨の日でも、営業所によって早番の台数が倍違う、ということが起きます。 どちらが正しかったかを後から確かめる記録も残っていないので、見方がそろっていきません。
- 【自動】 毎日15時、配車システムとメーターの記録から前日までの乗車と配車の依頼を書き出す
- 【自動】 Python が、1時間ごと・エリアごとに乗車件数と応えられなかった依頼の件数を集計する
- 【自動】 翌日の天気予報と、催しの表、暦を特徴に加える
- 【自動】 モデルが、翌日の1時間ごと・エリアごとの需要を中央の値と上側の値で見込む
- 【自動】 見込みを時間帯ごとの必要台数に直し、出庫の枠ごとの台数の案を出す
- 【自動】 勤務の実績から休息期間を計算し、早番の枠に入れられない乗務員を候補から外して、枠の割り当ての案を作る
- 【自動】 時間帯ごとの待機場所の台数の案を出す
- 【人】 運行管理者が案を見て、割り当てと待機場所を決め、勤務の指示に反映する
- 【自動】 翌日が過ぎたら、見込みと実際の乗車・応えられなかった依頼の件数を突き合わせて記録する
8番目が、この設計の分かれ目です。 案は出しますが、乗務員への指示は運行管理者が出します。 乗務員の体調や希望、新人に任せないエリア、車両の整備の予定は、記録に載っていないからです。
6番目で休息期間を機械で確かめるのも、意図してのことです。 案に載った乗務員が休息期間を割るなら、その案は使えません。候補から外した理由を一覧に出し、運行管理者が見落としに気づけるようにします。
02今回想定するシステム構成
配車システム(配車の依頼・配車の結果)/メーターの運行の記録(乗車の時刻と位置) │ 毎日15時に前日までを書き出し ▼【トリガー】定時実行 Python(pandas) ├──▶ 乗車の位置をエリアに当てはめ、1時間ごとに集計 ├──▶ 応えられなかった依頼を足して需要に近づける ▼ scikit-learn(HistGradientBoostingRegressor:poisson と quantile) │ 翌日の1時間ごと・エリアごとの需要(中央の値と上側の値) ▼ Python ── 必要台数への換算/出庫の枠の台数/休息期間の確認/待機場所の案 ▼ 翌日の配置の案(営業所ごとの一覧) ▼ 【運行管理者が確かめて決め、勤務の指示に反映】
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Python(pandas・scikit-learn の HistGradientBoostingRegressor) | R、BigQuery ML、LightGBM |
| データの取得元 | 配車システムとメーターの記録の書き出し | 配車システムのAPI(提供されている場合) |
| 一覧の出力先 | 営業所の共有フォルダの一覧(営業所別のシート) | 社内のダッシュボード |
| 定時実行 | 社内のジョブ管理の仕組み | OSのタスクスケジューラ |
生成AIは使いません。 この構成で行うのは、記録から件数を見込み、台数と割り当てに直す計算です。乗車の位置と時刻の記録を、外部の生成AIに渡す場面を最初から作りません。
配車システムと勤務表には書き込みません。 案は運行管理者が決めるための材料で、指示はいまと同じく運行管理者が出します。
モデルに HistGradientBoostingRegressor を選ぶのは、件数の見込みに向いた損失を選べるからです。 loss に poisson を指定すると、0以上の件数をそのまま扱えます。深夜の住宅地のように0件の多い時間帯があるこの題材では、二乗の誤差より合います。同じモデルを loss="quantile" と quantile=0.9 で学ばせれば、「多めに見て何件か」という上側の値も出せます。
欠けた値とカテゴリの列もそのまま入ります。 公式の説明では、学ばせるときに分かれ目ごとに欠けた値を左右どちらへ送るかを学ぶとされ、categorical_features の既定は "from_dtype" です。エリア、曜日、天気の区分をカテゴリの型にして渡します。 カテゴリの数は max_bins(255以下)以内である必要があり、24のエリアなら収まります。
03どうやって実装するのか
処理の起点を決める
毎日15時の定時実行を起点にします。 翌日の天気予報が出そろい、運行管理者が夕方に翌日の指示を作る前に一覧ができている時刻です。当日の朝に作る形にはしません。 早番の乗務員には前日のうちに出庫の時刻を伝える必要があるからです。
作るのは翌日の1日分だけです。 1週間分をまとめて作ると、天気予報の外れが大きい日の案が混ざります。週の見通しが欲しいときは、別に中央の値だけを参考として出します。
モデルの学び直しは月に1回です。 毎月1日に直近24か月で学ばせ直し、前のモデルより当たっているかを確かめてから入れ替えます。 当たり方が悪くなっていれば、前のモデルを使い続けて運行管理者に知らせます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 乗車の記録 | 乗車の時刻、乗車の位置、営業所、車両番号 | メーターの運行の記録 |
| 配車の依頼 | 依頼の時刻、迎えの位置、受付の経路(アプリ・電話)、配車できたか | 配車システム |
| エリアの区分 | 位置からエリアへの対応(24エリア) | 営業所で作る表 |
| 暦 | 曜日、祝日、連休、月末、給料日、学校の休み | 営業所で作る表 |
| 催し | 会場、開始と終了の時刻、見込みの来場者の規模 | 営業所で作る表 |
| 天気 | 1時間ごとの降水の有無と量の予報、気温 | 契約している気象情報の提供元 |
| 勤務 | 翌日の出勤者、勤務の種類、前日の終業時刻 | 勤務表と勤務の実績 |
質を決めるのは、配車の依頼の「配車できたか」の列です。 この列があれば、応えられなかった依頼の件数を時間帯とエリアで数えられます。無ければ、車が足りなかった時間帯の需要を知る手がかりがありません。 書き始める前に、配車システムが断った依頼を記録しているかを確かめてください。
催しの表は営業所が作ります。 会場の終演の時刻は、乗車の記録からは分かりません。ここに載っていない催しの日は、モデルが普段と同じ傾向で見込みます。
読まない列も決めておきます。 配車アプリの利用者のID、電話番号、降車の位置は書き出しの段階で外します。見込みに要るのは、時刻とエリアの件数だけです。
データの取得方法を決める
配車システムとメーターの記録から、前日までの乗車と配車の依頼をそれぞれ書き出します。 項目と形式は製品ごとに違うので、最初に書き出しの列を決めて固定します。毎日の処理の最初に、列の名前と数が決めたとおりかを照らし、違えばそこで止めます。 配車システムの更新で列が1つずれただけで、エリアの件数がすべて別のエリアに入るからです。
メーターの記録に乗車の位置が残らない車両がある場合は、その車両の乗車を「位置なし」として数え、営業所の時間帯の合計にだけ入れます。 エリア別の件数には入れられませんが、枠の割り当てに使う合計は正しくなります。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 乗車の時刻と位置 | メーターの記録 | エリア・1時間ごとの乗車件数 |
| 応えられなかった依頼 | 配車システム | 需要に近づけるための上乗せ |
| 前日の終業時刻 | 勤務の実績 | 休息期間の確認 |
| 翌日の出勤者 | 勤務表 | 枠の割り当ての候補 |
| 翌日の予報 | 気象情報の提供元 | 天気の特徴 |
学ばせるときの答えは、「乗車件数 + 応えられなかった依頼の件数」にします。 応えられなかった依頼は、同じ客が何度も依頼し直していることがあるので、同じ迎えの位置から10分以内に続いた依頼は1件にまとめます。 流しの客の取りこぼしは記録に残らないので、この答えも需要の下限だと割り切ります。
AIへ渡す前に整形する
- エリアへの当てはめ … 乗車と迎えの位置を、エリアの区分の表で24エリアに当てはめます。区域の外の位置は「区域外」にまとめます
- 1時間ごとの集計 … エリア × 1時間ごとに、乗車件数と応えられなかった依頼の件数を数えます。件数が0の時間帯も行として作ります
- 依頼のまとめ … 同じ位置から10分以内に続いた依頼を1件にします
- ずらした特徴 … 1週間前・2週間前・前年の同じ曜日の同じ時間帯の件数を列にします
- 天気の区分 … 降水量を「なし・弱い・強い」の3つに束ね、カテゴリの型にします
- 異常な日の印 … 大きな事故や災害で営業が止まった日は、学ばせる記録から外します
学ばせる記録の1行は、次のような形にします。1行が「ある営業所の、あるエリアの、ある日の1時間」です。 24エリア × 24時間 × 365日で、1営業所あたり年に約21万行になります。
{
"office": "north",
"area": "station_east",
"date": "2026-09-18",
"hour": 22,
"weekday": "fri",
"holiday_flag": "eve_of_holiday",
"month_end": true,
"rain_class": "light",
"temp_c": 19.5,
"event_end_nearby": true,
"lag_7d": 14,
"lag_14d": 11,
"lag_364d": 9,
"rides": 17,
"unserved_requests": 6,
"target": 23
}
rides と unserved_requests は答えを作るための列で、特徴には入れません。 特徴に入れるのは、翌日の15時の時点で分かる列だけです。lag_364d は前年の同じ曜日に合わせた値で、暦の日付ではなく曜日をそろえて引きます。 祝日の前の金曜と普通の金曜は、holiday_flag で分けます。
2番目の「0件の行を作る」を省くと、見込みが多めにずれます。 乗車が無かった時間帯の行が無いと、モデルは「件数がある時間帯」だけから学びます。深夜の住宅地のような時間帯こそ、0件の行が要ります。
4番目で「1日前」を使わないのは、15時の時点で前日の深夜の記録が出そろっていないことがあるからです。 予測の時点で手に入らない値を特徴に入れると、検証では当たるのに本番では当たらないモデルになります。
AIに処理させる
させるのは、翌日の1時間ごと・エリアごとの需要の件数を、中央の値と上側の値で見込むことだけです。 台数への換算、枠の割り当て、休息期間の確認は、見込みを受け取った後の Python の側で行います。
| 見るもの | 扱い方 | 判断できないときの扱い |
|---|---|---|
| エリアと時間帯 | カテゴリの型 | 区域外は別の行 |
| 曜日・祝日・月末 | 暦の表から | 暦に無い日は平日扱い |
| 天気 | 予報の3つの区分と気温 | 予報が取れなければ欠けた値 |
| 催し | 会場のエリアと終演の時刻の前後 | 表に無ければ催し無し |
| 過去の件数 | 1週間前・2週間前・前年 | 記録が無ければ欠けた値 |
見込みは2つ出します。 loss="poisson" のモデルで中央の見込み、loss="quantile" で quantile=0.9 のモデルで上側の見込みです。台数は中央の値で決め、上側の値は「足りなくなりそうな時間帯」に印を付けるのに使います。
台数への換算は、決まった式で行います。
必要台数(時間帯 t)= Σ エリア の 中央の見込み ÷ 1台が1時間に運べる件数(営業所の実績)
不足の印 = Σ エリア の 上側の見込み ÷ 1台が1時間に運べる件数 > その時間帯の稼働台数
出庫の枠の台数 = 早番・通常・遅番の組み合わせのうち、
各時間帯の稼働台数と必要台数の差の合計が最も小さいもの
| させないこと | 理由 |
|---|---|
| 出勤者の増減 | 勤務表は運行管理者と乗務員の取り決めで決まる |
| 休息期間の判断の省略 | 改善基準告示の内側で案を出す |
| 乗務員の評価 | 乗車件数の見込みは配置の材料。個人の成績に使わない |
| 催しの推測 | 営業所が表に足す |
3行目が大事です。 見込みを乗務員ごとの「取れたはずの件数」に直して成績と比べると、待機場所を指示された乗務員ほど不利になることがあります。 見込みはエリアと時間帯のもので、人のものではありません。
当たり方は、時間帯の合計とエリア別の2段で見ます。 枠の割り当てに効くのは営業所全体の時間帯ごとの合計で、待機場所の案に効くのはエリア別の件数です。エリア別の1時間の件数は小さく、ばらつきが大きいので、合計が当たっていればまず枠の案は使えます。 検証では、時間帯の合計の絶対誤差の平均と、上側の見込みを実際の件数が超えた割合(9割の分位なら1割前後が目安)を毎月の一覧に出します。超えた割合が2割を超えるようなら、上側の見込みが低すぎます。
指示内容を固定する
この構成は生成AIを使わないため、プロンプトはありません。 代わりに、学習・計算・一覧の作成を決める設定を、ひとつのファイルにまとめます。
【見込む先】
target: 乗車件数 + 応えられなかった依頼の件数(10分以内の重複は1件)
単位: 営業所 × エリア(24)× 1時間
学習期間: 前月までの24か月 検証: TimeSeriesSplit(日付の単位で4つに分け、gap で直前の1日を除く)
【モデル】
中央の見込み: HistGradientBoostingRegressor(loss="poisson")
上側の見込み: HistGradientBoostingRegressor(loss="quantile", quantile=0.9)
categorical_features: from_dtype
入れ替えの条件: 検証の期間で、前のモデルより絶対誤差の平均が小さいこと
【台数への換算】
1台が1時間に運べる件数: 営業所ごとの直近3か月の実績
出庫の枠: 早番 6:00/通常 8:00/遅番 11:00(いずれも日勤)
【休息期間の確認(改善基準告示)】
日勤: 前日の終業から継続9時間を下回る枠には入れない
(継続11時間を下回る場合は「努力の基準未満」と表示)
1日の拘束時間: 13時間を超える割り当ての案は出さない
隔日勤務: 割り当ての対象外(勤務表どおり)
【待機場所】
各時間帯で中央の見込みの多い上位5エリアに、見込みの比で台数を割る
会社が使える乗り場と待機所の一覧にある場所だけを出す
【一覧に載せる内容】
- 時間帯ごとの稼働台数の案、必要台数、不足の印
- 乗務員ごとの出庫の枠の案と、候補から外した理由
- 時間帯ごとの待機場所と台数の案
- 前日の案と、運行管理者が決めた割り当て
休息期間の基準を設定ファイルに書くのが大事です。 厚生労働省のページでは、タクシーの日勤の休息期間は継続11時間を与えるよう努めることを基本とし、9時間を下回らないものとされています。9時間は外す線、11時間は表示する線として分けて持ちます。 1日の拘束時間は13時間以内(延長しても上限15時間)とされているので、案では13時間を超える割り当てを出しません。
待機場所を「会社が使える場所の一覧」に限るのは、見込みが多いエリアでも車を止めてよい場所が決まっているからです。 一覧に無い場所を案に出すと、乗務員が路上で待つことになりかねません。
出力形式を固定する
一覧は表で出し、同じ内容を JSON でも残します。 表は運行管理者が読むため、JSON は翌日が過ぎた後の突き合わせのためです。
{
"run_at": "2026-10-14T15:00:00+09:00",
"office": "north",
"target_date": "2026-10-15",
"hourly": [
{ "hour": 7, "demand_median": 0.0, "demand_p90": 0.0,
"required_cars": 0, "planned_cars": 0, "shortage_flag": false }
],
"shift_plan": { "early": 0, "normal": 0, "late": 0 },
"assignments": [
{ "driver_id": "", "proposed_shift": "early | normal | late",
"rest_hours_before": 0.0, "excluded_from": [], "reason": "" }
],
"standby": [ { "hour": 7, "place_id": "", "cars": 0 } ],
"model_version": "",
"decided_by": "",
"decided_shift_plan": null
}
1つ目の理由は、案と決定を同じ行に残せることです。 shift_plan は計算が埋め、decided_shift_plan は運行管理者が埋めます。翌月の振り返りで、案どおりなら足りたか、運行管理者の判断でどうだったかを比べられます。
2つ目は、excluded_from と rest_hours_before で外した理由が分かることです。 早番に入れられなかった乗務員が、休息期間のためか、他の理由かを読めます。
| 列 | 運行管理者が見ること |
|---|---|
shortage_flag | 上側の見込みで足りなくなる時間帯。予備の手当てを考える |
demand_median と demand_p90 の差 | 差が大きい時間帯は天気や催しで振れやすい |
rest_hours_before | 11時間未満の乗務員は、早番にしない理由があるか |
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 配車システム | データの書き出し(読み取りのみ) | 配車の依頼と結果 |
| メーターの運行の記録 | データの書き出し(読み取りのみ) | 乗車の時刻と位置 |
| 勤務表・勤務の実績 | 読み取りのみ | 翌日の出勤者、前日の終業時刻 |
| 気象情報の提供元 | 契約に基づく取得 | 1時間ごとの予報 |
| 営業所の共有フォルダ | 一覧の書き出し | 営業所別の案 |
| 社内のチャット | 通知 | 一覧ができたこと、不足の印がある時間帯 |
配車システムへは書き込みません。 待機場所の案を配車システムに入れて自動で指示を出すと、運行管理者が乗務員の事情を見て直す余地がなくなります。
人が確認する
- 不足の印がある時間帯を見る … 予備の乗務員や、隔日勤務の乗務員の出庫の時刻で手当てできるかを考えます
- 外した乗務員の理由を見る … 休息期間で外れた乗務員を、案と違う枠に入れていないかを確かめます
- 記録に無い事情を足す … 道路の工事、新しい催し、車両の整備の予定を見て、待機場所と枠を直します
- 決めた割り当てを記録する … 案と違う割り当てにしたら、
decided_shift_planと短い理由を残します
2番目を省かないでください。 案は休息期間を守った形で出ますが、運行管理者が直すときに守れていない枠へ移すことがあります。 直した後の割り当ても、同じ計算でもう一度確かめられるようにします。一覧の表計算に「確かめ直す」のボタンを置き、直した割り当てを読み込んで同じ計算をかける形が扱いやすいです。
3番目は、営業所の運行管理者どうしで共有します。 駅前の工事で乗り場の位置が変わった、病院の外来の時間が変わった、といった情報は、どれか1つの営業所が知っていても、他の営業所の案には入りません。 催しの表と同じ場所に「エリアの変化」の欄を作り、気づいた人が書き足します。
目標は、90件をならして1件20分です。 不足の印が無く、前日と案が大きく変わらない日は数分で終わり、雨や催しの日は手当てを考えるのに時間がかかります。
例外に対処する
| 起きること | 対応 |
|---|---|
| 書き出しが15時までに届かない | 前日の一覧を「古い」と印を付けて残し、案は出さない |
| 天気予報が取れない | 天気の列を欠けた値にして見込み、一覧に「予報なし」と出す |
| 勤務の実績に前日の終業時刻が無い | その乗務員は早番の候補から外す(休息期間を確かめられない) |
| 催しの表に無い大きな催しを知った | 営業所が表に足して、もう一度計算する |
| 学び直したモデルが前より当たらない | 入れ替えず、前のモデルを使い続けて知らせる |
| 災害・大雪の予報 | 案を参考扱いにし、運行管理者が安全を優先して決める |
| 新しいエリア(新しい商業施設・病院の移転)ができた | エリアの区分の表に足し、記録がたまるまで近いエリアの傾向で見込むと一覧に書く |
| 配車システムの入れ替えで列が変わった | 書き出しの列の照合で止め、案を出さずに担当に知らせる |
| 出勤者が少なく、どの枠の組み合わせでも不足が残る | 不足の時間帯を一覧の先頭に出し、予備の手当ては運行管理者に任せる |
3行目を「外す」側に倒しているのは、誤りの向きを決めるためです。 確かめられない乗務員を早番に入れると、休息期間を割っていても気づけません。 外れて足りなくなる分は、運行管理者が手で補います。
記録を残す
- 毎日の書き出しと、1時間ごと・エリアごとの集計
- 見込み(中央の値と上側の値)と、使ったモデルの版
- 出庫の枠の案、割り当ての案、外した理由
- 運行管理者が決めた割り当てと、案と違うときの理由
- 翌日の実際の乗車件数と、応えられなかった依頼の件数
- 設定ファイルの変更の履歴(休息期間の線、出庫の枠の時刻)
4つ目と5つ目を並べて残すのが、この構成の振り返りの土台です。 3か月分たまると、見込みが外れやすい時間帯とエリア、運行管理者の判断が案より当たる場面が分かります。
04実装レベルの3段階
最小構成では、催しと天気の組み合わせが扱えません。 平均を区分ごとに出すだけなので、雨の金曜の終演の時刻のような重なりは見えません。 確かめるための段階です。 半自動化で、1件60分が35分程度になります。 集計と見比べは無くなりますが、枠への割り振りと休息期間の確認が運行管理者に残ります。本格構成で20分になり、この段階が本記事の想定です。 差が大きいのは、乗務員1人ずつの終業時刻を確かめる作業が毎日あったからです。 段階を飛ばさないでください。 半自動化の一覧を2か月見ると、見込みが外れやすいエリアと時間帯が先に分かります。
05工数削減シミュレーション
導入後 90件 × 20分 ÷ 60 = 30 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 車両が数十台から数百台あり、日勤・夜勤・隔日勤務の乗務員を複数の営業所で回しているタクシー会社。流しと駅の乗り場に加えて配車アプリや電話の配車を受けていて、配車の依頼に応えられなかった記録が残っている場合。出庫の時刻と最初に向かう場所を、運行管理者が前日の夕方に経験で決めている場合。
- 車両が数台で、乗務員の出庫の時刻も待機場所もほぼ固定の会社。乗車記録がタクシーメーターの紙の日報にしか残っておらず、乗車の時刻と場所がデータで取り出せない場合(先に日報のデータ化から始めます)。予約の送迎が中心で、流しや乗り場の需要が少ない場合。なお、勤務表の作成、拘束時間・休息期間の管理、乗務員への指示は、この構成では代替できません。
07最小構成で試す方法
- 配車システムから、過去1年分の配車の依頼と、配車できたかの記録を書き出す
- メーターの記録から、同じ期間の乗車の時刻と位置を書き出し、主な8エリアに当てはめる
- 表計算で、曜日 × 時間帯 × 雨の有無ごとに、乗車件数と応えられなかった依頼の件数の平均を出す
- 直近で車が足りなかった日を10日選び、その日の3番目の平均と、実際の稼働台数を時間帯ごとに並べる
- 平均から見た必要台数と、当日の運行管理者の割り振りを比べる
10日は必ずやってください。 モデルを作る前に、「応えられなかった依頼を足すと、足りない時間帯が見えるのか」を確かめます。 書き出した記録は、利用者のIDと電話番号の列を外してから表計算で開いてください。エリアは最初から24に分けず、乗車の多い8エリアとその他で足ります。
| 出てきた内容 | 判断 |
|---|---|
| 応えられなかった依頼が特定の時間帯に集まる | モデルに進む。 配置で取り返せる需要がある |
| 応えられなかった依頼がほとんど無い | 需要より車が多い。待機場所の案だけに絞る |
| 配車できたかの記録が無い | 配車システムの設定が先。 断った依頼を残すところから始める |
3行目が出ることは珍しくありません。 失敗ではなく、配置の判断に使える数字が足りていなかった理由が分かったということです。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 車が足りなかった時間帯ほど需要が少なく見える | 応えられなかった依頼を足す。 乗車件数だけで学ばせない |
| 同じ客の依頼し直しで需要が膨らむ | 同じ位置から10分以内の依頼を1件にまとめる |
| 検証ではよく当たるのに本番で外れる | 15時の時点で手に入る値だけで特徴を作る |
| 0件の時間帯の行が無くて見込みが多めになる | 0件の行も作ってから学ばせる |
| 時系列を混ぜて検証して甘い結果が出る | TimeSeriesSplit で、学ばせる期間の後で検証する |
| 中央の値だけで台数を決めて足りない | 上側の見込みで不足の印を付ける |
| 休息期間が足りない乗務員が早番に入る | 終業時刻を計算で確かめ、確かめられない人は外す |
| 運行管理者が直した後に休息期間を割る | 直した後の割り当ても同じ計算で確かめる |
| 待機場所の案が止められない場所になる | 会社が使える乗り場と待機所の一覧に限る |
| 見込みを乗務員の成績と比べる | 見込みはエリアと時間帯のもの。人の評価に使わない |
上の3行が、この構成の失敗のほとんどです。 どれも「数字は出るが、意味が違う」という形で起きます。需要の作り方と、予測の時点の守り方を押さえてあるかで、案が使えるかが決まります。
下の2行は、運用が始まってから効いてきます。 待機場所の案は乗務員の毎日の動きに直結し、見込みを成績に使えば、案そのものが信じてもらえなくなります。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 乗車と配車の依頼の時刻と位置、乗務員の勤務と終業時刻です。配車システムには、アプリの利用者のIDや電話番号も入っています。
- 利用者を特定する列を書き出さない … 利用者のID、電話番号、氏名は、書き出しの段階で外します。見込みに使うのはエリアと1時間ごとの件数だけです
- 位置をそのまま残さない … 乗車と迎えの位置はエリアに当てはめた後は消し、集計した件数だけを残します。 自宅の前から毎日乗る客の行動が、位置と時刻から分かってしまうからです
- 休息期間の確認を案の前提にする … 改善基準告示の休息期間を割る割り当ては、案に出しません。最後に守るのは運行管理者で、この構成はその見落としを減らすための仕組みです
- 見込みを乗務員の評価に使わない … エリアと時間帯の見込みを、乗務員ごとの成績に直しません
- 生成AIに記録を渡さない … この構成は生成AIを使いません。理由の文を作るために一覧をチャットのAIに貼り付けることも、運用の決まりで禁じます
- 気象情報の利用条件を守る … 予報の取得と保存は、提供元との契約の範囲で行います
- 一覧を見られる人を限る … 乗務員ごとの終業時刻と割り当ての案は、勤務の情報です。一覧は営業所の運行管理者と配車センターだけが開ける場所に置きます
誤りが起きた場合のリスクは、見込みが少なすぎて配車の依頼を断ることと、休息期間の確認が漏れることの2つです。 前者は売上と客の信頼にひびき、後者は乗務員の健康と安全にひびきます。だから例外の扱いは、迷ったら早番の候補から外す側に倒しています。
10まず何から始めるか
1週目:配車システムの記録を確かめる
配車システムが、配車できなかった依頼を時刻と迎えの位置付きで残しているかを確かめます。ここが最初の分かれ目です。 残っていなければ、この週のうちに設定を変えて記録を始めます。
2週目:10日で試す
過去1年分で曜日 × 時間帯 × 雨の有無の平均を出し、車が足りなかった10日に当てて、実際の稼働台数と並べます。応えられなかった依頼がどの時間帯に集まるかを見ます。
3週目:エリアと待機場所の表を作る
営業区域を24エリアに分ける表と、会社が使える乗り場と待機所の一覧を作ります。あわせて、出庫の枠の時刻と、休息期間の線(9時間・11時間)を設定ファイルに書きます。
4週目:毎日の集計を作る
Python で、毎日15時に1時間ごと・エリアごとの集計を作るところまで作ります。この時点ではモデルを作らず、集計の件数が配車システムの日報と合うかだけを確かめます。
集計の件数が日報と合わないときは、エリアの区分の表か、依頼のまとめ方を疑います。 ここで合わせておかないと、モデルの外れと集計の誤りの区別がつきません。
2か月目: モデルで見込みを出し、運行管理者は従来どおり決めながら案と並べます。休息期間の確認の計算を、勤務の実績と突き合わせて確かめます。3か月目以降: 出庫の枠の割り当てと待機場所の案を足し、decided_shift_plan を記録して毎月振り返ります。応えられなかった依頼の件数が時間帯ごとに減ったかを3か月分見た時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
HistGradientBoostingRegressor の loss に poisson(0以上の値)と quantile があり、quantile で推定する分位を指定すること。欠けた値をそのまま扱い、学ばせるときに分かれ目ごとに左右どちらへ送るかを学ぶこと。categorical_features の既定が "from_dtype" で、カテゴリの数が max_bins(255以下)以内である必要があること | scikit-learn: HistGradientBoostingRegressor | 2026-10-14 |
TimeSeriesSplit が、前の期間で学ばせて後の期間で検証する分け方で、通常の交差検証では未来の記録で学んで過去で検証してしまうこと。gap で学ばせる期間の末尾を除けること | scikit-learn: TimeSeriesSplit | 2026-10-14 |
| タクシーの改善基準告示(令和6年4月1日施行)で、日勤の1日の拘束時間が13時間以内(上限15時間)、休息期間が継続11時間を与えるよう努めることを基本とし9時間を下回らないこと。隔日勤務の休息期間が継続24時間を基本とし22時間を下回らないこと | 厚生労働省: ハイヤー・タクシー運転者の改善基準告示 | 2026-10-14 |
勤務表の作成、拘束時間と休息期間の管理、乗務員への指示は、運行管理者と会社が行ってください。 本記事は上記の公式情報で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1535)についてのご相談はこちらから。
