ゴルフ場の予約記録から直前のキャンセルが出やすい予約を予測し、空き枠の再販売とキャンセル待ちへの連絡の順番を出す
ゴルフ場に入っている予約1件ずつについて、プレー日の直前に取り消されるかの確率を見込みます。スタートの時間帯ごとに空きそうな組数の幅を出し、前日確認の連絡先、キャンセル待ちへの連絡の順番、空き枠を予約サイトに出す段取りの案にします。
- 連携・自動化
- Python
- 対象業界
- その他/宿泊
- 対象部門
- 営業
- 対象業務
- 比較検討/集計・分析
- 主な課題
- 判断に時間がかかる/属人化している/期限・対応漏れが起きる
- AIで行う処理
- 予測
- 主な効果
- 判断支援/属人化解消/機会損失防止
- 導入難易度
- ★★★☆☆
- 実装レベル
- 本格構成
- 費用感
- 個別開発(大)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 予約担当が、予約の管理の仕組みから見直すプレー日の予約一覧を出す
- 天気予報を見て、雨の見込みの日は取消が増えると見当を付ける
- 去年の同じ時期の取消を思い出しながら、取消が出そうな組に目星を付ける
- 目星を付けた組に、確認の電話を入れるかを決める(入れない日も多い)
- 取消が入ったら、キャンセル待ちの名簿を開き、時間帯と人数が合う人に順に電話する
- 埋まらなかった枠を、予約サイトの管理画面で販売に出す
- 自動毎朝6時、予約の管理の仕組みから予約・組・取消の記録を書き出す
- 自動Python が、3日後と翌日のプレー日の予約を、見直しの時点の状態に組み立てる
- 自動予約1件ごとに、見直しの時点からプレー日までに取り消される確率を見込む
- 自動スタートの時間帯ごとに確率を足し上げ、空きそうな組数の幅を出す
- 自動3日前の見直しでは、確率の高い予約を前日確認の連絡の対象として並べる
- 自動時間帯ごとの空きの見込みに合わせて、キャンセル待ちの名簿を連絡の順番に並べ直す
- 自動前日の朝の見直しでは、予約サイトに出す枠の数と時刻の案を出す
- 人予約担当が一覧を見て、確認の連絡を入れる組と、名簿の順番を決める
- 人取消が入ったら、並べ直した名簿の順に連絡し、残った枠を予約サイトに出す
- 自動プレー日が過ぎたら、見込みと実際の取消、埋まった枠の数を突き合わせて記録する
各工程の詳しい説明を読む
- 予約担当が、予約の管理の仕組みから見直すプレー日の予約一覧を出す
- 天気予報を見て、雨の見込みの日は取消が増えると見当を付ける
- 去年の同じ時期の取消を思い出しながら、取消が出そうな組に目星を付ける
- 目星を付けた組に、確認の電話を入れるかを決める(入れない日も多い)
- 取消が入ったら、キャンセル待ちの名簿を開き、時間帯と人数が合う人に順に電話する
- 埋まらなかった枠を、予約サイトの管理画面で販売に出す
(a)空きが分かるのが遅い。 取消は前日の夕方にまとまって入ります。5番目の電話を始められるのが夕方以降になり、翌朝のスタートに間に合う人が限られます。 予約サイトに出すのはさらに後で、売り切れずに空いたまま朝を迎える枠が出ます。
(b)目星の付け方が人によって違う。 3番目は担当者の記憶です。同じ雨の予報でも、ある担当は確認の電話を10組に入れ、別の担当は入れません。 担当が休みの日は、確認の電話そのものがありません。
(c)キャンセル待ちへの連絡が漏れる。 取消が重なる夕方は、名簿のどこまで電話したかが分からなくなります。受け付けた順が先の人を飛ばして、後の人に枠を案内してしまうことがあります。 後から苦情になるのは、この型です。
(d)見直しに時間がかかる。 1件20分でも月180件で60.0時間です。週末の前の木曜と金曜に見直しが集中し、ほかの電話の受付と重なります。
- 【自動】 毎朝6時、予約の管理の仕組みから予約・組・取消の記録を書き出す
- 【自動】 Python が、3日後と翌日のプレー日の予約を、見直しの時点の状態に組み立てる
- 【自動】 予約1件ごとに、見直しの時点からプレー日までに取り消される確率を見込む
- 【自動】 スタートの時間帯ごとに確率を足し上げ、空きそうな組数の幅を出す
- 【自動】 3日前の見直しでは、確率の高い予約を前日確認の連絡の対象として並べる
- 【自動】 時間帯ごとの空きの見込みに合わせて、キャンセル待ちの名簿を連絡の順番に並べ直す
- 【自動】 前日の朝の見直しでは、予約サイトに出す枠の数と時刻の案を出す
- 【人】 予約担当が一覧を見て、確認の連絡を入れる組と、名簿の順番を決める
- 【人】 取消が入ったら、並べ直した名簿の順に連絡し、残った枠を予約サイトに出す
- 【自動】 プレー日が過ぎたら、見込みと実際の取消、埋まった枠の数を突き合わせて記録する
8番目が、この設計の分かれ目です。 案は出しますが、確認の電話をかけるかどうかは予約担当が決めます。 長く通っている会員の組に確率だけで確認の電話を入れると、失礼に聞こえることがあるからです。
9番目の連絡も、いまと同じく人が行います。 名簿の人への電話や予約サイトへの掲出を自動にしないのは、空いた枠に誰を入れたかが、そのまま来場者どうしの公平さの話になるからです。 自動にするのは、連絡の順番と出す枠の案を作るところまでです。
6番目で名簿を並べ直しても、受け付けた順は崩しません。 同じ時間帯と人数の希望の中では、受け付けた順が先の人を必ず先に置きます。 並べ直すのは、空きそうな時間帯に合う希望を前に出すことだけです。
02今回想定するシステム構成
予約の管理の仕組み(予約・組・取消の記録、予約の経路、人数) │ 毎朝6時に前日までを書き出し ▼【トリガー】定時実行 Python(pandas) ├──▶ 見直しの時点(3日前・前日)の状態に組み立てる ├──▶ 予約ごとの特徴を作る(氏名・連絡先の列は読まない) ▼ scikit-learn(HistGradientBoostingClassifier+確率の較正) │ 予約1件ごとの「見直しの時点からプレー日までの取消」の確率 ▼ Python ── 時間帯ごとの空きの幅/前日確認の対象/名簿の並べ直し/予約サイトに出す枠の案 ▼ コースごとの一覧(プレー日別・時間帯別) ▼ 【予約担当が確かめて連絡し、予約サイトに出す】
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Python(pandas・scikit-learn の HistGradientBoostingClassifier) | R、BigQuery ML、LightGBM |
| データの取得元 | 予約の管理の仕組みの書き出し | 予約の管理の仕組みのAPI(提供されている場合) |
| 一覧の出力先 | 予約担当の共有フォルダの一覧(コース別のシート) | 社内のダッシュボード |
| 定時実行 | 社内のジョブ管理の仕組み | OSのタスクスケジューラ |
生成AIは使いません。 確認の連絡とキャンセル待ちへの案内は、決まった文面を予約担当が使います。予約者の氏名や電話番号を外部の生成AIに渡す場面を、最初から作りません。
予約の管理の仕組みと予約サイトには書き込みません。 予約サイトに枠を出すのは、いまと同じく販売の担当が管理画面で行います。計算の誤りが、そのまま販売や予約の取消に出る経路を作りません。
モデルに HistGradientBoostingClassifier を選ぶのは、欠けた値とカテゴリの列をそのまま扱えるからです。 公式の説明では、学ばせるときに分かれ目ごとに欠けた値を左右どちらへ送るかを学ぶとされています。予約サイトの予約には「コンペの名前」が無く、電話のコンペの予約には「予約サイトのプラン」が無い、というように、経路で埋まる列が違います。categorical_features の既定は "from_dtype" で、カテゴリの型にした列はそのまま入ります。
取消は全体の1割前後と少ないので、class_weight も検討します。 "balanced" を指定するとクラスの数の逆数で重みが付きます。ただし重みを付けると確率がずれるので、較正をした後の確率だけを足し上げに使います。
03どうやって実装するのか
処理の起点を決める
毎朝6時の定時実行を起点にします。 前日の夕方から夜に入った取消が記録に確定し、予約担当が出社する前に一覧ができている時刻です。取消が入るたびに動かす形にはしません。 案が日中に何度も変わると、どの順番で電話しているのかが分からなくなります。
毎朝作るのは、3日後と翌日のプレー日の2日分です。 3日後の分は前日確認の連絡の対象とキャンセル待ちの名簿の順番、翌日の分は予約サイトに出す枠の案が中心です。3日前を選ぶのは、確認の連絡に答えてもらい、取消が出たら名簿に電話する時間が残るからです。 自社のキャンセル規定で取消料がかかり始める日があれば、その前日を見直しの日にそろえます。
モデルの学び直しは月に1回です。 毎月1日に直近24か月の予約で学ばせ直し、前のモデルより当たっているかを較正曲線で確かめてから入れ替えます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 予約 | プレー日、コース、スタートの時間帯、組数、人数、予約の経路、プラン、予約を受けた日時 | 予約の管理の仕組み |
| 予約の履歴 | 作成・人数の変更・取消の日時 | 予約の管理の仕組み |
| 予約者の区分 | 会員・ビジター、コンペか個人か、過去2年の取消の回数 | 予約の管理の仕組み |
| 天気 | プレー日の降水確率と気温の予報(見直しの時点で出ていたもの) | 契約している気象情報の提供元 |
| 暦 | 曜日、祝日、連休、コースの催し | 予約担当が作る表 |
| キャンセル待ちの名簿 | 希望のプレー日・時間帯・人数、受け付けた日時、連絡の手段 | 表計算 |
質を決めるのは、予約の履歴と、見直しの時点で出ていた天気予報です。 いまの予約一覧では、3日前の時点では生きていた予約が「取消」になっています。履歴が無いと、3日前の状態を組み立て直せません。 天気も同じで、プレー日の実際の天気ではなく、3日前に出ていた予報を特徴にします。 実際の天気で学ばせると、3日前の時点では分からないことを知って当てるモデルになります。
予報は毎朝保存しておきます。 過去の予報は後から取り直せないことが多いので、この構成を始めると決めた日から、毎朝の予報をプレー日ごとに保存します。 保存が無い期間は、天気の列を欠けた値のまま学ばせます。
データの取得方法を決める
| 取るもの | どこから | 何に使うか |
|---|---|---|
| 予約の条件と経路 | 予約の書き出し | 予約ごとの特徴 |
| 作成・変更・取消の日時 | 履歴の書き出し | 見直しの時点の状態の組み立て |
| 予約者の区分と取消の回数 | 予約者のマスタ | 予約ごとの特徴 |
| 毎朝の予報 | 気象情報の提供元 | 天気の特徴(保存して学ばせる) |
| キャンセル待ちの名簿 | 表計算 | 連絡の順番の並べ直し |
答えの付け方を先に決めます。 3日前の見直しでは「3日前から当日までの取消、または無断の不来場」、前日の見直しでは「前日から当日まで」を1とします。人数が4名から3名に減っただけの変更は取消に数えません。 組が残れば枠は空かないからです。
AIへ渡す前に整形する
- 見直しの時点への組み立て … 履歴を見て、3日前・前日の時点で生きていた予約だけを残し、その時点の人数に戻します
- リードタイム … 予約を受けた日からプレー日までの日数と、見直しの時点からプレー日までの日数を作ります
- 人数の変更の回数 … 見直しの時点までに人数が減った回数を数えます。減り続けている組は、そろわなくなりかけています
- プランの束ね … 予約サイトのプラン名を「昼食付き」「セルフ」「早朝・薄暮」「コンペ」に束ねます
- 取消の回数の扱い … 予約者の過去2年の取消の回数を、0回・1〜2回・3回以上の区分にします。初めての予約者は欠けた値のまま渡します
- 天気の区分 … 降水確率を「30%未満・30〜60%・60%以上」に束ね、カテゴリの型にします
- 重複の確認 … 同じ組が予約サイトと電話の両方で取られていないかを、日時と代表者で確かめます
学ばせる記録の1行は、次のような形にします。1行が「ある予約の、ある見直しの時点の状態」です。 同じ予約が3日前と前日の2行になります。
{
"booking_id": "B-2025-108812",
"course": "east",
"play_date": "2025-11-08",
"checkpoint": "d-3",
"time_band": "morning",
"weekday": "sat",
"channel": "booking_site",
"plan_class": "lunch_included",
"groups": 1,
"players": 4,
"player_decrease_count": 1,
"lead_days_at_booking": 41,
"member_class": "visitor",
"competition": false,
"past_cancel_class": "1-2",
"rain_prob_class": "30-60",
"temp_forecast_c": 14.0,
"label": 1
}
booking_id は突き合わせのために持つ列で、特徴には入れません。 氏名や電話番号はこの段階ですでに外れています。label は、3日前の時点からプレー日までに取り消されたかどうかです。
1番目を省くと、モデルは未来を見て学びます。 いまの一覧で学ばせると、3日前の時点ではまだ分からなかった「人数が2回減った」が特徴に入り、検証ではよく当たるのに、本番では当たらないモデルになります。
5番目で初めての予約者を0回にしないのは、「記録が無い」と「取消が無い」が違うからです。 0で埋めると、初めての予約者がいちばん取り消さない人に見えます。
AIに処理させる
させるのは、予約1件ごとに「見直しの時点からプレー日までに取り消されるか」の確率を出すことだけです。 足し上げ、確認の連絡の対象の選び方、名簿の並べ直しは、Python の側の決まった規則で行います。
| 見るもの | 扱い方 | 判断できないときの扱い |
|---|---|---|
| リードタイム | 予約を受けた日と見直しの時点からの日数 | 予約日が欠けていれば欠けた値 |
| 予約の経路とプラン | カテゴリの型 | 束ねられないプランは「その他」 |
| 組数と人数、人数の変更 | そのまま | - |
| 会員・ビジター、コンペ | カテゴリの型 | 不明は欠けた値 |
| 過去の取消の回数 | 3つの区分 | 初めての予約者は欠けた値 |
| 天気の予報 | 降水確率の区分と気温 | 予報が無ければ欠けた値 |
確率は較正してから使います。 足し上げて組数にするので、「0.3と出た予約のうち実際に3割が取り消した」という意味の確率でなければ、足した数がずれます。 較正には CalibratedClassifierCV を使います。公式の説明では、十分なデータ(約1,000件超)があれば isotonic は sigmoid と同等以上で、少ないと過学習しやすいとされています。コース別・時間帯別には件数が少ないので、sigmoid から始めます。
時間帯ごとの空きの幅は、予約1件ずつの確率を順に重ねて出します。 空く組数が0組、1組、2組……になる確率を求め、中央の値と、9割の範囲の上の端を一覧に出します。 平均だけを出すと、「平均1.2組」が「必ず1組空く」に読まれます。
空く組数の分布 dist[0..n] を 予約1件ずつ畳み込む
dist = [1.0]
for p in その時間帯の予約ごとの確率(組数が2以上の予約は組ごとに分けない):
dist = [dist[i]*(1-p) + dist[i-1]*p for i in 0..len(dist)]
中央の値 = 累積が0.5を超える最初の組数
上の端 = 累積が0.9を超える最初の組数
2組以上をまとめた予約は、1件として畳み込みます。 同じ予約の2組は一緒に取り消されることが多いので、組ごとに独立に数えると空きの幅が狭く出ます。その予約が取り消されたら組数ぶん空く、として数えます。
前日確認の連絡の対象は、確率の上位から選びますが、上限を置きます。 1つのプレー日で、確率が0.3以上の予約のうち最大8組までです。電話をかけられる数には限りがあり、確率の低い予約まで電話すると、取り消すつもりのない来場者に手間をかけます。
| させないこと | 理由 |
|---|---|
| 予約の受付・取消の判断 | 確率は空きの見込みのためのもの。予約の扱いに使わない |
| 料金や条件の差 | 確率で予約者の条件を変えない |
| キャンセル待ちの受け付けた順の変更 | 名簿の公平さを保つ |
| 取消料の判断 | 自社の規定と予約担当が決める |
| プレーの可否(天候による中止) | コースの責任者が決める |
1行目と2行目がいちばん大事です。 過去の取消の回数を特徴に入れている以上、確率の高い予約者を断る使い方をすると、確率が予約者の扱いの差に直結します。 確率を見られるのは予約担当だけにし、使い道を確認の連絡の対象に限ります。
指示内容を固定する
この構成は生成AIを使わないため、プロンプトはありません。 代わりに、学習・計算・一覧の作成を決める設定を、ひとつのファイルにまとめます。
【見込む先】
target: 見直しの時点からプレー日までの取消、または無断の不来場(=1)
人数の減少だけの変更は 0
見直しの時点: プレー日の3日前・前日の朝
学習期間: 前月までの24か月 検証: 直近3か月
【読まない列(書き出しの段階で除く)】
- 氏名、電話番号、メールアドレス、住所、生年月日
- 予約の備考欄の自由記述
【モデル】
estimator: HistGradientBoostingClassifier(class_weight="balanced")
categorical_features: from_dtype
calibration: CalibratedClassifierCV(method="sigmoid")
入れ替えの条件: 検証の期間で、前のモデルより較正曲線のずれが小さいこと
【前日確認の連絡の対象(3日前の見直し)】
確率 0.3 以上、1プレー日あたり最大 8 組
会員の予約は対象から外し、一覧に「会員」と別枠で出す
【キャンセル待ちの名簿の並べ直し】
1. 空きの見込みの中央の値が1組以上の時間帯を希望する人を前へ
2. 同じ時間帯の中では、希望の人数が空きそうな組の人数に合う人を前へ
3. 同じ条件の中では、受け付けた日時の早い順(この順は崩さない)
【予約サイトに出す枠の案(前日の朝)】
前日の朝の時点で空いている枠のうち、名簿で埋まらない見込みの枠
出す時刻: 名簿の連絡を始めてから2時間後
会員の予約を前日確認の対象から外すのは、会員との関係を予約担当の判断に残すためです。 会員の取消の傾向は担当者がよく知っていて、確率で電話の対象を決めると、長く通っている会員に「来ますか」と聞くことになります。 一覧には別枠で確率を出し、電話するかは予約担当が決めます。
名簿の並べ直しの3番目を「崩さない」と書いているのは、キャンセル待ちの公平さが苦情の種になるからです。 時間帯と人数が合う人を前に出しても、同じ条件の中で後から受け付けた人を先に案内することはしません。
出力形式を固定する
一覧は表で出し、同じ内容を JSON でも残します。 表は予約担当が読むため、JSON はプレー日が過ぎた後の突き合わせのためです。
{
"run_at": "2026-10-14T06:00:00+09:00",
"course": "east",
"play_date": "2026-10-17",
"checkpoint": "d-3 | d-1",
"slots": [
{ "time_band": "morning", "booked_groups": 0,
"expected_open": { "median": 0, "p90": 0 } }
],
"confirm_calls": [
{ "booking_id": "", "time_band": "", "group_size": 0,
"probability": 0.0, "member": false }
],
"waitlist_order": [ { "waitlist_id": "", "rank": 1, "matched_band": "" } ],
"online_release": { "groups": 0, "release_at": "" },
"model_version": "",
"decided_by": ""
}
1つ目の理由は、booking_id と waitlist_id だけで個人を指せることです。 一覧に氏名や電話番号を書かず、予約担当は番号から予約の管理の仕組みを開いて連絡します。 一覧が誤って共有されても、連絡先は出ません。
2つ目は、expected_open の幅で名簿の連絡の深さを決められることです。 中央の値が1組でも、上の端が3組なら、名簿の上から3組分の人に心づもりを伝えておけます。
| 列 | 予約担当が見ること |
|---|---|
confirm_calls | 電話する組と、会員を別枠で見るか |
expected_open | 時間帯ごとに名簿のどこまで連絡を準備するか |
waitlist_order | 受け付けた順が逆転していないか |
online_release | 予約サイトに出す枠の数と時刻 |
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 予約の管理の仕組み | データの書き出し(読み取りのみ) | 予約、予約の履歴、予約者の区分 |
| 気象情報の提供元 | 契約に基づく取得 | 毎朝の予報(保存する) |
| キャンセル待ちの名簿 | 表計算の読み取り | 希望の時間帯・人数・受け付けた日時 |
| 予約担当の共有フォルダ | 一覧の書き出し | コース別の一覧 |
| 予約サイト | 連携しない | 販売の担当が管理画面で枠を出す |
名簿の表計算には書き込みません。 並べ直した順番は別の列として一覧に出し、名簿そのものは予約担当が管理します。 連絡した日時と結果は、名簿の側にいままでどおり記録します。
人が確認する
- 前日確認の対象を見る … 会員の別枠と、常連の組を見て、電話するかを決めます
- 名簿の順番を見る … 同じ条件の中で受け付けた順が逆転していないかを確かめます
- 天気の急な変化を足す … 朝の予報が一覧を作った後に大きく変わったら、確認の連絡の対象を手で足します
- 予約サイトに出す枠を決める … 名簿の連絡の結果を見て、出す枠と時刻を決めます
2番目を省かないでください。 並べ直しの規則は受け付けた順を守る形にしていますが、希望の時間帯の書き方が名簿の中でそろっていないと、規則が意図どおりに働きません。
目標は、180件をならして1件6分です。 空きの見込みが無い日は一覧を流し見て終わり、週末の雨の予報の日は確認の電話の対象を読むのに時間がかかります。
例外に対処する
| 起きること | 対応 |
|---|---|
| 書き出しが朝までに届かない | 前日の一覧を「古い」と印を付けて残し、案は出さない |
| 予報が取れない | 天気の列を欠けた値にして見込み、一覧に「予報なし」と出す |
| 大型のコンペの予約がある | 15組以上のコンペは確率を出さず、幹事への確認を予約担当に任せる |
| 台風・大雪の予報 | 案を参考扱いにし、クローズの判断と連絡はコースの責任者が行う |
| 名簿の希望の時間帯が読めない | その人を名簿の末尾に置かず、一覧に「希望の確認が要る」と出す |
| 学び直したモデルが前より当たらない | 入れ替えず、前のモデルを使い続けて知らせる |
| 予約サイトと電話で同じ組が二重に入っている | 一覧に「重複の疑い」と出し、どちらを残すかは予約担当が確かめる |
| 新しいプランが予約サイトに出た | 束ねの表に無ければ「その他」とし、一覧に件数を出す |
3行目でコンペを外すのは、取消の決まり方が違うからです。 コンペは幹事の判断で組数がまとめて変わり、1件で時間帯の見込みが大きく振れます。
5行目を末尾に回さないのは、書き方の問題で順番が下がることを防ぐためです。 読めないのは名簿の側の問題で、その人の受け付けた順は変わりません。
記録を残す
- 毎朝の書き出しと、見直しの時点に組み立てた予約の一覧
- 毎朝の天気予報(プレー日ごと)
- 予約ごとの確率と、使ったモデルの版
- 時間帯ごとの空きの見込み、前日確認の対象、名簿の順番、予約サイトに出す枠の案
- 予約担当が電話した組と、その結果(取消・継続)
- プレー日の実際の取消、名簿で埋まった枠、予約サイトで埋まった枠、空いたまま残った枠
最後の行が、この構成の効き目を測る記録です。 空いたまま残った枠の数が、見直しを始める前より減っているかを毎月見ます。確率の当たり外れより、こちらが目的の数字です。
04実装レベルの3段階
最小構成では、天気の予報が扱えません。 過去の予報を保存していないことが多く、率は天気を混ぜた平均になります。 確かめるための段階です。 半自動化で、1件20分が11分程度になります。 目星付けは無くなりますが、確認の電話の対象と名簿の順番を決める作業が予約担当に残ります。本格構成で6分になり、この段階が本記事の想定です。 差が大きいのは、名簿を時間帯と人数で読み直す作業を、取消のたびにしていたからです。 段階を飛ばさないでください。 半自動化の一覧を2か月見ると、確率の当たり方の悪いコースと時間帯が先に分かります。
05工数削減シミュレーション
導入後 180件 × 6分 ÷ 60 = 18 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 複数のコースを運営し、電話・自社サイト・ゴルフ場の予約サイトから予約を受けているゴルフ場の会社。週末や好天の日に予約が埋まり、直前のキャンセルで空いた枠を電話のキャンセル待ちと予約サイトで埋めているが、どこから手を付けるかを予約担当の経験で決めている場合。予約の作成・取消の日時が予約の管理の仕組みに2年以上残っている場合。
- 予約が埋まる日がほとんど無く、キャンセル待ちが出ないゴルフ場。会員の予約が大半で、取消の傾向を担当者がほぼ把握できている小さな倶楽部。予約の取消の日時が残らず、いまの状態しか取り出せない仕組みの場合。なお、取消料の扱い、予約の受付の可否、プレーの可否の判断と、来場者への説明は、この構成では代替できません。
07最小構成で試す方法
- 予約の管理の仕組みから、過去1年分の予約と、取消の日時を書き出す
- 週末のプレー日だけに絞り、3日前の時点で生きていた予約を残す
- 表計算で、予約の経路 × 予約からの日数の区分 × 会員・ビジターごとに、3日前以降の取消の率を出す
- キャンセル待ちが出た週末を10日選び、その日の3日前の予約に3番目の率を当て、時間帯ごとに足し上げる
- 足し上げた空きの見込みを、実際に空いた組数と比べる
10日は必ずやってください。 モデルを作る前に、「予約の中身で空きの見込みが変わるのか」を確かめます。 書き出した記録は、氏名と電話番号の列を外してから開いてください。
| 出てきた内容 | 判断 |
|---|---|
| 経路や予約からの日数で取消の率が大きく違う | モデルに進む。 予約の中身に手がかりがある |
| 率に違いがほとんど無い | 取消は天気で決まっている。予報の保存から始める |
| 3日前の予約を組み立て直せない | 書き出しが先。 毎朝の予約一覧の保存から始める |
2行目が出ることも珍しくありません。 その場合は、毎朝の予報をプレー日ごとに保存する仕組みを先に作り、3か月たまってから試し直してください。
あわせて、名簿の書き方を10日分見直します。 希望の時間帯が「午前希望」「9時台」「なるべく早く」とばらばらに書かれていれば、並べ直しの規則が働きません。 名簿の希望の欄を4つの時間帯の選択肢にそろえるのが、モデルより先にできる準備です。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 検証ではよく当たるのに本番で外れる | 見直しの時点の状態で学ばせる。 実際の天気ではなく当時の予報を使う |
| 足し上げた空きが実際とずれる | 確率を較正する。class_weight を付けたら必ず較正する |
| 平均の空きを「必ず空く」と読まれる | 中央の値と9割の範囲の上の端を出す |
| 初めての予約者がいちばん取り消さない人に見える | 取消の回数を0で埋めない。欠けた値のまま渡す |
| 人数の変更を取消に数えてしまう | 組が残る変更は0にする |
| コンペの1件で見込みが振れる | 15組以上は外し、予約担当の判断に残す |
| 確認の電話が多すぎて来場者の手間になる | 対象に確率の下限と件数の上限を置く |
| 会員に確率で電話して関係を損ねる | 会員は別枠で出し、電話するかは予約担当が決める |
| 名簿の受け付けた順が逆転する | 並べ直しは同じ条件の中で受け付けた順を崩さない |
| 確率で予約を断る使い方をされる | 確率の使い道を連絡の対象に限り、見られる人を限る |
上の3行が、この構成の失敗のほとんどです。 どれも「数字は出るが、意味が違う」という形で起きます。時点、較正、幅の3つを押さえてあるかで、案が使えるかが決まります。
下の2行は、運用が始まってから効いてきます。 キャンセル待ちの順番と確率の使い道は、どちらも来場者から見た公平さの話です。一度崩れると、仕組みそのものが信じてもらえなくなります。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 予約の条件(プレー日、時間帯、組数、人数、経路、プラン)、予約の変更・取消の履歴、会員・ビジターの区分と過去の取消の回数、キャンセル待ちの名簿です。予約の管理の仕組みには、予約者の氏名・電話番号も入っています。
- 個人を特定する列を書き出さない … 氏名・電話番号・住所・生年月日は、書き出しの段階で外します。予約番号と名簿の番号だけでつなぎ、連絡は予約担当が予約の管理の仕組みから行います
- 確率を予約の扱いの差に使わない … 過去の取消の回数を特徴に入れているため、確率の高い予約者の予約を断る、料金を変えるといった使い方は、運用の決まりで禁じます。 使い道は確認の連絡の対象と空きの見込みだけです
- 確認の連絡は丁寧な案内にとどめる … 「取消の確率が高いので」とは伝えません。全員に同じ文面で、天気の予報と来場の予定の確認として連絡します
- キャンセル待ちの公平さを守る … 並べ直しの規則を名簿の担当者で共有し、受け付けた順を崩さないことを一覧の上でも確かめます
- 生成AIに予約の記録を渡さない … この構成は生成AIを使いません。案内の文面を作るために予約の一覧をチャットのAIに貼り付けることも禁じます
- 一覧を見られる人を限る … 予約ごとの確率は、予約担当と販売の担当だけが開ける場所に置きます
誤りが起きた場合のリスクは、確率が予約者の扱いの差に使われることと、キャンセル待ちの順番が崩れることの2つです。 どちらも空き枠の売上より重く、来場者の信頼に直接ひびきます。 だから案は一覧を出すまでにし、連絡と販売は予約担当が行う設計にしています。
10まず何から始めるか
1週目:予約の書き出しと予報の保存を始める
予約の管理の仕組みから、予約と予約の履歴を書き出せるかを確かめます。取消の日時が残っているかが最初の分かれ目です。 あわせて、毎朝の天気予報をプレー日ごとに保存する仕組みを、この週のうちに始めます。
2週目:10日で試す
過去1年の週末で、経路 × 予約からの日数 × 会員区分の取消の率を出し、キャンセル待ちが出た10日に当てて足し上げます。実際に空いた組数と並べて見ます。
3週目:連絡と名簿の決まりを決める
前日確認の対象の確率の下限と件数の上限、会員を別枠にすること、名簿の並べ直しの規則を、予約担当と支配人で決めます。 確認の連絡の文面も、全員に同じものを作ります。
4週目:見直しの時点の状態を作る
Python で、3日前と前日の時点で生きていた予約を組み立てる処理を作ります。この時点ではモデルを作らず、組み立てた予約の数が当時の一覧の数と合うかだけを確かめます。
2か月目: モデルで確率を出し、較正曲線で当たり方を見ます。一覧を毎朝出し、予約担当は従来どおり決めながら案と並べます。3か月目以降: 前日確認の対象と名簿の並べ直しを使い始め、空いたまま残った枠の数を毎月数えます。見直しを始める前より、空いたまま朝を迎える枠が減ったことを3か月分確かめた時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
HistGradientBoostingClassifier が欠けた値をそのまま扱い、学ばせるときに分かれ目ごとに欠けた値を左右どちらへ送るかを学ぶこと。categorical_features の既定が "from_dtype" で、カテゴリの数が max_bins 以下である必要があること。class_weight="balanced" がクラスの数の逆数で重みを付けること。predict_proba がクラスの確率を返すこと | scikit-learn: HistGradientBoostingClassifier | 2026-10-14 |
| 較正曲線が、予測した確率と実際の割合を比べるものであること。CalibratedClassifierCV の sigmoid が少ないデータに向き、isotonic は十分なデータ(約1,000件超)があれば sigmoid と同等以上で、少ないと過学習しやすいこと。較正は分類器を学ばせたのと別のデータで行う必要があること | scikit-learn: Probability calibration | 2026-10-14 |
取消料の扱い、予約の受付、クローズの判断と来場者への説明は、支配人と予約担当で決めてください。 自社のキャンセル規定と予約サイトの規約に合わせて運用してください。本記事は上記の公式情報で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1536)についてのご相談はこちらから。
