市役所の窓口の受付記録と曜日・月末・制度の締切から、翌週の時間帯ごとの来庁者数と待ち時間を見込み、窓口の職員配置の案を出す
番号札の受付記録と、曜日・月末・祝日・制度の締切の暦から、翌週の30分ごとの来庁者数を窓口ごとに見込みます。待ち時間の目安と必要な職員数を出し、係長が配置を決める材料にします。
- 連携・自動化
- Python
- 対象業界
- 自治体
- 対象部門
- 総務
- 対象業務
- 比較検討/集計・分析
- 主な課題
- 人手が足りない/判断に時間がかかる/属人化している
- AIで行う処理
- 予測
- 主な効果
- 判断支援/対応スピード向上/工数削減
- 導入難易度
- ★★★★☆
- 実装レベル
- 本格構成
- 費用感
- 個別開発(大)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 木曜の午前、主任が受付システムの集計画面から、窓口ごとの先週と前年の同じ週の日別・時間帯別の件数を書き出す
- 課内の予定表と市の広報から、翌週にかかる締切(保険証の更新、各種の申請の期限など)を拾う
- 祝日の前後、月末と月初、給付の通知を送った後などを手で印を付ける
- 窓口ごとに「混みそうな日と時間帯」を見込み、表に色を付ける
- 勤務表と並べて、窓口ごとに何人を座らせるかの案を作る
- 係長が案を見て、人数を直し、応援を頼むかを決める
- 応援が要る日は、ほかの係や課の担当者に頼む
- 自動毎週水曜の夜、受付システムから先週までの受付記録をCSVで書き出す
- 自動Python が記録を窓口ごと・30分ごとの来庁者数と、手続きにかかった時間に集計する
- 自動内閣府の祝日のCSVと、課で持つ締切の暦から、翌週の日ごとの特徴(曜日、月末からの営業日、祝日明け、締切までの日数)を作る
- 自動勾配ブースティングのモデルで、翌週の30分ごとの来庁者数を、真ん中と多めの見込み(80%点)の2本で出す
- 自動多めの見込みと手続きの時間から、職員の人数ごとの待ち時間の目安を計算し、目標の待ち時間に収まる人数を出す
- 自動勤務表の予定人数と並べ、足りない時間帯と応援の候補の時間帯を一覧にする
- 自動先週の見込みと実際の来庁者数を並べ、多めの見込みを超えた時間帯の割合を窓口ごとに出す
- 人主任が、イベントや臨時の通知など暦に無い事情を確かめ、一覧に書き足す
- 人係長が、人数の案を見て配置を決め、応援を頼む
各工程の詳しい説明を読む
- 木曜の午前、主任が受付システムの集計画面から、窓口ごとの先週と前年の同じ週の日別・時間帯別の件数を書き出す
- 課内の予定表と市の広報から、翌週にかかる締切(保険証の更新、各種の申請の期限など)を拾う
- 祝日の前後、月末と月初、給付の通知を送った後などを手で印を付ける
- 窓口ごとに「混みそうな日と時間帯」を見込み、表に色を付ける
- 勤務表と並べて、窓口ごとに何人を座らせるかの案を作る
- 係長が案を見て、人数を直し、応援を頼むかを決める
- 応援が要る日は、ほかの係や課の担当者に頼む
(a)材料作りが毎週重い。 6種類の窓口それぞれに、件数の書き出し、締切の拾い出し、印付け、人数の案が要ります。1窓口150分で、毎週6窓口分を作っています。 係長と主任が窓口に座りながら作るので、混む週ほど材料作りが後回しになります。
(b)見込みの根拠が経験にある。 「月末の月曜は住民異動が混む」「保険証の更新の前は国保の窓口が混む」という見込みは当たることが多いものの、2つが重なった週にどれくらい混むかは、誰も数字で持っていません。 係長が異動すると、見込みのやり方も一緒にいなくなります。
(c)前年の同じ週がそのまま使えない。 祝日の位置、曜日の並び、締切の日付は毎年ずれます。前年の同じ週の件数を並べても、曜日がずれていれば比べられません。
(d)待ち時間で考えていない。 材料にあるのは件数だけで、何人座らせれば待ち時間がどれくらいになるかは分かりません。人数を1人足すか迷う時間帯で、判断の材料がありません。
- 【自動】 毎週水曜の夜、受付システムから先週までの受付記録をCSVで書き出す
- 【自動】 Python が記録を窓口ごと・30分ごとの来庁者数と、手続きにかかった時間に集計する
- 【自動】 内閣府の祝日のCSVと、課で持つ締切の暦から、翌週の日ごとの特徴(曜日、月末からの営業日、祝日明け、締切までの日数)を作る
- 【自動】 勾配ブースティングのモデルで、翌週の30分ごとの来庁者数を、真ん中と多めの見込み(80%点)の2本で出す
- 【自動】 多めの見込みと手続きの時間から、職員の人数ごとの待ち時間の目安を計算し、目標の待ち時間に収まる人数を出す
- 【自動】 勤務表の予定人数と並べ、足りない時間帯と応援の候補の時間帯を一覧にする
- 【自動】 先週の見込みと実際の来庁者数を並べ、多めの見込みを超えた時間帯の割合を窓口ごとに出す
- 【人】 主任が、イベントや臨時の通知など暦に無い事情を確かめ、一覧に書き足す
- 【人】 係長が、人数の案を見て配置を決め、応援を頼む
8番目と9番目が、この設計の分かれ目です。 モデルが知っているのは過去の記録と暦だけです。臨時の給付の通知を送った、庁舎の駐車場が工事で狭くなる、といった事情は担当者しか知りません。 担当者はそれを一覧に書き、機械の見込みと違う配置にした理由を残します。
7番目を最初から組み込むのも、意図してのことです。 80%点の見込みなら、10回に2回くらいは実際がそれを上回るはずです。上回った割合が4割もあれば、多めの見込みは多めになっていません。 その割合を毎週、窓口ごとに出します。
02今回想定するシステム構成
受付システム(発券・呼出・終了の時刻 CSV) 勤務表(翌週の予定人数) │ │ ▼【トリガー】毎週水曜 20:00 の定時実行 Python ├──▶ 内閣府「国民の祝日」CSV(年1回取り込み) ├──▶ 課の締切の暦(担当者が更新する表) ▼ 集計 ── 窓口ごと・30分ごとの来庁者数/手続きの時間の分布 ▼ HistGradientBoostingRegressor ├── 平均の見込み(loss="poisson") └── 多めの見込み(loss="quantile", quantile=0.8) ▼ 待ち時間の計算 ── 人数ごとの待ち時間の目安 → 目標に収まる人数 ▼ 配置の一覧(予定人数との差、応援の候補)+ 先週の見込みの振り返り ▼ 【主任が暦に無い事情を書き足し、係長が配置を決める】
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Python(pandas・scikit-learn の HistGradientBoostingRegressor と TimeSeriesSplit) | R、BigQuery ML |
| 連携 | 内閣府「国民の祝日」のCSV(年1回の取り込み) | 課で持つ祝日の表 |
| 集計 | Python(30分ごとの件数と手続きの時間の集計) | 受付システムの集計画面 |
| データの取得元 | 受付システムのCSV出力、勤務表、課の締切の暦 | 受付システムのAPI |
| 結果の出力先 | 窓口係の共有フォルダの配置の一覧 | 庁内の掲示板 |
受付システムと勤務表には書き込みません。 この構成が出すのは見込みと人数の案までです。勤務表を直すのも、応援を頼むのも、係長です。
祝日は、内閣府のページで公開されているCSVから取ります。 内閣府の「国民の祝日について」のページには、昭和30年(1955年)から令和9年(2027年)までの国民の祝日のCSVが置かれています。翌年の祝日は前年の2月に掲載するとされているため、毎年2月以降に1回取り込み直します。 毎週取りに行く必要はありません。
生成AIは使いません。 見込みも人数も数字で出し、配置の一覧も表です。混む理由を文章で説明させると、暦に無い理由を書き足すおそれがあります。 理由の欄は、モデルに入れた特徴(月末、祝日明け、締切の何日前か)をそのまま書きます。
03どうやって実装するのか
処理の起点を決める
毎週水曜の夜20時に、定時で動かします。 窓口は17時15分に閉まり、その日の受付記録は夜には締まっています。木曜の朝に係長が一覧を見て、その日のうちに応援を頼めるようにするためです。 応援は前の週に頼めば来てもらえることが多いので、木曜に決めれば間に合います。
月曜にもう一度、同じ処理を軽く動かします。 先週の金曜までの実績で、その週の見込みを出し直すだけで、モデルの学び直しはしません。週の途中で臨時の通知が出た場合は、主任がボタンで動かし直します。
モデルの学び直しは、四半期に1回にします。 毎週学び直すと、同じ曜日の見込みが週ごとに上下して、先週の見込みと今週の見込みが比べられなくなります。 年度の切り替わり(3月と4月)だけは、転入・転出の動きが大きいため、前の年度の同じ時期の記録が入っていることを確かめてから見込みます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 受付記録 | 窓口の種類、番号、発券の時刻、呼び出しの時刻、終了の時刻 | 受付システムのCSV |
| 祝日 | 年月日、祝日の名前 | 内閣府「国民の祝日」のCSV |
| 締切の暦 | 締切の日付、関係する窓口、内容(保険証の更新、各種の申請の期限、通知の発送日) | 課で持つ表(主任が更新) |
| 開庁の情報 | 開庁日、窓口を開ける時間、休日開庁や延長の日 | 課で持つ表 |
| 勤務表 | 翌週の日ごと・時間帯ごとに窓口に座れる予定の人数 | 勤務表の表計算 |
| 目標の待ち時間 | 窓口ごとに、何分以内に呼び出したいか | 係長が決める値 |
質を決めるのは、3行目の締切の暦です。 保険証の更新や申請の期限、通知の発送日は、窓口が混む理由のうち、曜日や月末では説明できない部分を持っています。暦に載っていない締切の前の週は、モデルにとってはふつうの週です。通知を送った日と、その通知が何についての通知かを、主任が毎回書きます。
受付記録に、住民の名前や手続きの中身は要りません。 使うのは窓口の種類と3つの時刻だけです。書き出しの段階で、番号と時刻以外の列を外します。
データの取得方法を決める
受付システムからは、前の週までの記録を毎週CSVで書き出します。 書き出しの形は機種によって違うため、最初に1回、どの列が発券・呼び出し・終了の時刻かを主任と確かめ、列の対応表を作ってから取り込みます。API で取れる機種なら API を使いますが、CSVの書き出しで足ります。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 窓口ごとの発券の時刻 | 受付記録 | 30分ごとの来庁者数(予測する値) |
| 呼び出しから終了までの時間 | 受付記録 | 手続きにかかる時間の分布(待ち時間の計算) |
| 発券から呼び出しまでの時間 | 受付記録 | 実際の待ち時間(計算の確かめ) |
| 祝日 | 内閣府のCSV | 祝日、祝日の前後、連休明けの特徴 |
| 締切と通知 | 課の締切の暦 | 締切までの営業日の数の特徴 |
来庁者数は、発券の時刻で数えます。 呼び出しの時刻で数えると、混んで待たされた人が後ろの時間帯にずれ、混んだ時間帯ほど来庁者が少なく見えます。
手続きの時間は、窓口ごとに分布のまま持ちます。 住民異動の手続きは、転入と転居で時間がまったく違います。平均の1つの値にすると、長い手続きが続いたときの待ち時間を小さく見積もります。 過去3か月の記録から、時間帯ごとの分布を作ります。
1人が番号札を2枚取ることもあります。 転入の届出のあとに証明書を取る住民は、2つの窓口の番号札を続けて取ります。2枚目の番号札は、1枚目の手続きが終わった直後に発券されることが多いため、来庁者数としては2つの窓口の両方に数え、窓口どうしの流れとして別に集計しておきます。
AIへ渡す前に整形する
- 列の対応と型のそろえ … 時刻を日時の型にし、窓口の種類の名前を表記ゆれの無い形にそろえます
- 取消と呼び出し漏れの扱い … 発券後に呼び出されずに帰った番号は、来庁者数には数え、手続きの時間からは外します
- 30分ごとの集計 … 開庁時間を30分ごとに区切り、窓口ごとの発券の数を数えます。来庁が0件の時間帯も0として行を作ります
- 暦の特徴を作る … 曜日、月末から数えた営業日、月初から数えた営業日、祝日の翌営業日か、連休明けか、締切までの営業日の数、通知の発送からの営業日の数
- 特殊な日の印 … システムの障害、災害、庁舎の工事、臨時の休日開庁の日に印を付け、学習から外します
- 前年の同じ曜日の値 … 「前年の同じ週」ではなく、前年の同じ月の同じ週目・同じ曜日の件数を特徴にします
3番目の「0件の時間帯も行を作る」を軽く見ないでください。 来庁が無かった時間帯の行が無いと、モデルはどの時間帯にも誰かが来ると学びます。閉庁間際の見込みが多めに出て、人を余らせます。
6番目は、第3章の(c)への答えです。 前年の同じ週は、曜日がずれていれば比べられません。「前年の同じ月の第2月曜」のように並べれば、曜日のずれが消えます。
学習と検証は、時間の順で分けます。 scikit-learn の TimeSeriesSplit は時間順のデータの分け方を作るもので、ほかの分け方では未来のデータで学習して過去のデータで評価することになるとされています。分割数の既定は5で、gap で学習用の末尾と検証用の間を空けられます。翌週を見込むモデルなので、gap を1週間分にします。
AIに処理させる
この構成の「AI」は、来庁者数の見込みだけです。 待ち時間と人数は、見込みと手続きの時間から計算で出します。
| 段 | させること | させないこと |
|---|---|---|
| 平均の見込み | 窓口ごと・30分ごとの来庁者数の平均 | 暦に無い事情の推測 |
| 多めの見込み | 同じく80%点(10回に8回はこれ以下に収まる数) | 待ち時間の直接の予測 |
| 待ち時間の計算 | 人数を1人ずつ変えたときの待ち時間の目安 | 職員の割り振り |
| 人数の案 | 目標の待ち時間に収まる最少の人数と、予定人数との差 | 応援を頼む相手の決定 |
来庁者数の見込みには、scikit-learn の HistGradientBoostingRegressor を使います。 損失の関数に poisson を選べるので、0以上の件数を見込むのに向いています。 quantile を選び、quantile に0.8を指定すれば80%点の見込みになります。窓口の種類をカテゴリの特徴として入れることができ、既定の from_dtype では、データフレームの列の型がカテゴリなら自動でそう扱われます。欠けた値(NaN)もそのまま扱えますので、前年の値が無い新しい窓口の行も落とさずに済みます。
窓口ごとに別のモデルを作るのではなく、1つのモデルに窓口の種類を入れます。 証明書の発行のように件数の多い窓口と、戸籍の届出のように少ない窓口を1つのモデルで学ばせると、少ない窓口でも、曜日や月末の効き方を件数の多い窓口から借りられます。
待ち時間は、30分ごとに順に計算します。 時間帯の初めに残っていた人数に、見込みの来庁者数を足し、職員の人数と手続きの時間の分布から、その30分で終わる人数を引きます。残った人数を次の時間帯に持ち越すので、朝の混雑が昼まで尾を引く様子も出ます。 手続きの時間の分布から何度もくじを引くように計算し、待ち時間の目安を出します。
| 機械にさせないこと | 理由 |
|---|---|
| 職員の名前を入れた勤務の割り振り | 休暇、研修、ほかの事務の締切を知らない |
| 応援を頼む課の決定 | 課どうしの取り決めがある |
| 窓口を開ける時間や席の数の変更 | 条例・規則や庁舎の都合で決まる |
| 暦に無い事情による補正 | 担当者が一覧に書き足して扱う |
1行目がいちばん起きやすい失敗です。 人数の案を勤務表に自動で書き込むと、休暇を取る予定の職員が窓口に入った勤務表ができあがります。この構成は人数までにとどめ、誰を座らせるかは係長が決めます。
指示内容を固定する
この構成は生成AIを使わないため、指示は Python の設定ファイルに書きます。 何をどう見込むかを、係長と主任が読める形で残すためです。
# 窓口の来庁者数の見込みの設定(counter_forecast.yaml)
対象の窓口: [住民異動, 戸籍, 証明発行, 国保年金, 税証明, マイナンバーカード]
時間の刻み: 30分
開庁時間: "08:30-17:15" # 休日開庁・延長の日は開庁の表を優先する
見込み:
平均: {loss: poisson}
多め: {loss: quantile, quantile: 0.8}
学習の期間: 直近の24か月
学び直し: 四半期に1回(1月・4月・7月・10月の第1週)
検証: TimeSeriesSplit(n_splits=5, gap=1週間分)
特徴:
- 曜日
- 月末から数えた営業日 / 月初から数えた営業日
- 祝日の翌営業日か / 連休明けか # 内閣府のCSVから作る
- 締切までの営業日の数(窓口ごと) # 課の締切の暦から作る
- 通知の発送からの営業日の数
- 前年の同じ月・同じ週目・同じ曜日の件数(無ければ空のまま)
待ち時間:
手続きの時間: 窓口ごと・時間帯ごとの過去3か月の分布
目標: {住民異動: 20分, 証明発行: 10分, その他: 15分}
人数の探索: 1人から予定人数+3人まで
守ること:
- 来庁が0件の時間帯も行を作る。欠けた時間帯を前後の値で埋めない
- 印の付いた特殊な日(障害・災害・工事)は学習に使わない
- 多めの見込みが平均を下回った行は、並べ替えずに印を付けて人に見せる
- 受付記録の窓口・番号・時刻以外の列は読み込まない
- 人数の案は勤務表に書き込まない。一覧に出すだけにする
「欠けた時間帯を前後の値で埋めない」を設定に書くのは、第7章の前処理の3番目を守るためです。 書いておかないと、集計を直した担当者が善意で埋めます。埋めると、閉庁間際の見込みが毎週多めに出ます。
「多めの見込みが平均を下回った行に印を付ける」は、2本のモデルを別々に作ると起きることへの備えです。 黙って並べ替えると、見込みの不安定な時間帯があることに誰も気づきません。
出力形式を固定する
配置の一覧を、次の形のJSONと、それを表にしたものの2つで出します。
{
"week_start": "2026-10-12",
"counter": "住民異動",
"model_version": "2026Q4",
"slots": [
{
"date": "2026-10-13",
"time": "09:00",
"visitors_mean": 0.0,
"visitors_p80": 0.0,
"wait_minutes_at_planned": 0,
"staff_planned": 0,
"staff_needed_p80": 0,
"shortage": 0,
"drivers": ["連休明け", "月初2営業日目"],
"flag": ""
}
],
"last_week_review": { "over_p80_rate": 0.0, "slots": 0 },
"notes_by_staff": [],
"decision": { "staff_final": [], "support_requested": [], "reason": "" }
}
slots は Python が埋め、notes_by_staff は主任が、decision は係長が書きます。drivers には、その時間帯の見込みが多めになった理由として、特徴の名前をそのまま入れます。
1つ目の理由は、見込みと判断を同じ記録に並べられることです。 staff_needed_p80 と decision の staff_final を並べれば、機械の案より少なく配置した時間帯で、実際に待ち時間が延びたかを後から確かめられます。
2つ目は、drivers で係長が見込みを読めることです。 「この火曜の朝が多めなのは、連休明けで、保険証の更新の締切の3営業日前だから」と分かれば、係長は自分の経験と照らして見込みを受け入れるか決められます。 理由の無い数字は、経験のある係長ほど信用しません。
3つ目は、last_week_review で見込みの確かさが毎週見えることです。 over_p80_rate が0.2から大きく離れていれば、多めの見込みが多めになっていません。その窓口の見込みは、参考程度に扱います。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 受付システム | CSVの書き出し(読み取りのみ) | 窓口・番号・3つの時刻 |
| 内閣府の祝日のCSV | 年1回の取り込み | 国民の祝日 |
| 課の締切の暦・開庁の表 | 共有フォルダの表の読み取り | 締切、通知の発送日、休日開庁 |
| 勤務表 | 読み取りのみ | 翌週の予定人数 |
| 配置の一覧 | 共有フォルダへの書き込み | 窓口ごとの表とJSON |
受付システムへは何も書き込みません。 番号札の発券や呼び出しの設定は、窓口の運営そのものです。見込みが外れたときに、受付の仕組みまで巻き込まないためです。
庁外のサービスにはデータを送りません。 祝日のCSVを取りに行く以外は、庁内のパソコンかサーバーで計算が終わります。受付記録を庁外に出さない構成にしておくと、情報政策の担当との相談が短く済みます。
人が確認する
係長は、毎週木曜に6窓口の一覧を必ず見ます。
- 振り返りを先に見る …
over_p80_rateが大きく離れた窓口は、今週の見込みも割り引いて読みます - 暦に無い事情を確かめる … 主任が書き足した事情(臨時の通知、庁舎の工事、近くの施設の催し)を見て、見込みを上下させるかを決めます
- 人数の案と勤務表を照らす …
shortageが出た時間帯について、席を動かすか、後ろの事務から人を回すか、応援を頼むかを決めます - 決めた配置を書く …
decisionに最終の人数と応援を書き、案と違う場合は理由を一言残します
2番目を省かないでください。 臨時の給付の通知を送った週は、過去の記録に似た週がありません。 モデルはその週をふつうの週と見ます。担当者が書き足さないかぎり、見込みは少なめに出ます。
係長が不在の週は、代わりに決める人を前もって決めておきます。 一覧が出ても、決める人がいなければ応援は頼めません。一覧を見る人と、決める人の順番を、勤務表と同じ場所に書いておきます。
目標は、1窓口あたり35分です。 振り返りの確かめが数分、事情の書き足しと人数の検討が20分前後、配置の記録と応援の連絡が10分前後です。
例外に対処する
| 起きること | 対応 |
|---|---|
| 受付システムのCSVが書き出せない | 先週の見込みをそのまま使い、一覧の冒頭に「実績の取り込みなし」と書く |
| 列の並びが変わった(機種の更新) | 列の対応表と合わなければ止め、主任に確かめを頼む |
| 新しい窓口の種類ができた | 過去の記録が無いので見込みを出さず、近い窓口の値を参考として並べる |
| 臨時の休日開庁 | 開庁の表に足し、その日は過去の休日開庁の日の記録だけで見込む |
| 締切の暦が更新されていない | 一覧の冒頭に暦の最終更新日を書き、2週以上古ければ警告を出す |
| 多めの見込みが平均を下回った | 印を付けて人に見せる。並べ替えない |
| 障害・災害で記録が飛んだ日 | 特殊な日の印を付け、学習と振り返りから外す |
| 祝日のCSVに翌年の祝日が無い | 2月の掲載を待つ。それまでの翌年の週は、祝日の特徴を空にして見込む |
上の2行は、運用の最初の数か月で必ず起きます。 どちらも見込みを止める理由にはしませんが、どの週の実績まで取り込んだかを一覧に書かないと、古い見込みが新しいものに見えます。
記録を残す
- 毎週の受付記録のCSV(窓口・番号・時刻の列だけ)と、取り込んだ日時
- 祝日のCSVと締切の暦の、そのときの版
- モデルの版、学習の期間、検証の結果
- 窓口ごと・30分ごとの見込み(平均と多め)、待ち時間の目安、人数の案
- 主任が書き足した事情と、係長が決めた配置と理由(
decision) - 先週の見込みと実際の来庁者数・実際の待ち時間の比べ
最後の行は、四半期ごとの学び直しの材料になります。 多めの見込みを超えた時間帯が特定の締切の前に集まっていれば、その締切の効き方をモデルが学べていないということです。締切の暦の書き方を見直します。
04実装レベルの3段階
半自動化だけでも、①の50分はほぼ消えます。 曜日のずれを手で合わせる作業が無くなるからです。ただし、混む日と人数の見込みは、まだ係長の経験に残ります。 本格構成で1窓口35分になり、この段階が本記事の想定です。 違いは、多めの見込みと待ち時間の目安が最初から並び、人数を1人足したときの差が数字で見えることです。 本格構成で増えるのは、待ち時間の計算です。 件数の見込みだけでは、何人を座らせるかの判断はまだ係長の頭の中に残ります。人数を1人ずつ変えたときの待ち時間が並ぶと、「この時間帯は1人足せば目標に収まる」「2人足しても収まらないので応援が要る」と、判断が数字の比べになります。 段階を飛ばさないでください。 半自動化で数か月、暦の印と件数を並べると、締切の暦に何を書けば効くかが窓口係の間でそろいます。それを暦に書いてから見込みを出すほうが、係長に受け入れられます。
05工数削減シミュレーション
導入後 24件 × 35分 ÷ 60 = 14 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 番号札の発券機(受付システム)を入れていて、発券・呼出・終了の時刻を書き出せる市役所・区役所。住民異動・証明発行・国民健康保険・税証明など窓口が複数に分かれ、窓口ごとに混む日と時間帯が違う場合。翌週の窓口の職員配置を係長が前の週に経験で決めていて、応援の頼み方が担当者ごとに違う場合。2年以上の受付記録が残っている場合。
- 発券機が無く、受付の時刻が記録に残っていない窓口。窓口が1つで、配置を動かす余地が無い小規模な町村。来庁の大半が予約制で、予約の数がそのまま来庁者数になる窓口。なお、職員の勤務の割り振りそのもの、応援を出す課との調整、窓口を開ける時間の変更は、この構成では代替できません。
07最小構成で試す方法
- 証明書の発行の窓口だけを選び、過去2年分の受付記録をCSVで書き出す
- 表計算で、日ごと・1時間ごとの発券の件数を数える
- 曜日、月末、祝日明け、締切の日に印を付け、件数と並べる
- 手元のAIサービスに印と件数の表を貼り、「どの印の日に件数が多いか、印が重なった日にどれくらい増えるかを見てください」と聞く
- 出てきた傾向を、係長の経験と比べる
この段階ではモデルを作りません。 確かめたいのは、暦の印だけで、混む日がどれくらい説明できるかです。
| 出てきた内容 | 判断 |
|---|---|
| 印の重なった日ほど件数が多く、係長の経験とも合う | Python で30分ごとの見込みを出す段階に進む |
| 印と関係なく、特定の日だけ飛び抜けて多い | 暦に無い事情がある。締切の暦の作り直しが先 |
| どの日も件数がほとんど同じ | 見込む意味が小さい。その窓口は対象から外す |
2行目が出ることは珍しくありません。 失敗ではなく、係長が経験で知っている事情が、まだ暦に書かれていないことが分かったということです。飛び抜けた日の理由を係長に聞き、締切の暦に足してから、同じ表をもう一度見てください。手元のAIサービスに貼るのは件数と印だけにし、受付記録そのものは貼りません。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 混んだ時間帯の来庁者が少なく見える | 呼び出しの時刻で数えている。発券の時刻で数える |
| 閉庁間際の見込みがいつも多い | 0件の時間帯の行が無い。0として行を作る |
| 検証ではよく当たるのに本番で外れる | 時間の順を無視して分けた。TimeSeriesSplit と gap で未来を見ない |
| 前年との比べで曜日がずれる | 前年の同じ週ではなく、同じ月・同じ週目・同じ曜日で並べる |
| 待ち時間の目安が実際より短い | 手続きの時間を平均にしている。分布のまま使う |
| 締切の前の週を見込めない | 締切の暦が空。通知の発送日まで書く |
| 翌年の祝日が入っていない | 内閣府のCSVは翌年分を前年の2月に掲載する。2月以降に取り込み直す |
| 多めの見込みが平均を下回る | 2本を別に作ると起きる。印を付けて人に見せる |
| 人数の案がそのまま勤務表になる | 書き込まない。 係長が決める |
| 機種の更新で列が変わる | 列の対応表と照らし、合わなければ止める |
| 2枚目の番号札で来庁者が二重に見える | 窓口ごとの件数としては両方に数え、窓口どうしの流れを別に集計する |
| 人数は足りているのに窓口が回らない | その窓口に座れる職員が足りない。誰が座れるかは係長が照らす |
上の2行が、見込みの失敗のほとんどです。 どちらも数字は出ているので動いているように見えます。先週の見込みを超えた割合を毎週出す仕組みが無いと、ずれに気づけません。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 窓口の種類、番号札の番号、発券・呼び出し・終了の時刻、職員の予定人数。住民の名前や手続きの中身は使いません。 ただし、時刻と窓口の組み合わせは、ほかの記録と突き合わせれば個人に近づく情報です。
- 書き出しの段階で列を絞る … 受付システムに氏名や手続きの種類の細目を入力している場合も、窓口・番号・時刻以外の列は書き出さない設定にします
- 庁外のサービスへ送らない … 計算は庁内で終わります。最小構成で手元のAIサービスを使うときも、貼るのは集計した件数と暦の印だけにします
- 配置を自動で決めない … 人数の案は判断の材料です。勤務表への書き込みと、応援の依頼は係長が行います
- 見込みを住民向けの混雑の案内にそのまま使わない … 住民に出す混雑の目安は、外れたときの影響が窓口の中より大きくなります。出す場合は、実際の待ち時間の記録で見込みの確かさを確かめてからにします
- 見込みと判断の記録を残す … 見込み、配置、実際の待ち時間を並べて残し、後から配置の理由を説明できるようにします
- 職員ごとの処理の速さを測らない … 受付記録には、どの職員が手続きをしたかが残る機種もあります。この構成で使うのは窓口ごとの手続きの時間の分布だけで、職員ごとの速さは集計しません。 配置の材料が職員の評価の材料に変わると、窓口の手続きが急がされます
誤りが起きた場合のリスクは、少なめの見込みで人を減らして住民を長く待たせることと、多めの見込みで後ろの事務が止まることの2つです。 前者は多めの見込みで人数を出すことで、後者は係長が後ろの事務の締切と照らして配置を決めることで防ぎます。
10まず何から始めるか
1週目:受付記録の列を確かめる
受付システムから1か月分の記録を書き出し、発券・呼び出し・終了の時刻がどの列か、取消の番号がどう記録されるかを主任と確かめます。氏名などの列を書き出さない設定もここで決めます。
2週目:締切の暦を作る
窓口ごとに、毎年くり返す締切と、通知の発送日を書き出します。係長が経験で知っている「混む理由」を聞き取り、暦に足します。
3週目:1窓口で並べてみる
証明書の発行の窓口について、過去2年の件数と暦の印を表で並べ、印の重なった日にどれくらい増えるかを見ます。
4週目:集計を自動にする
Python で受付記録の30分ごとの集計と暦の特徴を毎週そろえ、前年の同じ曜日の件数と並べるところまで作ります。この時点では見込みを出しません。
2か月目: 6窓口の見込みを2本で出し、TimeSeriesSplit で検証します。待ち時間の計算と人数の案を付けます。3か月目以降: 先週の見込みを超えた割合を毎週出し、係長の配置と並べて残します。全6窓口で振り返りの割合が安定し、木曜の午前に配置と応援の依頼が済むようになった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
| 内閣府のページに、昭和30年(1955年)から令和9年(2027年)までの国民の祝日のCSV(csv形式:22KB)が置かれていること。令和10年(2028年)の国民の祝日は前年の2月に掲載するとされていること | 内閣府: 国民の祝日について | 2026-10-07 |
HistGradientBoostingRegressor の loss に poisson と quantile があり、quantile で分位点を指定できること。欠けた値(NaN)をそのまま扱えること。categorical_features の既定が from_dtype で、カテゴリ型の列を自動でカテゴリの特徴として扱うこと | scikit-learn: HistGradientBoostingRegressor | 2026-10-07 |
TimeSeriesSplit が時間順のデータの分け方を作り、ほかの分け方では未来のデータで学習して過去を評価することになること。n_splits の既定が5、gap で学習用の末尾と検証用の間を空けられること | scikit-learn: TimeSeriesSplit | 2026-10-07 |
窓口の配置と応援の依頼は、窓口係の係長が決めてください。 本記事は製品と公的なデータの公開ドキュメントで確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-0738)についてのご相談はこちらから。
