求人媒体ごとの過去の応募数と掲載条件・時期から来月の応募数を見込み、採用目標に足りない職種と媒体の追加案を出す
求人媒体・職種・エリアごとに、過去の応募数と掲載の条件、時期、地域の求人の動きから翌月の応募数を見込みます。採用目標に必要な応募数と比べて足りない募集を挙げ、媒体の追加や掲載の変更の案を並べます。
- 連携・自動化
- Google Apps Script/Python
- 対象業界
- 介護/小売/物流/飲食
- 対象部門
- 採用
- 対象業務
- 比較検討/集計・分析
- 主な課題
- 人手が足りない/判断に時間がかかる/属人化している
- AIで行う処理
- 予測
- 主な効果
- 判断支援/工数削減/機会損失防止
- 導入難易度
- ★★★★☆
- 実装レベル
- 本格構成
- 費用感
- 個別開発(大)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 応募者管理システムから、前月と前年同月の媒体ごとの応募数を書き出す
- 媒体の管理画面から、掲載のプランと掲載日数を確かめる
- 店舗ごとの採用計画から、来月の採用目標を職種とエリアごとに集める
- 職種とエリアごとに、来月の応募数を見込む
- 目標の採用数に届くだけの応募が来そうかを、これまでの経験で判断する
- 足りなそうな募集について、どの媒体を足すか、プランを上げるかを考える
- 課長と相談して翌月の掲載を決め、媒体に申し込む
- 自動毎月15日に、応募者管理システムと掲載の記録から、前月までの応募数と掲載の条件を取り込む
- 自動地域の求人の動き(公表された最新の統計)と、店舗の新店・改装の予定を取り込む
- 自動媒体・職種・エリアごとに、翌月の応募数を「控えめな見込み」「ふつうの見込み」の2本で予測する
- 自動店舗ごとの採用計画から、職種とエリアごとに必要な応募数を出す
- 自動控えめな見込みが必要な応募数に届かない募集を挙げ、不足の大きい順に並べる
- 自動不足の募集ごとに、過去に実績のある媒体とプランの組み合わせから追加の案を並べる
- 人採用課が、不足の募集と案を確かめ、店舗の事情を足して翌月の掲載を決める
- 人翌月の終わりに、見込みと実際の応募数の差を見て、外れた理由を記録する
各工程の詳しい説明を読む
- 応募者管理システムから、前月と前年同月の媒体ごとの応募数を書き出す
- 媒体の管理画面から、掲載のプランと掲載日数を確かめる
- 店舗ごとの採用計画から、来月の採用目標を職種とエリアごとに集める
- 職種とエリアごとに、来月の応募数を見込む
- 目標の採用数に届くだけの応募が来そうかを、これまでの経験で判断する
- 足りなそうな募集について、どの媒体を足すか、プランを上げるかを考える
- 課長と相談して翌月の掲載を決め、媒体に申し込む
(a)見込みが前年同月の数字に引っ張られる。 去年の10月に30件来たなら今年も30件、という見込み方です。去年は近くに競合の大型店が開業する前だった、去年は時給を上げた直後だった、という事情は数字に残っていません。見込みが外れた理由も、翌年には分からなくなります。
(b)足りないと分かるのが月の半ばになる。 見込みが甘いと、月の前半の応募が少ないことに気づいてから慌てて掲載を足します。媒体の締め切りを過ぎていれば、翌月まで足せません。 その間、店舗は人手が足りないまま回します。
(c)媒体の選び方が担当者の経験で決まる。 「このエリアの夜間の品出しなら、あの媒体」という判断は、担当者の頭の中にあります。担当替えのたびに、同じ失敗を一度ずつ繰り返します。
(d)地域全体の求人の動きを見ていない。 地域の求人が増えると、同じ掲載でも応募は減ります。自社の数字だけを見ていると、応募が減った理由を自社の掲載のせいだと考えてしまいます。
- 【自動】 毎月15日に、応募者管理システムと掲載の記録から、前月までの応募数と掲載の条件を取り込む
- 【自動】 地域の求人の動き(公表された最新の統計)と、店舗の新店・改装の予定を取り込む
- 【自動】 媒体・職種・エリアごとに、翌月の応募数を「控えめな見込み」「ふつうの見込み」の2本で予測する
- 【自動】 店舗ごとの採用計画から、職種とエリアごとに必要な応募数を出す
- 【自動】 控えめな見込みが必要な応募数に届かない募集を挙げ、不足の大きい順に並べる
- 【自動】 不足の募集ごとに、過去に実績のある媒体とプランの組み合わせから追加の案を並べる
- 【人】 採用課が、不足の募集と案を確かめ、店舗の事情を足して翌月の掲載を決める
- 【人】 翌月の終わりに、見込みと実際の応募数の差を見て、外れた理由を記録する
7番目が、この設計の分かれ目です。人が見るのは60件全部の見込みではありません。 控えめな見込みでも目標に届く募集は一覧で流し見て、届かない募集と、見込みの幅が大きい募集だけに時間を使います。 60件すべての見込みを人が見直す設計にすると、30分はほとんど減りません。
8番目を省かないのも、意図してのことです。 予測が外れた理由が「近くに競合が開業した」なら、それは来月のデータに入れられます。外れた理由を記録しないと、同じ外れ方を毎年繰り返します。
02今回想定するシステム構成
応募者管理システム(媒体ごとの応募の記録) 掲載の記録(プラン・日数・時給)
店舗の採用計画・新店の予定 地域の求人の統計(公表された最新の値)
│ │
└──────────────┬──────────────────────────┘
▼【トリガー】毎月15日
Python(pandas で取り込み・整形)
├──▶ 応募数の予測(scikit-learn、ふつうの見込み/控えめな見込み)
├──▶ 採用目標 ÷ 応募から採用までの歩留まり = 必要な応募数
└──▶ 不足の募集と、実績のある媒体・プランの追加の案
▼
来月の募集ごとの見込みと案(根拠付き)
▼
【採用課が確認・決定 → 外れた理由を翌月に記録】| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Python(pandas と scikit-learn で予測と不足の計算) | Google Apps Script(予測は外部で行い、集計と表の作成のみ) |
| 予測モデル | scikit-learn の HistGradientBoostingRegressor | LightGBM |
| 保管 | 共有ストレージ(取り込んだデータの写しと、予測・案・実績の記録) | データベース |
| 案の表示 | Google スプレッドシート(エリアごとのシート) | Microsoft 365 の共有のブック |
生成AIは使いません。 この構成で行うのは、過去の数字から翌月の数字を見込む予測と、その数字を採用目標と比べる計算です。どちらも、同じ入力から毎回同じ答えが出る仕組みのほうが、課長や店舗に説明しやすくなります。
予測には、scikit-learn の HistGradientBoostingRegressor を使います。 scikit-learn のドキュメントでは、ヒストグラムにもとづく勾配ブースティングの回帰木で、データが大きい(1万件以上)場合には従来の GradientBoostingRegressor よりはるかに速いとされています。5媒体+自社サイト+ハローワーク × 6職種 × 10エリア × 3年分の月次のデータは1万件を超え、この範囲に入ります。
この構成で効くのは、4つの性質です。 1つ目は、loss に 'poisson' を指定できることです。ポアソン分布の逸脱度を損失にするもので、目的の値が0以上である必要があります。 応募数は0以上の件数なので、この性質に合います。2つ目は、loss='quantile' と quantile の値を指定すると分位点を予測できることです。控えめな見込みには0.2のように低い値を指定し、別のモデルとして学習させます。3つ目は、欠けた値(NaN)をそのまま扱えることで、学習の途中で、欠けた値の行を分岐のどちら側に送るかを学びます。古い月の時給の記録が無くても、行ごと捨てずに済みます。4つ目は、categorical_features で媒体・職種・エリアをカテゴリとして扱えることです。既定の 'from_dtype' では、pandas のカテゴリ型の列がそのままカテゴリとして扱われます。
地域の求人の動きには、厚生労働省の一般職業紹介状況を使います。 厚生労働省のページでは、この統計は公共職業安定所における求人、求職、就職の状況を取りまとめ、求人倍率等の指標を作成することを目的とするとされ、毎月公表されています。年度単位では、都道府県別・職業別(中分類)などのより詳しい区分の集計も公表されています。
03どうやって実装するのか
処理の起点を決める
毎月15日に動かします。 翌月の掲載を決めるのが20日ごろなので、その5日前に見込みと案がそろっていれば、採用課が確認し、課長と相談し、媒体に申し込む時間が取れます。
15日にしているのは、前月の応募数が確定しているからでもあります。 応募者管理システムには、媒体からの応募が数日遅れて取り込まれることがあります。月初に動かすと、前月の最後の数日の応募が欠けたまま学習します。 前月の応募数が確定する日を、運用の中で先に確かめておきます。
新店の開業や大きな改装が決まったときは、採用課が手で動かせるようにします。 新店の採用は数十名をまとめて採るので、通常の月次とは別に、開業の3か月前から見込みを出します。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 応募の記録 | 応募日、媒体、職種、エリア、店舗(個人の情報は使わない) | 応募者管理システムの書き出し |
| 掲載の記録 | 媒体、プラン、掲載の開始日・終了日、提示した時給、掲載した店舗の数 | 掲載の記録(スプレッドシート) |
| 採用の記録 | 応募から採用までの結果(採用・不採用・辞退) | 応募者管理システム |
| 採用計画 | 店舗・職種ごとの来月の採用目標 | 店舗ごとの採用計画 |
| 店舗の予定 | 新店・改装・閉店の予定日 | 店舗開発部の予定表 |
| 地域の求人の動き | 都道府県ごとの求人倍率など、公表された最新の値 | 厚生労働省の一般職業紹介状況 |
質を決めるのは、掲載の記録です。 応募数は応募者管理システムにきれいに残っていても、その月にどの媒体にどのプランで何日掲載したかが残っていないと、応募が多かった理由が分かりません。 掲載の記録がスプレッドシートで担当者ごとにばらばらなら、まずここをそろえます。
採用計画は、店舗から上がってきた数字をそのまま使います。 店舗の欠員の見込みは、退職の申し出が月の途中で増えると変わります。予測を動かす15日の時点の採用計画を写して保存し、後から計画が変わったときは、どの時点の計画で不足を判定したかが分かるようにします。計画が変わった募集だけを、採用課が手で動かし直せるようにしておきます。
時給は、エリアの中での相対的な水準に直して持ちます。 同じ1,100円でも、都市部と郊外では意味が違います。エリアごとの自社の提示時給の中央値との差を特徴量にします。
データの取得方法を決める
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 応募の記録 | 応募者管理システムからCSVで書き出し | 月 × 媒体 × 職種 × エリアの応募数 |
| 掲載の記録 | スプレッドシートを読み取る | プラン、掲載日数、時給の水準 |
| 採用の記録 | 応募者管理システムからCSVで書き出し | 応募から採用までの歩留まり |
| 採用計画 | 店舗ごとの採用計画のシート | 必要な応募数 |
| 地域の求人の動き | 公表された統計表を、公表のたびに取り込む | 地域の求人の動きの特徴量 |
応募の記録から取るのは件数だけです。 氏名や連絡先、年齢は予測に使いません。応募者管理システムの書き出しの段階で、個人を特定できる列を外します。
自社の採用サイトとハローワークからの応募も、媒体の1つとして数えます。 応募者管理システムに経路が記録されていれば、ほかの媒体と同じ形で集計できます。経路が「その他」や空欄になっている応募は、どの媒体の数字にも入れず、件数だけを別に数えます。 空欄の割合が大きい月は、応募の取り込みの設定が崩れている合図です。
地域の求人の統計は、予測する時点で公表されている値だけを使います。 統計は月ごとに公表されますが、翌月の値は予測する時点ではまだありません。学習のときも、その月の時点で公表されていた値を使います。 後から公表された値を学習に入れると、本番では手に入らない情報を使ったモデルになります。
AIへ渡す前に整形する
- 月次への集計 … 応募の記録を、月 × 媒体 × 職種 × エリアの件数にします。応募が0件の月も、0の行として残します
- 掲載の記録の結合 … 同じ月・媒体・職種・エリアの掲載の記録を結合し、掲載日数とプランを付けます
- 掲載していない月の扱い … 掲載していない月の0件と、掲載したのに0件だった月を分けます。前者は学習から外し、後者は残します
- 時給の水準 … エリアごとの中央値との差に直します。記録の無い古い月は空のままにします
- 時期の特徴量 … 月、前年同月の応募数、直近3か月の平均を作ります
- 地域の求人の動き … その月の時点で公表されていた最新の値を付けます
- 歩留まりの計算 … 職種 × エリアごとに、直近12か月の応募から採用までの割合を出します
- 重複の除去 … 同じ人が複数の媒体から応募した場合の数え方を決め、そろえます
3番目を軽く見ないでください。 掲載していない月の0件を学習に入れると、モデルは「この媒体はこの時期に応募が来ない」と覚えます。 実際は掲載していなかっただけです。掲載していたかどうかは、掲載の記録からしか分かりません。
AIに処理させる
させるのは、媒体 × 職種 × エリアごとの翌月の応募数を、「ふつうの見込み」と「控えめな見込み」の2本で予測することです。 不足の判定と追加の案は、予測の後にプログラムの規則で出します。
| 何をするか | どうやって | 何のために |
|---|---|---|
| ふつうの見込み | loss='poisson' のモデル | 応募数の中心の値 |
| 控えめな見込み | loss='quantile'、quantile=0.2 のモデル | 不足を見つけるための低めの値 |
| 必要な応募数 | 採用目標 ÷ 歩留まり | 目標に届くかの基準 |
| 不足の判定 | 控えめな見込みの合計 < 必要な応募数 | 先に手当てする募集を選ぶ |
| 追加の案 | 過去に実績のある媒体・プランの組み合わせを並べる | 足し方の候補 |
控えめな見込みで判定するのは、足りないときの損のほうが大きいからです。 応募が多すぎれば面接を断るだけで済みますが、少なすぎれば店舗は翌月も人手が足りないまま回します。低めの見込みで目標に届くかを見て、届かないものだけを手当てします。
特徴量は次のとおりです。
| 特徴量 | 中身 |
|---|---|
| 媒体・職種・エリア | カテゴリとして扱う |
| 月 | 季節の動き(年末の短期、春の主婦層の動きなど) |
| 掲載のプランと掲載日数 | 掲載の強さ |
| 時給の水準 | エリアの中央値との差。古い月は空 |
| 前年同月の応募数、直近3か月の平均 | その募集の基本の水準 |
| 地域の求人の動き | 予測する時点で公表されていた最新の値 |
| 新店・改装 | その月にエリア内で予定があるか |
追加の案は、予測のモデルから効果を出しません。 モデルの入力の「掲載のプラン」を上のプランに変えて予測し直せば数字は出ますが、それは過去のデータの中の相関で、プランを上げれば応募が増えることを示すものではありません。 案には、そのエリア・職種で過去にその媒体・プランを使ったときの応募数の実績を並べ、実績の無い組み合わせは「実績なし」と明記します。
指示内容を固定する
生成AIは使わないので、プロンプトはありません。 代わりに、学習と予測の設定を固定して記録します。
# 学習の設定(毎月同じ)
対象: 月 × 媒体 × 職種 × エリア の応募数(掲載した月だけ)
期間: 直近36か月
ふつうの見込み: HistGradientBoostingRegressor(loss='poisson',
categorical_features='from_dtype')
控えめな見込み: HistGradientBoostingRegressor(loss='quantile', quantile=0.2,
categorical_features='from_dtype')
検証: TimeSeriesSplit(n_splits=5, gap=1) # 1か月空けて検証
評価: 媒体ごと・エリアごとの絶対誤差、控えめな見込みを下回った割合
# 予測の規則
- 予測する月の地域の求人の動きは、その時点で公表済みの最新の値を使う
- 学習期間に掲載の実績が6か月未満の 媒体×職種×エリア は予測しない
→ 「実績不足」として人へ回す
- 予測が前年同月の実績の半分未満、または2倍を超えたら「要確認」を付ける
# 不足の判定
- 必要な応募数 = 採用目標 ÷ 歩留まり(直近12か月)
- 控えめな見込みの合計が必要な応募数を下回る募集を「不足」とする
- 歩留まりの元になる応募が30件未満の職種×エリアは、エリア全体の歩留まりを使う
検証に TimeSeriesSplit を使うのは、未来の月で学習して過去の月を当てるのを防ぐためです。 scikit-learn のドキュメントでは、時系列のデータのための分割で、通常の交差検証と違ってシャッフルせず、各回の学習の期間は前の回を含んで広がっていくとされています。gap を指定すると、学習と検証の間を空けられます。本番では前月の応募が確定してから翌月を予測するので、1か月空けた検証が本番の条件に近くなります。
「実績不足は予測しない」を規則に入れているのも、意図してのことです。 掲載したばかりの媒体や、新しいエリアの募集は、モデルが似た組み合わせから数字を出してしまいます。その数字がもっともらしいほど、人は疑いません。 予測しないと決め、人に回します。
出力形式を固定する
募集ごとに、次の形の表を出します。
| 列 | 中身 |
|---|---|
| 職種・エリア | 募集の単位 |
| 必要な応募数 | 採用目標 ÷ 歩留まり |
| ふつうの見込み(合計) | 媒体ごとの見込みの合計 |
| 控えめな見込み(合計) | 媒体ごとの控えめな見込みの合計 |
| 判定 | 不足/届く/実績不足/要確認 |
| 媒体ごとの内訳 | 媒体、プラン、ふつうの見込み、控えめな見込み、前年同月の実績 |
| 追加の案 | 実績のある媒体・プラン、過去の応募数の実績、1件あたりの費用の実績 |
機械が読む形は、次のJSONです。
{
"target_month": "2026-11",
"job": "夜間品出し",
"area": "東エリア",
"required_applicants": 0,
"forecast_mid_total": 0,
"forecast_low_total": 0,
"status": "shortage | ok | insufficient_history | check",
"by_media": [
{ "media": "", "plan": "", "mid": 0, "low": 0, "last_year_actual": 0 }
],
"options": [
{ "media": "", "plan": "", "past_applicants": [0], "past_cost_per_applicant": 0,
"note": "実績あり | 実績なし" }
]
}
表とJSONの両方を出すのは、読む人が違うからです。 表は採用課が見るためのもので、JSONは翌月に実績と突き合わせるために保存します。見込みと実績を同じ形で並べられないと、外れた理由を記録できません。
options には、効果の見込みの数字を入れません。 過去の実績の数字だけを並べ、「このプランなら何件増える」とは書きません。 第7章の「AIに何をさせるのか」で述べた理由です。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 応募者管理システム | CSVの書き出しを読み取る | 応募と採用の記録(個人の情報を外したもの) |
| 掲載の記録 | スプレッドシートの読み取り | プラン・日数・時給 |
| 採用計画・店舗の予定 | スプレッドシートの読み取り | 採用目標、新店・改装 |
| 地域の求人の統計 | 公表のたびに統計表を取り込む | 求人の動きの特徴量 |
| 案の表示 | Google スプレッドシートへ書き込み | エリアごとのシートに表を書く |
| 採用課 | Teams への通知 | 不足の募集の数と、表の場所 |
媒体には申し込みません。 掲載を決めて媒体に申し込むのは、採用課の仕事のままです。媒体の管理画面に自動で申し込む連携は作りません。 予算を伴う判断を、予測の数字だけで実行させないためです。
応募者管理システムにも書き込みません。 読むのは書き出したCSVだけです。
人が確認する
人が見るのは、「不足」「実績不足」「要確認」の募集だけです。 「届く」の募集は一覧で流し見ます。
- 「不足」を先に見る … 不足の大きい順に、追加の案と過去の実績を見て、足し方を決めます。店舗の事情(近くの競合の開業など)があれば足します
- 「要確認」を見る … 見込みが前年同月から大きく離れた理由を、特徴量の値から確かめます。掲載の記録の入力漏れが原因のことが多くあります
- 「実績不足」を決める … 新しい媒体やエリアは、担当者が見込みを立てます
- 課長と相談して決める … 追加の掲載の費用を含めて決めます
- 翌月の終わりに外れた理由を記録する … 見込みと実績の差が大きかった募集について、理由を1行で残します
1番目で、案をそのまま採らないでください。 案は過去の実績を並べただけで、その媒体がいまも同じように応募を集められるかは分かりません。 媒体側のプランや料金が変わっていることもあります。
目標は、1件8分です。 60件のうち不足と要確認が1〜2割という想定で、それより多い月は、掲載の記録が漏れているか、地域の求人の動きが大きく変わっています。
確認の画面には、見込みの根拠になった値を並べます。 前年同月の実績、直近3か月の平均、掲載のプランと日数、地域の求人の動きの値です。担当者は、見込みが低い理由を「前年同月が低かったから」なのか「掲載日数が短いから」なのかで見分けられます。 理由が掲載の側にあれば、掲載日数を延ばすだけで足りることもあります。
例外に対処する
| 起きること | 対応 |
|---|---|
| 前月の応募数がまだ確定していない | 予測を止め、確定してから動かす |
| 掲載の記録に、その月の行が無い | 「掲載していない」と扱わず、要確認として担当者に聞く |
| 新しい媒体・新しいエリア | 「実績不足」。担当者が見込みを立てる |
| 媒体がプランの名前を変えた | 新旧のプランの対応表を持ち、同じプランとして扱う |
| 新店の開業で、エリアの採用目標が急に増える | 新店の分は別の表にし、開業の3か月前から見込む |
| 地域の求人の統計の公表が遅れる | 前月の値を使い、使ったことを記録する |
| 見込みが前年同月の半分未満・2倍超 | 「要確認」を付けて人へ |
| 予測の誤差が急に大きくなった | その月の予測を参考扱いにし、外れた理由を先に調べる |
| 処理が途中で止まる | 前月の予測を残したまま、担当者に通知する |
2行目がいちばん大事な例外です。 掲載の記録が漏れている月を「掲載していない」と扱うと、前処理の3番目で学習から外れ、さらに予測の入力も間違います。 記録が無いことと、掲載していないことは、人に聞かないと区別できません。
例外で止めた募集は、止めた理由と一緒に一覧の先頭に出します。 止まったまま20日の締め切りを迎えると、その募集だけ見込みの無いまま掲載が決まります。止めた募集の数を、通知の1行目に書きます。
記録を残す
- 取り込んだデータの写し(応募・掲載・採用・計画・統計)と取り込んだ日時
- 学習に使った期間と設定、モデルの版
- 予測の結果(JSON)と、判定・案
- 採用課が決めた掲載と、案から変えた点
- 翌月の実績と、見込みとの差、外れた理由
- 媒体ごと・エリアごとの誤差の推移
モデルの版と学習に使った期間を残すのは、毎月学習し直すためです。 先月と今月で見込みが大きく変わったとき、データが変わったのか、モデルが変わったのかを切り分けられるようにします。
5つ目が、この構成の改善の材料になります。 「競合の開業」「時給の改定」「媒体のプラン変更」のように外れた理由がたまると、どの特徴量を足せば外れが減るかが見えてきます。
04実装レベルの3段階
半自動化だけでも、①の集める作業は無くなります。 見込みは単純なままですが、必要な応募数との比較が全募集で同じ規則で行われます。 本格構成で、1件30分が8分になります。この段階が本記事の想定です。 見込みを人が立てる作業が無くなり、人に残るのは不足の募集の手当てと、外れた理由の記録です。 段階を飛ばさないでください。 半自動化を数か月回すと、掲載の記録の漏れと、歩留まりの元になる採用の記録の漏れが先に見つかります。 それを直してから予測を入れたほうが、外れが少なくなります。
05工数削減シミュレーション
導入後 60件 × 8分 ÷ 60 = 8 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 多店舗でパート・アルバイトを中心に毎月採用しており、複数の求人媒体に掲載を出し分けている小売・飲食・物流などの企業。翌月の応募数を前年同月の数字と担当者の勘で見込み、足りないと分かったときには掲載の追加が間に合わない場合。媒体ごとの応募数と掲載条件の記録が、少なくとも2〜3年分残っている場合。
- 採用が年に数名で、募集のたびに状況が違う場合。求人媒体を1つしか使っておらず、出し分けの判断が無い場合。応募数の記録が媒体の管理画面にしか無く、過去の分を書き出せない場合。なお、時給の水準や採用の基準をどう変えるかの判断は、この構成では代替できません。
07最小構成で試す方法
- 応募者管理システムから、直近2年分の応募数を月 × 媒体 × 職種 × エリアで書き出す
- 掲載の記録から、同じ期間の媒体ごとのプランと掲載日数を書き出し、同じ表にまとめる
- 表計算の機能で、前年同月の値と直近3か月の平均の2つの単純な見込みを作る
- 直近6か月について、その2つの見込みと実際の応募数を比べ、どれだけ外れたかを見る
- 外れた月について、担当者に理由を聞いて書き出す
この段階では機械学習を使いません。 確かめたいのは、手元のデータで「当てる」ことがどれだけ難しいかと、外れた理由がデータで説明できるかです。
| 出てきた内容 | 判断 |
|---|---|
| 単純な見込みでも大きく外れ、理由が掲載や時期で説明できる | モデルで改善できる余地がある。本格構成に進む |
| 単純な見込みでほぼ当たる | 表計算の見込みで十分。 モデルは要らない |
| 掲載の記録が欠けていて比べられない | 掲載の記録の整備が先。 モデルの問題ではない |
2行目が出たら、それは良い結果です。 単純な見込みで当たる募集は、表計算のままで運用し、外れる募集だけにモデルを使うことも考えられます。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 後から公表された統計を学習に入れる | 予測する時点で公表済みの値だけを使う |
| 検証で月をシャッフルしてしまう | TimeSeriesSplit で時間の順を守る。 gap で1か月空ける |
| 掲載していない月の0件を学習に入れる | 掲載の記録と結合し、掲載した月だけを学習に使う |
| 掲載の記録の漏れを「掲載なし」と扱う | 要確認として人に聞く |
| 応募数に負の予測値が出る | loss='poisson' を使う(目的の値が0以上の前提) |
| 1本の見込みだけで判断する | 控えめな見込みを別のモデルで出す |
| 予測のモデルで追加の案の効果を出す | 相関であって効果ではない。過去の実績だけを並べる |
| 新しい媒体に、もっともらしい予測が出る | 実績が6か月未満なら予測しない |
| 媒体のプランの名前が変わる | 新旧の対応表を持つ |
| 同じ人が複数の媒体から応募する | 数え方を先に決める |
| 時給を高くすれば応募が増えると読む | 時給は相関の1つ。時給の判断は別に行う |
上の2行が、この構成の失敗のほとんどです。 どちらも、検証では良く当たるのに、本番では外れるという同じ形で表れます。本番で手に入らない情報を、学習のときに使っているからです。
下から5行目と最後の行も、早い時期に効いてきます。 予測のモデルの中で「プラン」や「時給」が応募数に効いているように見えても、それは過去にそうした組み合わせが多かったというだけで、変えれば増えるとは限りません。 案には実績だけを並べ、効果の数字を書かないことで守ります。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 媒体ごとの応募の件数、掲載のプランと費用、提示した時給、採用の結果の件数、店舗ごとの採用計画です。応募者の氏名や連絡先は扱いません。
- 個人を特定できる列を最初に外す … 応募者管理システムの書き出しの段階で、氏名・連絡先・年齢・住所を外します。予測に要るのは件数だけです
- 少ない件数の集計に気をつける … 小さいエリアの職種で月に応募が1〜2件だと、件数と応募日から個人が推測できることがあります。採用課の外に出す表では、少ない件数をまとめて示します
- 採用の基準と予測を混ぜない … この構成が見込むのは応募の数で、どの応募者を採るかの判断には使いません。 歩留まりの計算に採用の結果を使いますが、個人ごとの結果はモデルに入れません
- この構成は時給や採用の方針を決めない … 時給の水準をどう変えるか、どの層を採るかは、人事と経営が決めることです。 予測のモデルの中の時給の効き方を、時給を決める根拠に使わないでください
- 予算を伴う実行を自動にしない … 媒体への申し込みは、採用課が決めて行います
- 掲載の費用と採用計画の閲覧範囲を絞る … 店舗ごとの採用計画は、出店や改装の予定を含みます。採用課と店舗開発部の外に出さない場所に置きます
誤りが起きた場合のリスクは、不足を見落として店舗が人手不足のまま1か月を過ごすことと、不要な掲載を足して費用をかけすぎることの2つです。 前者は1本の見込みだけで判断すると起き、後者は予測のモデルで案の効果を見積もると起きます。控えめな見込みで判定し、案には実績だけを並べることで、両方を抑えます。
10まず何から始めるか
1週目:掲載の記録をそろえる
直近の3年分について、媒体・プラン・掲載の開始日と終了日・提示した時給・掲載した店舗の数を、月 × 媒体 × 職種 × エリアで1行になる形にそろえます。プランの名前の新旧の対応表も作ります。
2週目:単純な見込みで試す
第8章の手順で、前年同月と直近3か月の平均の2つの見込みを作り、直近6か月の実績と比べます。外れた月について、担当者に理由を聞いて書き出します。 これが、どの特徴量を入れるかの材料になります。
3週目:取り込みと不足の判定をつなぐ
Python で応募者管理システムの書き出し、掲載の記録、採用計画、統計を取り込み、必要な応募数と不足の判定までを自動にします。この時点では予測を入れず、単純な見込みのまま判定します。
4週目:予測のモデルを入れる
scikit-learn で2本の見込みのモデルを作り、TimeSeriesSplit で検証します。単純な見込みより外れが小さくなっているかを、媒体ごと・エリアごとに確かめます。 小さくならない組み合わせは、単純な見込みのまま使います。
2か月目: 予測と単純な見込みを並べて採用課に見せ、どちらが当たったかを毎月数えます。3か月目以降: 追加の案と外れた理由の記録を足し、1件30分が何分になったかを実測します。外れた理由の記録から特徴量を1つ足して、外れが減ったことを確かめられた時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
ヒストグラムにもとづく勾配ブースティングの回帰木で、データが大きい(1万件以上)場合に GradientBoostingRegressor より速いこと。loss に 'poisson'(目的の値が0以上)と 'quantile'(quantile を指定)があること。欠けた値(NaN)を扱えること。categorical_features の既定が 'from_dtype' であること | scikit-learn: HistGradientBoostingRegressor | 2026-10-06 |
時系列のデータのための分割で、通常の交差検証と違ってシャッフルしないこと。学習の期間が前の回を含んで広がること。n_splits(既定5)、test_size、gap、max_train_size を指定できること | scikit-learn: TimeSeriesSplit | 2026-10-06 |
| 一般職業紹介状況が、公共職業安定所における求人、求職、就職の状況(新規学卒者を除く)を取りまとめ、求人倍率等の指標を作成することを目的とすること | 厚生労働省: 一般職業紹介状況 統計の概要 | 2026-10-06 |
| 一般職業紹介状況として統計表が毎月公表されていること。年度単位で、都道府県別・職業別(中分類)などのより詳細な区分の集計が公表されていること | 厚生労働省: 一般職業紹介状況 雇用関係指標(年度) | 2026-10-06 |
予測の結果を採用の方針や時給の判断に使うときは、人事と経営で別に検討してください。 本記事は、公開資料で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-0577)についてのご相談はこちらから。
