応募経路ごとの応募・選考・入社と入社後の定着を Python で分析し、定着した1人あたりの採用単価から来月の採用予算の配分案を出す
応募経路と職種ごとに、応募・面接・入社の数と入社後に辞めた時期をつなぎ、入社90日後に残っている見込みを出します。その見込みで割った「定着した1人あたりの採用単価」から、来月の経路ごとの予算配分の案を作ります。
- 連携・自動化
- Python
- 対象業界
- 人材/小売/物流/製造
- 対象部門
- 採用
- 対象業務
- 比較検討/集計・分析
- 主な課題
- データ分析に時間がかかる/判断に時間がかかる/属人化している
- AIで行う処理
- 予測
- 主な効果
- 判断支援/工数削減/機会損失防止
- 導入難易度
- ★★★★☆
- 実装レベル
- 本格構成
- 費用感
- 個別開発(大)
- 人間の確認
- 必須
01導入前 / 導入後の業務フロー
- 月初に、各媒体の請求書と管理表から、前月に経路ごとにいくら使ったかを集める
- 掲載の費用は、複数の職種の求人をまとめて出している媒体があるため、掲載した求人の数で職種に割る
- 採用管理の仕組みから、経路・職種ごとの応募・面接・採用・入社の数を書き出して数える
- 人事に依頼して、過去6か月の入社者の在籍・退職の一覧をもらう
- 応募IDと社員番号で入社者を突き合わせ、経路ごとに「辞めた人」の数を数える
- 応募単価と入社単価を計算し、辞めた人の多い経路にメモを付ける
- 媒体の担当者の提案と見比べながら、来月の配分を表計算で組み、責任者に出す
- 人月初に、媒体ごとの前月の費用を費用の管理表に入れる(請求書の確定を待って入れる)
- 自動毎月第3営業日の夜に、採用管理と人事の記録を書き出したファイルをプログラムが読み込む
- 自動応募IDと社員番号で入社者をつなぎ、つながらない記録を一覧にする
- 自動入社者ごとに、入社日から退職日まで(在籍中なら集計日まで)の日数と、辞めたかどうかを作る
- 自動経路・職種ごとに、入社後90日と180日に残っている割合を、在籍中の人を途中までの記録として扱って見込む
- 自動職種・拠点・勤務の形の違いをそろえたうえで、経路ごとの辞めやすさを比べる
- 自動経路・職種ごとに、応募から入社までの歩留まりと、定着した1人あたりの採用単価を出す
- 自動予算の上限・契約の最低額・職種ごとの必要人数を条件に、期待できる定着人数が最も多くなる配分の案を出す
- 自動入社者が少ない組み合わせ、見込みの幅が広い組み合わせ、前月から配分が大きく動く経路に印を付ける
- 人採用企画の担当が、印の付いた組み合わせだけを開いて確かめ、配分の案を直す
- 人責任者が配分を決め、媒体との契約の変更が要るものは担当が媒体と話す
各工程の詳しい説明を読む
- 月初に、各媒体の請求書と管理表から、前月に経路ごとにいくら使ったかを集める
- 掲載の費用は、複数の職種の求人をまとめて出している媒体があるため、掲載した求人の数で職種に割る
- 採用管理の仕組みから、経路・職種ごとの応募・面接・採用・入社の数を書き出して数える
- 人事に依頼して、過去6か月の入社者の在籍・退職の一覧をもらう
- 応募IDと社員番号で入社者を突き合わせ、経路ごとに「辞めた人」の数を数える
- 応募単価と入社単価を計算し、辞めた人の多い経路にメモを付ける
- 媒体の担当者の提案と見比べながら、来月の配分を表計算で組み、責任者に出す
(a)応募単価が安い経路に予算が寄る。 媒体の担当者が持ってくる数字は応募単価で、比べやすいのもこの数字です。入社後のことを数えるには人事の記録が要り、毎月そこまで手が回りません。 結果として、応募は多いが現場に残らない経路に予算が寄ります。
(b)辞めた人の数え方が毎月違う。 5番目の作業は、半年前に入社した人と先月入社した人を同じ一覧で数えます。先月の入社者はまだほとんど辞めていないので、最近始めた経路ほど成績がよく見えます。 担当者によって「入社3か月以上の人だけ数える」「全員数える」が分かれ、月ごとに比べられる数字になっていません。
(c)職種の違いと経路の違いが混ざる。 コールセンターは製造ラインより辞める人が多い職種です。コールセンターの求人を多く出している経路は、経路のせいではなく職種のせいで成績が悪く見えます。 表計算で職種ごとに分けると、1つのセルの入社者が数名になり、比べる意味が薄れます。
(d)配分の組み立てが1人の頭の中にある。 予算の上限、媒体ごとの契約の最低額、職種ごとに必要な人数を同時に満たす組み合わせを、長く担当している1名が経験で組んでいます。 その人が休むと、前月の配分をそのまま引き継ぐことになります。
- 【人】 月初に、媒体ごとの前月の費用を費用の管理表に入れる(請求書の確定を待って入れる)
- 【自動】 毎月第3営業日の夜に、採用管理と人事の記録を書き出したファイルをプログラムが読み込む
- 【自動】 応募IDと社員番号で入社者をつなぎ、つながらない記録を一覧にする
- 【自動】 入社者ごとに、入社日から退職日まで(在籍中なら集計日まで)の日数と、辞めたかどうかを作る
- 【自動】 経路・職種ごとに、入社後90日と180日に残っている割合を、在籍中の人を途中までの記録として扱って見込む
- 【自動】 職種・拠点・勤務の形の違いをそろえたうえで、経路ごとの辞めやすさを比べる
- 【自動】 経路・職種ごとに、応募から入社までの歩留まりと、定着した1人あたりの採用単価を出す
- 【自動】 予算の上限・契約の最低額・職種ごとの必要人数を条件に、期待できる定着人数が最も多くなる配分の案を出す
- 【自動】 入社者が少ない組み合わせ、見込みの幅が広い組み合わせ、前月から配分が大きく動く経路に印を付ける
- 【人】 採用企画の担当が、印の付いた組み合わせだけを開いて確かめ、配分の案を直す
- 【人】 責任者が配分を決め、媒体との契約の変更が要るものは担当が媒体と話す
10番目が、この設計の分かれ目です。 40の組み合わせのすべてを人が読み直すのではなく、数が少なくて当てにならないもの、大きく動くものだけに時間を使います。 全件を見直す運用にすると、時間はほとんど減りません。
8番目の計算が出すのは「この条件ならこの配分」という案で、条件のほうを変えるのは人です。
02今回想定するシステム構成
採用管理の仕組み(応募・面接・採用・入社の記録の書き出し) 人事・給与の仕組み(社員番号・入社日・退職日・職種・拠点の書き出し) 費用の管理表(経路 × 月の費用、契約の最低額) │ ▼【トリガー】毎月第3営業日の夜 Python(pandas) ├──▶ 応募IDと社員番号で入社者をつなぐ/つながらない記録の一覧 ▼ lifelines │ KaplanMeierFitter … 経路・職種ごとの90日・180日の定着の見込み │ CoxPHFitter … 職種・拠点・勤務の形をそろえた経路ごとの辞めやすさ ▼ Python ── 歩留まり、定着した1人あたりの採用単価 ▼ SciPy(linprog)── 予算・最低額・必要人数を条件にした配分の案 ▼ 【人が印の付いた組み合わせだけ確認】── 採用企画の担当 ▼ 配分の案の表(共有フォルダ)── 責任者の決定へ
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Python(pandas・lifelines・SciPy) | R(survival パッケージ) |
| 処理エンジン | lifelines の KaplanMeierFitter と CoxPHFitter | scikit-survival、statsmodels の PHReg |
| 集計 | Python(歩留まり・単価の計算と、SciPy の linprog による配分の計算) | 表計算のソルバー |
| データの取得元 | 採用管理と人事・給与の仕組みからの書き出し | 各仕組みの連携の機能 |
| 結果の出力先 | 共有フォルダの配分の案の表 | 採用企画の会議資料 |
採用管理と人事・給与の仕組みは、新しく足すものではありません。 どちらからも書き出すだけで、この構成から記録を書き換えることはしません。媒体との契約も変えません。 出すのは配分の案までです。
土台になるのは、lifelines の KaplanMeierFitter です。 右側が打ち切られたデータ(まだ退職が起きていない人を含むデータ)から、カプラン・マイヤー法で生存関数(ある日数の時点でまだ残っている割合)を推定します。退職が観測されなかった人は、観測された期間までは推定に加わり、退職した人としては数えられません。 第3章の(b)の偏りを外すのは、この扱いです。
職種の違いをそろえるには、CoxPHFitter を使います。 比例ハザードモデル(辞めやすさが、項目ごとの倍率で決まると置くモデル)で、duration_col に日数の列、event_col に辞めたかどうかの列を渡します。比例の前提が崩れる項目は strata で層に分けられ、penalizer で係数の大きさに罰則を付けられます。 入社者の少ない組み合わせで係数が大きく振れるのを抑えるために使います。
配分の計算には、SciPy の linprog を使います。 線形の目的を条件のもとで最小化する関数で、既定の解法は 'highs' です。最大にしたい量は符号を反転して渡します。 変数の範囲は既定で下限0・上限なしです。
03どうやって実装するのか
処理の起点を決める
毎月第3営業日の夜に動かします。 媒体の請求は月初の数日で確定し、それより前に動かすと費用が欠けた月の単価が出ます。費用の管理表に前月の行がそろっていなければ動かさず、担当者に知らせます。 欠けたまま計算すると、その経路だけ単価が安く出ます。
人事の記録は、前月末時点の在籍の状態で書き出します。月の途中で書き出すと、月末に退職の手続きをした人が在籍として残ります。退職日の記録が入るまでの遅れは会社ごとに違うので、最初の3か月は、前月に辞めた人が書き出しに載っているかを人事と確かめます。
同じ月の中で作り直すのは、費用の訂正が入ったときと、人事の記録の誤りが直ったときだけです。作り直したら、前の版を残したまま新しい版を作ります。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 応募の記録 | 応募ID、経路、職種、拠点、応募日、面接日、合否、入社日 | 採用管理の仕組み |
| 在籍の記録 | 社員番号、応募ID、職種、拠点、勤務の形(日勤・交替勤務)、時給の帯、入社日、退職日 | 人事・給与の仕組み |
| 費用の記録 | 経路 × 月の費用、払い方(掲載・クリック・採用ごと・無料)、契約の最低額 | 費用の管理表 |
| 掲載の記録 | 経路 × 職種 × 月の掲載した求人の数 | 採用企画の掲載の一覧 |
| 来月の条件 | 予算の上限、職種ごとの必要な入社人数、経路ごとの上限・下限 | 採用企画の担当が入れる |
質を決めるのは、在籍の記録の応募IDです。 ここが空だと、入社者がどの経路から来たか分かりません。応募IDの書き写しが漏れている入社者が多い月は、計算の前に人事と埋めます。
性別・年齢・国籍・住所は、入力に入れません。 経路の成績を比べるのに要らない項目で、入れると「この属性の人は辞めやすい」という形で採用の判断に戻ってくるおそれがあります。入れない項目を決めておくことが、この構成の前提です。
データの取得方法を決める
採用管理の仕組みと人事・給与の仕組みから、決まった列の並びで表の形に書き出す設定を作り、共有フォルダの決まった場所に置きます。どちらの仕組みも、画面から書き出す機能か、連携の機能のどちらかで足ります。連携の機能で自動化するかは、それぞれの仕組みの提供元に確かめます。 最初は担当者が月に1回書き出す運用で始められます。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 応募から入社までの記録 | 採用管理の書き出し | 歩留まりと入社者の経路 |
| 入社日・退職日 | 人事の書き出し | 入社から退職までの日数と、辞めたかどうか |
| 職種・拠点・勤務の形 | 人事の書き出し | 経路の違いと職種の違いを分ける |
| 費用と払い方 | 費用の管理表 | 単価の分子 |
| 掲載した求人の数 | 掲載の一覧 | 職種をまたぐ掲載費用の割り振り |
つなぐ順は、応募IDが先です。 応募IDでつながらない入社者は、社員番号と入社日で採用管理の「入社」の記録を探しますが、氏名ではつなぎません。 同姓同名と表記の違いで、別の人を同じ人として数えることがあるからです。
AIへ渡す前に整形する
- 入社者をつなぐ … 応募IDで採用管理と人事の記録をつなぎ、つながらないものを
unlinkedの一覧に出します - 同じ人の2回目の応募をまとめる … 同じ人が複数の経路から応募していたら、入社につながった応募の経路を採ります。その規則を設定に書いておきます
- 日数を作る … 入社日から退職日まで、在籍中の人は集計日までの日数を作り、辞めたかどうかの列(辞めた 1、在籍中 0)を作ります
- 会社の都合の終了を分ける … 取引先の契約が終わって現場ごと閉じたことによる退職は、本人が辞めたのではないので、辞めた人として数えません。 集計日で途中までの記録として扱います
- 費用を割り振る … 複数の職種を1つの掲載で出している媒体の費用は、掲載した求人の数で職種に割ります
- 入社月をそろえる … 単価は入社した月の費用で割ります。費用を払った月と入社した月がずれる経路(採用ごとに払う紹介など)は、入社月に寄せます
- 少ない組み合わせを確かめる … 経路 × 職種で過去12か月の入社者が20名に満たない組み合わせに
few_hiresの印を付けます
4番目を軽く見ないでください。 取引先の工場のラインが止まって30名が一度に契約終了になると、その月に多く採用していた経路だけが「すぐ辞める経路」に見えます。辞めた理由の区分を人事の記録から取り、本人の都合と会社の都合を分けます。
AIに処理させる
させるのは、経路・職種ごとに「入社後の日数ごとに残っている割合」を見込むことと、職種などの違いをそろえた経路ごとの辞めやすさを比べることです。 歩留まり、単価、配分の計算は、決まった式で行います。
| 見込むもの | 使うもの | 判断できないときの扱い |
|---|---|---|
| 90日・180日に残っている割合(幅つき) | 経路・職種ごとの入社から退職までの日数と、辞めたかどうか | 入社者が20名未満なら few_hires |
| 職種などをそろえた経路ごとの辞めやすさ | 経路、職種、拠点、勤務の形、時給の帯 | 比例の前提が崩れる項目は層に分ける |
| 来月の定着人数の見込み | 来月の入社の見込み × 90日に残っている割合 | 幅の下側を別に持つ |
右端の列が、人が見る組み合わせを決めます。 入社者が少ない組み合わせは、90日に残っている割合の幅が広くなります。幅は KaplanMeierFitter の confidence_interval_ で取れ、 グリーンウッドの式(指数・対数対数の形)で出されます。幅の下側と上側の差が30ポイントを超えるものには wide を付けます。
90日を基準にするのは、この会社の現場の仕事が3か月で一通り身に付くからです。 基準の日数は会社ごとに決めます。基準の日数より最近に入社した人は、その日数の時点の割合には直接は効きませんが、それまでの日数の推定には加わります。 これが途中までの記録として扱う意味です。
経路ごとの比べ方は2段にします。 1段目は KaplanMeierFitter で経路・職種ごとの割合をそのまま出し、2段目は CoxPHFitter で職種・拠点・勤務の形をそろえた辞めやすさの倍率を出します。1段目で悪く見えて2段目で差が消える経路は、経路ではなく職種の問題です。 第3章の(c)を、この2段で切り分けます。
| させないこと | 理由 |
|---|---|
| 個々の応募者が辞めるかどうかの予測 | 採用の合否に使われるおそれがある。見込むのは経路ごとの割合だけ |
| 性別・年齢・国籍などでの比べ方 | 公正な採用の考え方に反し、経路の比較にも要らない |
| 媒体との契約を変える判断 | 契約の期間・解約の条件は人が媒体と話す |
| 辞めた理由の推測 | 人事の記録の区分だけを使う |
| 費用の補完 | 管理表に無い月の費用を前月の値で埋めない |
1行目がいちばん起きやすい失敗です。 経路ごとの辞めやすさを出す仕組みは、少し変えると応募者1人ずつの「辞めそうな度合い」を出せます。それを選考に使うと、経路の比較ではなく応募者の選別になります。 プログラムは経路・職種の単位でしか出力しない作りにします。
指示内容を固定する
この構成は生成AIを使わないので、プロンプトの代わりに、モデルの設定と計算の規則を書いておきます。
【定着の見込み(経路 × 職種ごと)】
- KaplanMeierFitter
・durations = 入社日から退職日(在籍中は集計日)までの日数
・event_observed = 本人の都合で辞めたら 1、在籍中・会社の都合の終了は 0
・対象 = 過去24か月に入社した人
・survival_function_at_times([90, 180]) で90日・180日に残っている割合
・confidence_interval_ の下側を lower、上側を upper として残す
【経路の辞めやすさの比べ方】
- CoxPHFitter
・duration_col = days、event_col = left
・項目 = 経路、職種、拠点、勤務の形、時給の帯(性別・年齢・国籍は入れない)
・penalizer = 0.1(入社者の少ない経路で係数が振れるのを抑える)
・比例の前提が崩れる項目(例:職種)は strata に移す
・基準の経路 = 自社の採用サイト
【歩留まりと単価】
- 応募 → 面接 → 採用 → 入社 の各段の割合(過去6か月)
- 入社単価 = 入社月の費用 ÷ 入社した人数
- 定着した1人あたり = 入社単価 ÷ 90日に残っている割合
- 定着した1人あたり(下側) = 入社単価 ÷ 90日に残っている割合の lower
【配分の計算(linprog)】
- 変数 x_i = 来月の経路 i の費用
- 目的 = Σ x_i ÷ 定着した1人あたり(下側)を最大にする
(linprog は最小化なので符号を反転して c に渡す)
- 条件 = Σ x_i ≦ 予算の上限
職種 j について Σ (x_i ÷ 入社単価_ij) ≧ 職種 j の必要な入社人数
- 範囲 = 契約の最低額 ≦ x_i ≦ 過去12か月の最大の月の 1.3 倍
(その範囲を超えると単価が同じとは言えないため)
- 無料の経路と採用ごとに払う経路は、上限人数を条件に入れる
【印を付ける条件】
- few_hires … 過去12か月の入社者が20名未満
- wide … 90日の割合の upper − lower が 30 ポイント超
- unlinked … 入社者のうち経路とつながらない人が 5%超
- shift … 配分の案が前月から 30%以上動く経路
- infeasible… linprog の status が 2(条件を満たす配分が無い)
- 印の無い組み合わせは、一覧で流し見て責任者へ渡す
目的に下側の値を使うのは、意図してのことです。 真ん中の値で計算すると、入社者が少なく幅の広い経路が、たまたまよい月に引っ張られて大きく配分されます。下側で計算すれば、数が少ない経路は控えめに扱われます。 新しい経路を試したいときは、その経路の下限を人が決めて入れます。
範囲の上限を「過去の最大の月の1.3倍」で切るのも同じ理由です。 線形計画は、単価が費用にかかわらず同じだと置いて計算します。実際には、同じ媒体に倍の費用を出しても入社者は倍になりません。 過去に試した範囲から大きく外れる配分は出さないようにします。
出力形式を固定する
経路 × 職種ごとに、次の形のJSONを作り、表にして共有フォルダへ書き出します。
{
"month": "",
"channel": "",
"job_type": "",
"funnel": { "applied": 0, "interviewed": 0, "offered": 0, "hired": 0 },
"cost": 0,
"cost_per_hire": 0,
"retention": {
"d90": { "estimate": 0, "lower": 0, "upper": 0 },
"d180": { "estimate": 0, "lower": 0, "upper": 0 },
"at_risk_d90": 0
},
"cost_per_retained": { "estimate": 0, "lower_based": 0 },
"hazard_ratio_vs_base": { "value": 0, "lower": 0, "upper": 0 },
"allocation": { "last_month": 0, "proposed": 0 },
"flags": ["few_hires | wide | unlinked | shift | infeasible"],
"model_version": "",
"planner_override": { "proposed": null, "reason": "" }
}
1つ目の理由は、cost_per_hire と cost_per_retained を並べて見せられることです。 入社単価が安くても、定着した1人あたりで高い経路があります。2つの差が大きい経路が、第3章の(a)で予算が寄っていた経路です。
2つ目は、at_risk_d90 を出せることです。 90日の時点まで観測できた人の数で、この数が少ないと、割合がどれほど確かでも当てになりません。 担当者は割合の前にこの数を見ます。
3つ目は、planner_override で直した記録が残ることです。 担当が配分を直したら、ここに値と理由を書きます。計算の案と人の判断の両方が残り、 3か月後にどちらの経路から残る人が来たかを比べられます。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 採用管理の仕組み | 書き出したファイルの読み込み | 応募から入社までの記録 |
| 人事・給与の仕組み | 書き出したファイルの読み込み | 入社日・退職日・退職の区分・職種・拠点 |
| 費用の管理表 | 共有フォルダの表の読み込み | 経路 × 月の費用、契約の最低額 |
| 配分の案の表 | 共有フォルダへの書き出し | 経路 × 職種の単価・定着・配分の案 |
| 採用企画の連絡の場 | 通知 | 印の付いた件数と、表の場所 |
採用管理と人事の仕組みへは書き込みません。 出すのは分析の結果と配分の案までで、媒体の掲載を変える作業は担当者が行います。 書き込みを足すと、計算の誤りがそのまま来月の掲載に進みます。
人事の記録は、分析に必要な列だけを書き出します。 氏名、住所、給与の額は書き出しの設定から外します。
人が確認する
人が開くのは、印の付いた組み合わせだけです。 印の無いものは一覧で単価と配分の動きを流し見ます。全件を開く設計にすると、第10章の10.0時間には収まりません。
unlinkedを先に見る … 経路とつながらない入社者が多いと、どの経路の数字も低めに出ます。人事と応募IDを埋めてから計算し直しますinfeasibleを見る … 予算の上限で職種ごとの必要人数を満たせないということです。予算か必要人数のどちらを動かすかを責任者に上げますfew_hiresとwideを見る … 数が少ない組み合わせは、割合よりもat_risk_d90と現場の声で判断しますshiftを見る … 配分が大きく動く経路は、媒体との契約の期間と解約の条件を確かめます- 直したら理由を書く …
planner_overrideに値と理由を残します
4番目を省かないでください。 計算は契約の期間を知りません。半年の掲載を契約している媒体の費用を翌月から減らす案は、実行できません。 契約の最低額を条件に入れ忘れた経路が、この印で見つかります。
例外に対処する
| 起きること | 対応 |
|---|---|
| 費用の管理表に前月の行が無い | 計算を止め、担当者に知らせる。前月の値で埋めない |
| 入社者の応募IDが空 | unlinked に出し、人事と埋める。氏名でつながない |
| 同じ人が複数の経路から応募 | 入社につながった応募の経路を採る。規則を設定に残す |
| 現場ごとの契約終了で一度に退職 | 会社の都合の終了として、辞めた人に数えない |
| 新しく始めた経路 | 入社者が20名に達するまで few_hires。配分は人が下限を決める |
| 比例の前提が崩れる | その項目を strata に移し、比べ方の版を上げる |
| 条件を満たす配分が無い | status が 2。infeasible を付けて責任者に上げる |
| 経路の名前が仕組みごとに違う | 経路の対応表で名前をそろえる。対応表に無い名前が出たら止める |
| 再入社の人 | 2回目の入社を別の入社として扱い、前回の在籍とはつながない |
上から2行目と4行目が大半を占めます。 どちらもモデルの問題ではなく、記録の付け方の問題です。 入社の手続きで応募IDを必ず書き写す、退職の理由の区分を必ず付ける、という運用を直すほうが、計算の工夫より効きます。
記録を残す
- 読み込んだ書き出しのファイルと、書き出した日時
- つないだ結果の表と、
unlinkedの一覧 - 経路・職種ごとの定着の見込み、幅、
at_risk_d90 - 辞めやすさの倍率と、そのときの項目の一覧、
strataの設定 - 配分の計算の条件(予算・最低額・必要人数・範囲)と、linprog の
statusとmessage - 担当者が直した値と理由
- 3か月後・6か月後に、実際に残った割合と見込みとの差
最後の行が、この構成を育てる材料になります。 3か月前に「90日に残る割合は7割」と見込んだ経路から入社した人が、実際に何割残ったかを毎月並べます。外れ続ける経路は、媒体の側で求人の出し方が変わっていることが多く、媒体の担当者と話す材料になります。
04実装レベルの3段階
最小構成では、最近の入社者が使えません。 90日たっていない人を外すので、新しく始めた経路や最近条件を変えた経路は数が足りません。確かめるための段階です。 半自動化で、集計と突き合わせの時間はほぼ無くなります。 ただし、配分の案を組む作業は表計算で残ります。本格構成で、担当が見るのは印の付いた組み合わせだけになり、この段階が本記事の想定です。 差が大きいのは、予算と最低額と必要人数を同時に満たす組み合わせを探す作業が、毎月の手作業だからです。 段階を飛ばさないでください。 半自動化の一覧を3か月並べると、unlinked の多い月と、会社の都合の終了が混ざっている現場が先に分かります。
05工数削減シミュレーション
導入後 40件 × 15分 ÷ 60 = 10 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 工場・倉庫・コールセンターなどの請負や派遣の現場で働くスタッフを、毎月数十名から百名を超えて採用している人材会社。求人媒体、求人検索エンジン、自社の採用サイト、紹介など10前後の経路に予算を出していて、媒体の担当者が出す「応募単価」で配分を決めている場合。採用しても3か月以内に辞める人が多く、経路によって辞め方が違う気がするが数字で確かめられていない場合。採用管理の仕組みと人事の在籍の記録を、社員番号や応募IDでつなげる場合。
- 採用が年に数名で、経路ごとの入社者が統計として扱える数にならない場合。応募経路を記録しておらず、誰がどの媒体から来たか分からない場合。採用管理の記録と人事の在籍の記録をつなぐ番号が無く、氏名でしか突き合わせられない場合。なお、誰を採用するか、個々の応募者の合否、媒体との契約の判断は、この構成では代替できません。
07最小構成で試す方法
- 過去12か月の入社者の一覧を人事からもらう(社員番号、応募ID、職種、入社日、退職日、退職の区分)
- 採用管理の仕組みから、同じ期間の応募の記録を書き出し、応募IDで経路をつなぐ
- 表計算で、入社月ごと・経路ごとに「入社して90日たった人」だけを選び、そのうち90日の時点で在籍している割合を出す
- 同じ期間の経路ごとの費用を割り、入社単価と「入社単価 ÷ 90日に残っている割合」を並べる
- いまの配分と比べ、順位が大きく入れ替わる経路を3つ書き出す
3番目の「90日たった人だけを選ぶ」を必ず守ってください。 途中までの記録の扱いは表計算では難しいので、まだ90日たっていない人を外して数えます。 最近の数か月の入社者は使えなくなりますが、偏りは入りません。
| 出てきた内容 | 判断 |
|---|---|
| 入社単価と定着した1人あたりで、順位が入れ替わる経路がある | Python で分析と配分の計算に進む |
| どの経路も残る割合がほぼ同じ | 経路より職種や現場の違いが大きい。職種ごとに見直す |
| 応募IDでつながらない入社者が多い | 入社の手続きの運用を直すのが先 |
3行目が出ることは珍しくありません。 応募IDの書き写しを入社の手続きの必須の項目にしてから、3か月後にもう一度試してください。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 在籍中の人を「辞めなかった人」として数える | 途中までの記録として扱う。 新しい経路ほどよく見える偏りが出る |
| 会社の都合の終了が「辞めた」に入る | 退職の区分で分け、本人の都合だけを数える |
| 職種の違いが経路の違いに見える | 経路・職種ごとの割合と、職種をそろえた倍率の2段で見る |
| 入社者が少ない組み合わせの割合を信じる | at_risk_d90 と幅を先に見る。配分の計算では下側を使う |
| 応募IDでつながらない入社者が多い | 入社の手続きで書き写しを必須にする。氏名でつながない |
| 線形計画が1つの経路に予算を寄せる | 過去に試した範囲で上限を切る。単価が費用によらず同じという前提を忘れない |
| 契約の期間を無視した配分が出る | 契約の最低額を下限に入れ、shift で見る |
| 応募者ごとの辞めそうな度合いに作り替えられる | 出力を経路・職種の単位に限る作りにし、選考に使わない |
| 性別・年齢を項目に入れたくなる | 入れない。公正な採用の考え方に反し、経路の比較にも要らない |
| 費用の欠けた月が混ざる | 管理表に行が無ければ止める |
上の2行が、この構成の失敗のほとんどです。 どちらも「辞めた人 ÷ 入社した人」という素直な数え方から出てきます。数え方の偏りを外すことが、この構成をわざわざ Python で組む理由です。
下から3行目と2行目も、早く問題になります。 経路の分析の仕組みができると、「この人は辞めそうか」を出してほしいという声が出ます。最初から作らないと決めておいてください。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 応募者の応募の記録と選考の結果、スタッフの入社日・退職日・退職の区分・職種・拠点・時給の帯です。氏名や連絡先は使いませんが、社員番号と応募IDで個人にたどれる記録です。
- 求職者の個人情報を、目的の範囲で使う … 職業安定法第5条の5は、労働者の募集を行う者などが求職者等の個人情報を収集・保管・使用するときは、業務の目的の達成に必要な範囲内で、目的を明らかにして行い、収集の目的の範囲内で保管・使用することを求めています(本人の同意がある場合その他正当な事由がある場合を除く)。応募者の記録を募集の方法の改善に使うことを、応募の時点で示す目的に含めているかを、法務と確かめてください
- 出力を経路・職種の単位に限る … 個人ごとの予測を出さない作りにします。選考の判断に流れ込む経路を、仕組みの側で断ちます
- 性別・年齢・国籍などを入力に入れない … 経路の比較に要らない項目は、書き出しの設定から外します
- 外部のサービスに記録を出さない … 計算は社内の環境の Python で行います。生成AIのサービスに入社者の一覧を貼り付けて分析させる使い方はしません
- アクセスできる人を絞る … つないだ表には、応募から退職までの記録が1行にまとまります。採用企画の2名と責任者に限り、保存する場所を分けます
- 配分を自動で実行しない … 出すのは案までです。媒体の掲載の変更は、人が契約を確かめてから行います
誤りが起きた場合のリスクは、よい経路の予算を削ることと、すぐ辞める経路に予算を寄せることの2つです。 前者は入社者の少ない経路の割合を信じると起き、後者は在籍中の人を辞めなかった人として数えると起きます。
10まず何から始めるか
1週目:入社者と経路をつなぐ
人事に過去12か月の入社者の一覧をもらい、応募IDで採用管理の記録とつなぎます。つながらない入社者が何割いるかを数えます。2割を超えるなら、入社の手続きで応募IDを書き写す運用を直すところから始めます。
2週目:90日たった人だけで比べる
第8章の手順で、90日たった入社者だけを使い、経路ごとの定着した1人あたりの単価を表計算で出します。いまの配分と順位が入れ替わる経路があるかを見ます。
3週目:退職の区分と契約の条件をそろえる
人事の記録で、本人の都合の退職と会社の都合の終了を分けられるかを確かめます。分けられないなら、区分を付ける運用を人事と決めます。 あわせて、費用の管理表に契約の最低額と期間を足します。
4週目:Python で定着の見込みを出す
lifelines で経路・職種ごとの90日の割合と幅を出し、2週目の表計算の結果と比べます。この時点では配分の計算はせず、定着の見込みの一覧だけを見ます。
2か月目: 職種をそろえた比べ方と配分の計算を足し、印付けを入れます。担当者が直した件数と理由を毎月数えます。3か月目以降: 3か月前の見込みと実際に残った割合を並べ、1件45分が何分になったかを実測します。外れ続ける経路について媒体の担当者と求人の出し方を話した時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
右側が打ち切られたデータからカプラン・マイヤー法で生存関数を推定すること。fit() が durations・event_observed(省略時は全員に事象が起きたと扱う)・entry・timeline・label を取ること。事象が観測されなかった人は観測された期間まで推定に加わり、事象としては数えられないこと。survival_function_at_times で指定した時点の値を返すこと。confidence_interval_ がグリーンウッドの指数(対数対数)の式によること。median_survival_time_ | lifelines: KaplanMeierFitter | 2026-10-15 |
比例ハザードモデルであること。fit() の duration_col・event_col(省略時は全員が打ち切りなしと扱う)・strata(比例の前提が崩れる項目の層別)・penalizer(係数の大きさへの罰則)。基準のハザードの推定の既定が "breslow" であること。predict_survival_function と summary | lifelines: CoxPHFitter | 2026-10-15 |
線形の目的 c @ x を最小化すること(最大化は符号を反転する)。A_ub・b_ub・A_eq・b_eq・bounds の意味と、既定の範囲が下限0・上限なしであること。既定の解法が 'highs' であること。結果の x・fun・status(2は条件を満たす解が無い)・success・message | SciPy: scipy.optimize.linprog | 2026-10-15 |
| 労働者の募集を行う者などが求職者等の個人情報を収集・保管・使用するときは、業務の目的の達成に必要な範囲内で目的を明らかにして収集し、収集の目的の範囲内で保管・使用しなければならないこと。本人の同意がある場合その他正当な事由がある場合を除くこと。個人情報を適正に管理するために必要な措置を講じなければならないこと(第5条の5) | e-Gov 法令API: 職業安定法(昭和22年法律第141号) | 2026-10-15 |
応募者の記録をこの目的で使えるかは、応募の時点で示した利用目的と、自社の法務の判断で確かめてください。 本記事は上記の公開資料で確認できた範囲だけを扱っており、厚生労働省の指針の細目は扱っていません。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1746)についてのご相談はこちらから。
