はじめに:誰が次に買ってくれそうかを知りたい

「メルマガやクーポンを全員に同じだけ配っているけれど、本当はもっと買いそうなお客さんに集中したい」。中小ECや個人事業主の現場では、よくある悩みだと思います。

ただ、「買いそうな人」を勘で選ぶと、たいてい上得意ばかりに偏ってしまいます。本当に効くのは「あと一押しで買いそうな人」を見つけることなのですが、それを目視で探すのはなかなか大変です。

そこで使えるのが BigQuery ML の購買予測モデルです。すでに BigQuery に購買履歴や行動ログが入っているなら、SQLを数本書くだけで「次に買う確率」をお客さんごとに出せます。本記事では、学習データの準備からモデルの作成、見込み客の抽出、そして評価と注意点までを、中小ECの現場目線で順番に見ていきます。

時系列で「全体の売上がどう動くか」を予測したい場合は、ARIMA_PLUSでEC売上の週次予測を自動化する記事も合わせて参考にしてください。今回は「個人ごとに買うかどうか」を当てる、いわば分類の話です。

やりたいことを整理する

今回作るのは、こういうモデルです。

  • 入力:お客さんごとの特徴量(過去の購入回数、最終購入からの経過日数、閲覧した商品数 など)
  • 出力:「これから一定期間内に購入するかどうか(する=1 / しない=0)」の確率

このように「Yes / No」を当てる問題は、機械学習では 二値分類 と呼びます。BigQuery ML なら LOGISTIC_REG(ロジスティック回帰)というモデルで手軽に扱えます。シンプルですが、結果の解釈がしやすく、最初の一本としては十分に実用的です。

💡 補足 「ロジスティック回帰」という名前に「回帰」と入っていますが、やっていることは分類です。出力が 0〜1 の確率になるので、しきい値(例:0.5)で「買う / 買わない」に分けられる、というイメージで大丈夫です。

ステップ1:学習データを準備する

機械学習でいちばん大事なのは、実はモデルよりも学習データの作り方です。ここがずれていると、どんなモデルでも当たりません。

今回は「ある基準日までの行動」から「その後30日以内に購入したか」を予測する形にします。つまり、特徴量を集める期間と、答え(ラベル)を集める期間をきっちり分けるのがポイントです。

ここでは、注文テーブル orders と閲覧ログ pageviews があると仮定して、基準日を 2026-05-31 として特徴量を作ります。

-- 学習用の特徴量+ラベルを作るクエリ
CREATE OR REPLACE TABLE `myproject.ec.training_data` AS
WITH
  -- 基準日「以前」の行動から特徴量を作る
  features AS (
    SELECT
      o.customer_id,
      COUNT(DISTINCT o.order_id)                              AS order_count,      -- 累計注文回数
      SUM(o.total_amount)                                     AS total_spend,      -- 累計購入金額
      DATE_DIFF(DATE '2026-05-31', MAX(o.order_date), DAY)    AS days_since_last,  -- 最終購入からの日数
      AVG(o.total_amount)                                     AS avg_order_value   -- 平均購入単価
    FROM `myproject.ec.orders` AS o
    WHERE o.order_date <= DATE '2026-05-31'
    GROUP BY o.customer_id
  ),
  -- 閲覧行動も特徴量に加える
  browsing AS (
    SELECT
      customer_id,
      COUNT(*)                          AS pageview_count,   -- 基準日前30日の閲覧数
      COUNT(DISTINCT product_id)        AS viewed_products
    FROM `myproject.ec.pageviews`
    WHERE event_date BETWEEN DATE_SUB(DATE '2026-05-31', INTERVAL 30 DAY)
                         AND DATE '2026-05-31'
    GROUP BY customer_id
  ),
  -- 基準日「より後」の30日で実際に買ったか(=答え)
  label AS (
    SELECT DISTINCT customer_id, 1 AS purchased
    FROM `myproject.ec.orders`
    WHERE order_date BETWEEN DATE_ADD(DATE '2026-05-31', INTERVAL 1 DAY)
                         AND DATE_ADD(DATE '2026-05-31', INTERVAL 30 DAY)
  )
SELECT
  f.customer_id,
  f.order_count,
  f.total_spend,
  f.days_since_last,
  f.avg_order_value,
  IFNULL(b.pageview_count, 0)   AS pageview_count,
  IFNULL(b.viewed_products, 0)  AS viewed_products,
  IFNULL(l.purchased, 0)        AS purchased   -- ラベル:買った=1 / 買ってない=0
FROM features AS f
LEFT JOIN browsing AS b USING (customer_id)
LEFT JOIN label    AS l USING (customer_id);

ポイントは、ラベル(答え)を 基準日より後 の期間から作っていることです。特徴量に「未来の情報」が混ざると、後述する「データ漏洩」という問題が起きてしまいます。

💡 補足 特徴量は最初から欲張らなくて大丈夫です。「最終購入からの日数」「累計注文回数」「累計金額」のいわゆる RFM 的な3つだけでも、けっこう手応えのあるモデルになります。まずは少数で動かして、効きそうな特徴量を後から足していくのがおすすめです。

ステップ2:CREATE MODEL でモデルを学習する

学習データができたら、モデルの作成は CREATE MODEL 一発です。model_typeLOGISTIC_REG を指定し、答えの列を input_label_cols で教えてあげます。

⚠️ 注意 BigQuery ML の構文・オプション名・出力列名(ML.PREDICT の結果列など)はバージョンによって変わることがあります。実際に動かす前に、必ず最新の公式ドキュメントで確認してください。

CREATE OR REPLACE MODEL `myproject.ec.purchase_prediction`
OPTIONS (
  model_type = 'LOGISTIC_REG',          -- ロジスティック回帰(二値分類)
  input_label_cols = ['purchased'],     -- 答えの列
  auto_class_weights = TRUE,            -- 買う人/買わない人の偏りを自動で補正
  data_split_method = 'AUTO_SPLIT',     -- 学習用と評価用を自動で分割
  l2_reg = 0.1                          -- 過学習を抑える正則化
) AS
SELECT
  -- customer_id は識別子なので学習からは外す
  order_count,
  total_spend,
  days_since_last,
  avg_order_value,
  pageview_count,
  viewed_products,
  purchased
FROM `myproject.ec.training_data`;

いくつか実務で効くオプションがあります。

  • auto_class_weights = TRUE:EC では「買わない人」が圧倒的に多く、データが偏りがちです。これを付けないと「全員買わない」と予測するだけのモデルになりかねません。
  • data_split_method = 'AUTO_SPLIT':学習用と評価用のデータを自動で分けてくれます。手元のデータで自分を採点しても意味がないので、評価用を分けておくのが鉄則です。
  • l2_reg:過学習(後述)を抑えるためのブレーキです。

customer_id を学習列に入れていない点にも注意してください。お客さん一人ひとりに固有の ID は予測の役に立たないどころか、過学習の原因になります。

ステップ3:ML.PREDICT で見込み客を抽出する

学習が終わったら、ML.PREDICT で予測します。ここでは「いま現在のお客さん」の特徴量を同じ形で用意して、購入確率を出します。

ML.PREDICT の結果には predicted_purchased_probs という配列が付いてきて、各クラス(1 と 0)の確率が入っています。ここから「購入する(label = 1)の確率」だけ取り出すと扱いやすくなります。

-- 購入確率が高い順に見込み客を抽出する
SELECT
  customer_id,
  predicted_purchased            AS predicted_label,   -- モデルの判定(0/1)
  -- 「購入する(=1)」確率だけ取り出す
  (SELECT prob
   FROM UNNEST(predicted_purchased_probs)
   WHERE label = 1)              AS purchase_probability
FROM ML.PREDICT(
  MODEL `myproject.ec.purchase_prediction`,
  (
    SELECT * FROM `myproject.ec.current_customers`   -- 学習時と同じ特徴量を持つテーブル
  )
)
WHERE (SELECT prob
       FROM UNNEST(predicted_purchased_probs)
       WHERE label = 1) >= 0.6      -- 確率60%以上を見込み客とする
ORDER BY purchase_probability DESC;

この結果を使えば、たとえば「購入確率60%以上のお客さんだけにクーポンを配る」「上位300人にだけリターゲティング広告を当てる」といった、メリハリのある施策が組めます。全員に同じ予算を配るより、効率はぐっと上がるはずです。

💡 補足 しきい値(ここでは 0.6)は固定の正解があるわけではありません。「予算が限られているから上位だけに絞りたい」なら高めに、「取りこぼしを減らしたい」なら低めに、施策の目的に合わせて調整してください。

ステップ4:評価指標と、過学習・データ漏洩の注意

モデルができたら、必ず精度を確認します。ML.EVALUATE で主要な指標がまとめて出ます。

SELECT *
FROM ML.EVALUATE(MODEL `myproject.ec.purchase_prediction`);

ここで特に見たいのが ROC AUC です。これは「買う人と買わない人をどれだけ見分けられるか」を 0〜1 で表す指標で、0.5 だと当てずっぽうと同じ、1.0 に近いほど優秀、という読み方になります。EC の購買予測では 0.7〜0.8 くらい出れば実用ラインと言われることが多いです(あくまで一般的な目安の例です。実際の数字はデータ次第なので、ご自身の環境で確認してください)。

精度(accuracy)だけを見るのは危険です。買わない人が95%を占めるデータなら、「全員買わない」と答えるだけで精度95%になってしまうからです。偏ったデータでは、ROC AUC や適合率・再現率(precision / recall)まで合わせて見るようにしてください。

そして、購買予測でいちばん気をつけたいのが次の2つです。

⚠️ 注意:データ漏洩(リーク)に気をつける 予測したい「未来」の情報が、うっかり特徴量に混ざっていないか必ず確認してください。たとえば「予測対象期間中の閲覧数」を特徴量に入れてしまうと、評価上の精度は跳ね上がりますが、本番では使えないモデルになります。「答えを知った状態で問題を解いている」状態だからです。特徴量とラベルの集計期間を、はっきり時間で区切るのが対策です。

⚠️ 注意:過学習(オーバーフィッティング)に気をつける 学習データだけにやたら強くて、新しいデータでは外す状態を過学習といいます。AUTO_SPLIT で分けた評価用データの ROC AUC が、学習時より大きく下がっていたら過学習のサインです。特徴量を増やしすぎない、l2_reg を効かせる、データ件数を増やす、といった対策で抑えられます。

データが少ない(数百件など)うちは、無理に複雑なモデルを作るより、特徴量を絞ってシンプルに保つほうが結果的に安定します。

まとめ

BigQuery ML を使えば、Python を書かなくても SQL だけで購買予測モデルが作れます。今回の流れを振り返ると、次の4ステップでした。

  1. 学習データの準備:特徴量とラベルの期間を時間で区切って作る
  2. CREATE MODELLOGISTIC_REG で購入有無を分類する
  3. ML.PREDICT:購入確率で見込み客を抽出する
  4. 評価と注意:ROC AUC で精度を確認し、過学習・データ漏洩を防ぐ

最初の一本としては、特徴量を3〜4個に絞ったシンプルなモデルで十分です。まずは動かしてみて、「思ったより当たるな」「ここが効いてるな」という手応えを掴むところから始めるのがおすすめです。

なお、こうしたSQLを書くのにハードルを感じる場合は、自然言語で BigQuery に問い合わせられる仕組みも整ってきています。Gemini in BigQueryで自然言語からSQLを生成する記事も合わせて読むと、「SQLが苦手でもデータ活用を始める」イメージが湧きやすいと思います。