機械学習で顧客の購買行動を予測する方法|行動予測モデルの作り方と評価(Pythonで実行)
機械学習で顧客の購買行動を予測するには、過去の顧客ごとの行動データ(最終購入からの日数、購入回数、閲覧数、カート追加など)と「その後の一定期間に買ったかどうか」を表にまとめ、分類モデルに学習させて一人ひとりの購入確率を出します。評価は正解率ではなく、AUCや「確率の高い上位何割に購入者がどれだけ集まったか」で見ます。
この記事では、マーケティングの担当者が自社で購買予測(行動予測モデル)を作るときの流れを、データの作り方からモデルの評価、施策への使い方まで順に説明します。コードは架空の顧客データで実際に動かし、出力をそのまま載せています(Python 3.12.15、scikit-learn 1.9.1、pandas 3.0.6、2026年10月15日実行)。解約の予測についてはチャーン予測とはで別にまとめています。
購買予測で何がわかり、何に使うのか
購買予測モデルが出すのは、「この顧客が次の30日以内に購入する確率は○%」のような、顧客ごとの数値です。この数値を使うと、たとえば次のような判断ができます。
- クーポンや広告を、購入確率が中くらいの顧客に絞って配る(すでに買う人や、ほとんど買わない人に配る費用を減らす)
- カートに商品を入れたまま離れた顧客のうち、確率が高い人に先にフォローのメールを送る
- 営業担当がいる商材なら、見込みの高い顧客から順に連絡する
注意したいのは、モデルがわかるのは「買いそうかどうか」であって、「施策をすれば買うかどうか」ではない点です。確率が高い顧客は、何もしなくても買うかもしれません。施策の効果まで確かめたいときは、対象の一部にだけ施策をするA/Bテストと組み合わせます。
予測に使うデータと「答え」の決め方
答え(目的変数)を先に決める
最初に決めるのは、何を予測するかです。「次の30日以内に1回以上購入したか(1か0)」のように、期間と条件をはっきりさせます。期間が長すぎると施策に間に合わず、短すぎると購入者が少なくなり学習しにくくなります。
特徴量(説明変数)の例
| 種類 | 特徴量の例 | 考え方 |
|---|---|---|
| 購買履歴 | 最終購入からの日数、直近90日の購入回数・金額 | RFM分析のRecency・Frequency・Monetaryにあたる |
| サイト行動 | 直近7日の閲覧ページ数、カート追加数、検索回数 | 購入直前の行動が表れやすい |
| 反応履歴 | メール開封率、クーポン利用の有無 | 施策への反応のしやすさ |
| 属性 | 会員歴、居住地域、利用している端末 | 取得の可否と、使ってよいかを先に確認する |
大事なのは、特徴量は「予測する時点で手に入る情報」だけで作ることです。たとえば10月1日時点で「10月中に買うか」を予測するなら、特徴量は9月30日までのデータで作ります。10月の閲覧数を混ぜると、テストでは精度が高く見えても、本番では使えません(これをリーク、データ漏れと呼びます)。特徴量の作り方は特徴量とはでくわしく扱っています。
Pythonで購買予測モデルを作る
手順1:データを用意する
ここでは練習用に、5,000人分の架空の顧客データを作ります。実際の業務では、この部分を自社の購買履歴やアクセスログから集計した表に置き換えます。
import numpy as np
import pandas as pd
rng = np.random.default_rng(42)
n = 5000
df = pd.DataFrame({
"recency_days": rng.integers(1, 181, n), # 最終購入からの日数
"orders_90d": rng.poisson(1.2, n), # 直近90日の購入回数
"page_views_7d": rng.poisson(4, n), # 直近7日の閲覧ページ数
"cart_adds_7d": rng.poisson(0.6, n), # 直近7日のカート追加数
"email_open_rate": rng.uniform(0, 1, n), # メール開封率
})
# 架空の「次の30日に買ったか」を、特徴量から確率的に作る
logit = (-2.6 - 0.012 * df["recency_days"] + 0.45 * df["orders_90d"]
+ 0.08 * df["page_views_7d"] + 0.9 * df["cart_adds_7d"]
+ 0.8 * df["email_open_rate"])
df["purchased_30d"] = (rng.uniform(0, 1, n) < 1 / (1 + np.exp(-logit))).astype(int)
pd.set_option("display.width", 120)
pd.set_option("display.max_columns", None)
print(df.head())
print("購入した割合:", round(df["purchased_30d"].mean(), 3))
df.to_csv("customers.csv", index=False)
recency_days orders_90d page_views_7d cart_adds_7d email_open_rate purchased_30d
0 17 0 4 1 0.056212 0
1 140 3 7 2 0.575882 0
2 118 0 7 2 0.417413 0
3 79 4 2 1 0.369572 0
4 78 1 4 1 0.724460 0
購入した割合: 0.18
購入した顧客は全体の18%です。実際のデータでも、買った人より買わなかった人のほうが多いのがふつうです。この「偏り」が、次の評価の話につながります。
手順2:モデルを学習させて比べる
データを学習用(75%)とテスト用(25%)に分け、ロジスティック回帰と勾配ブースティングの2つのモデルを学習させます。stratify=y は、学習用とテスト用で購入者の割合をそろえる指定です。
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.metrics import roc_auc_score, accuracy_score
df = pd.read_csv("customers.csv")
X = df.drop(columns="purchased_30d")
y = df["purchased_30d"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, stratify=y, random_state=0)
models = {
"ロジスティック回帰": make_pipeline(StandardScaler(), LogisticRegression()),
"勾配ブースティング": HistGradientBoostingClassifier(random_state=0),
}
for name, model in models.items():
model.fit(X_train, y_train)
proba = model.predict_proba(X_test)[:, 1]
print(f"{name}: AUC={roc_auc_score(y_test, proba):.3f}",
f"正解率={accuracy_score(y_test, model.predict(X_test)):.3f}")
print("全部「買わない」と答えた場合の正解率:", round(1 - y_test.mean(), 3))
ロジスティック回帰: AUC=0.767 正解率=0.827
勾配ブースティング: AUC=0.744 正解率=0.822
全部「買わない」と答えた場合の正解率: 0.82
正解率はどちらも82%台ですが、全員を「買わない」と答えるだけでも82%になります。購入者が少ないデータでは、正解率はモデルの良し悪しをほとんど表しません。そこで使うのがAUC(ROC曲線の下の面積)です。AUCは「買った人と買わなかった人を1人ずつ選んだとき、買った人のほうに高い確率を付けられる割合」で、0.5ならでたらめ、1.0なら完全に分けられている状態です。
この架空データは、作るときに使った式がロジスティック回帰と同じ形なので、ロジスティック回帰のほうがよい結果になりました。実際のデータでは、特徴量どうしの組み合わせが効く場合にHistGradientBoostingClassifierのような木のモデルが上回ることもあります。どちらがよいかは、自社のデータで比べて決めます。
手順3:施策に使える形で評価する
マーケティングで使うときは、「確率の高い順に並べた上位10%に、購入者がどれだけ集まったか」を見るのがわかりやすい方法です。テスト用の顧客を確率の高い順に10等分(デシル)し、各グループの購入率と、全体の購入率に対する倍率(リフト)を出します。あわせて、ロジスティック回帰の係数から、どの特徴量が効いているかを確かめます。
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
df = pd.read_csv("customers.csv")
X = df.drop(columns="purchased_30d")
y = df["purchased_30d"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, stratify=y, random_state=0)
model = make_pipeline(StandardScaler(), LogisticRegression())
model.fit(X_train, y_train)
result = pd.DataFrame({"actual": y_test.values,
"score": model.predict_proba(X_test)[:, 1]})
result["decile"] = pd.qcut(result["score"].rank(method="first", ascending=False),
10, labels=range(1, 11))
table = result.groupby("decile", observed=True)["actual"].agg(["count", "mean"])
table["lift"] = table["mean"] / result["actual"].mean()
print(table.round(3).head(4))
coef = pd.Series(model[-1].coef_[0], index=X.columns).sort_values()
print(coef.round(2))
count mean lift
decile
1 125 0.528 2.933
2 125 0.376 2.089
3 125 0.192 1.067
4 125 0.232 1.289
recency_days -0.56
email_open_rate 0.14
page_views_7d 0.14
orders_90d 0.58
cart_adds_7d 0.67
dtype: float64
確率が上位10%(デシル1)の125人では52.8%が購入していて、全体の購入率の約2.9倍です。上位20%まで広げても、購入率は全体の約2倍あります。「予算が限られているので上位2割だけにクーポンを送る」といった判断に、この表をそのまま使えます。
係数を見ると、カート追加数と直近の購入回数が多いほど、最終購入からの日数が短いほど、購入確率が上がる関係が読み取れます(特徴量は標準化してあるので、係数の大きさをおおまかに比べられます)。ただし、これは「一緒に動いている」という関係で、カートに入れさせれば買うようになる、という因果までは示していません。
精度を上げるときに見直すポイント
データの偏り(不均衡)への対処
購入者が少ないときは、LogisticRegression などの class_weight="balanced" で少ないほうのクラスに重みを付ける方法があります。ただし、AUCやデシルのように確率の順位で評価して上位から施策を打つなら、重み付けをしなくても使えることが多いです。「確率が何%以上なら購入とみなす」というしきい値は、施策の費用と得られる利益から決めます。
時間の順番を守って検証する
購買データには時間の流れがあります。ランダムに分けると、未来のデータで学習して過去を当てる形になり、本番より精度が高く出ることがあります。実務では「1〜6月のデータで学習し、7月で確かめる」のように期間で分けるか、TimeSeriesSplit を使います。交差検証の種類は交差検証とはで比べています。
特徴量を足す・作り直す
精度を上げるのに効くのは、モデルを複雑にするより、購入につながる行動を特徴量にすることです。「同じ商品ページを何回見たか」「価格の安い順に並べ替えたか」「前回の購入から何日おきに買っているか」など、自社の商品と顧客の動きに合わせて考えます。
定期的に作り直す
季節、商品構成、サイトのデザインが変わると、行動と購入の関係も変わります。月に1回などの頻度で新しいデータで学習し直し、上位10%の購入率が下がっていないかを見ます。
購買予測でつまずきやすい点
- 予測する時点より後のデータを特徴量に入れてしまう(リーク)
- 購入者が少ないのに、正解率だけで良し悪しを判断する
- 確率が高い顧客にばかり施策を打ち、もともと買う人に費用を使ってしまう
- 個人データの扱いを確認せずに属性を使う(利用目的の範囲内か、社内ルールと照らし合わせる)
ここで使ったロジスティック回帰・勾配ブースティングは、テックジムのAIエンジニア養成コースでは第4章「分類問題」で、入会・継続・退会の予測は第5章「実践ビジネスデータ分析」で扱っています(16章で機械学習とディープラーニングを学ぶコースです)。
よくある質問
Q. 顧客の購買行動を予測するには、どんなデータが必要ですか?
顧客ごとの購買履歴(最終購入からの日数、購入回数、金額)と、サイトでの行動(閲覧数、カート追加など)、そして予測したい「答え」として、その後の一定期間に購入したかどうかの記録が必要です。特徴量は予測する時点までのデータだけで作ります。
Q. 購買予測にはどの機械学習の手法を使えばよいですか?
まずは結果を説明しやすいロジスティック回帰で基準を作り、勾配ブースティングなどの木のモデルと比べるのが進めやすい方法です。どちらがよいかはデータによって変わるので、同じテストデータのAUCや上位10%の購入率で比べて決めます。
Q. 購買予測モデルの精度は正解率で評価してよいですか?
購入者が少ないデータでは、正解率は向いていません。全員を「買わない」と答えるだけで正解率が高くなるためです。AUCや、確率の高い順に並べた上位の購入率(リフト)で評価します。
Q. 予測結果はマーケティング施策にどう使いますか?
顧客を購入確率の高い順に並べ、予算に合わせて上位から施策の対象を決めます。ただし確率が高い人は施策がなくても買う場合があるため、施策の効果はA/Bテストで確かめます。
機械学習の全体像は機械学習とは?仕組み・種類・できることを簡単に解説|Pythonで動く例つきにまとめています。





