キャンペーン施策の効果を評価する際によく用いられる指標がリフト効果(Lift)です。
しかし、単純に接触群と非接触群を比較するだけでは、もともとのユーザ属性の偏りが結果を歪める可能性があります。
本記事では、リフト効果を正しく測定するための実務的な手順を、変数選定、多重共線性対策、ロジスティック回帰の詳細な推定手法、層別化とPSMの使い分け、さらに重回帰分析との比較まで含めて徹底的に解説します。
1. 目的変数と群の定義
目的変数(リフトを測る対象)
- 二値:モバイル契約率、提携QR決済利用率、提携クレジットカード利用率、提携ポイント利用率
- 連続値:ARPU(平均利用額)
比較する群
- 接触群:キャンペーンに接触したユーザ
- 非接触群:キャンペーンに接触していないユーザ
2. 説明変数(マッチングに使用する属性)の選定
リフト効果を測定する際は、マッチングに使用する説明変数にキャンペーン効果が混ざらないよう注意が必要です。
➡ マッチングには必ず「キャンペーン開始前(前月)」の情報を使用します。
例:前月の提携クレジットカード利用有無、前月の提携QR決済利用有無、前月の提携ポイント利用有無、前月の利用金額、性別、年代、地域、子持ち有無など。
3. 多重共線性を整理する重要性
3-1. 相関係数での事前チェック
- 説明変数同士の相関係数を総当たりで確認し、0.8以上の強い相関があるペアはどちらかを削除。
3-2. VIF(Variance Inflation Factor)で重複度を定量化
VIFとは?
- ある説明変数が他のすべての説明変数でどの程度説明されるかを測る指標。
- 計算式:
$$VIF_j = \frac{1}{1 – R_j^2}$$
ここで $R_j^2$ は「変数 $X_j$ を他の全説明変数で回帰したときの決定係数」です。
R²は「自由度調整済み」ではない
- VIFの計算には「通常の決定係数(R²)」を使用します。
- 自由度調整済み決定係数(Adjusted R²)ではありません。
- 理由:VIFは「変数数が多いとR²が高くなる」特性も含めて多重共線性を検出するため、通常R²を採用します。
VIFの判断基準
- VIF ≈ 1 → 問題なし
- VIF > 5 → やや共線性が強い
- VIF > 10 → 強い共線性 → 変数削除を検討
4. 変数選定の流れ
- 候補を広めに列挙(基本属性+前月のサービス利用)
- 相関係数で粗く整理
- VIF(通常R²)で重複変数を除去
この時点で変数が4個程度に絞れた場合は、傾向スコアを使わない単純層別化で十分な精度が得られるため、ロジスティック回帰やPSMを省略できます。
ただし、変数が多い場合や複雑な調整が必要な場合にはロジスティック回帰とPSMを併用します。
5. ロジスティック回帰による変数選定(詳細)
5-1. モデル式
ロジスティック回帰は、接触群になる確率 $p_i$ を次のように表します:
$$p_i = P(y_i=1|X_i) = \frac{1}{1+\exp(-z_i)}$$
$$z_i = \beta_0 + \beta_1x_{i1} + \beta_2x_{i2} + \dots + \beta_kx_{ik}$$
5-2. 対数尤度 $\ell(\beta)$ と $y_i$
対数尤度は以下の式で表されます:
$$\ell(\beta) = \sum_i \left[ y_i\log p_i + (1 – y_i)\log(1 – p_i) \right]$$
$y_i$ について
- $y_i$ は接触群かどうかを示す二値データ(0または1)です。
- 連続値(0.1や0.2など)にはなりません。
5-3. 係数 $\beta$ の算出方法
- 解析解は存在しないため、最尤推定(MLE)で係数を求めます。
- 尤度関数 $L(\beta)$ を最大化するため、ニュートン–ラフソン法やIRLS(反復重み付き最小二乗法)が用いられます。
5-4. p値の算出方法
p値は「係数 $\beta_j$ が0(効果なし)」という帰無仮説を検定して算出します。
- 推定係数 $\beta_j$ と標準誤差 $SE(\beta_j)$ を計算
- Wald統計量 $W = \beta_j / SE(\beta_j)$ を算出
- $W$ は正規分布に従うと近似
- p < 0.05なら有意と判断
5-5. 数値計算を最も簡単に行う方法
- Excel / GSS:Solverを使えば尤度最大化が可能だが、設定は煩雑。
- Python:
import statsmodels.api as sm
X = sm.add_constant(df[['x1','x2']])
y = df['y']
model = sm.Logit(y, X)
result = model.fit()
print(result.summary())
- R:
model <- glm(y ~ x1 + x2, data=df, family=binomial)
summary(model)
6. 属性バランスを揃える方法
6-1. 傾向スコアを使わない場合(単純層別化)
- 性別、年代、地域、前月サービス利用有無など、主要属性を組み合わせて層を作成します。
- 各層で接触群と非接触群の人数を揃える(または同じ比率で抽出)ことで、バランス調整が可能。
- メリット:SQLだけで実装でき、運用しやすい。
- デメリット:属性が多い場合は層が細分化しすぎ、サンプル不足に陥ることがある。
6-2. 傾向スコアを使う場合(PSM)
変数が多い場合や、層別化では調整が困難な場合に傾向スコアマッチング(PSM)を使用します。
PSMの手法
- 層化PSM:傾向スコアを5〜10帯域に分け、各層で人数比を揃える。
- 1対1最近傍マッチング:各接触群に最も近い非接触群を1人マッチング(Caliperで精度向上)。
- 1対kマッチング:接触群1人に近い非接触群k人をマッチング。
- 重み付け(IPTW):全サンプルを保持しつつ、傾向スコアに基づき重みを付与して効果を推定。
6-3. ロジスティック回帰による傾向スコア算出(PSM用)
PSMを実施する場合は、上記のロジスティック回帰で算出した傾向スコアを用います。
これにより、多次元の属性情報を1つのスコアに圧縮してマッチングが可能になります。
7. リフト効果の算出
マッチング後、目的変数を比較してリフトを算出します:
$$\text{Lift} = \frac{E[Y|\text{接触}] – E[Y|\text{非接触}]}{E[Y|\text{非接触}]}$$
- 二値目的変数 → 比率差
- 連続目的変数 → 平均値の差
8. 実務フローまとめ
- 目的変数を決定
- 前月データで説明変数を設定
- 相関係数 → VIF(通常R²)で重複変数を除去
- 変数が4個程度に絞れた場合 → 傾向スコアを使わない単純層別化で分析完結
- 変数が多く残る場合 → ロジスティック回帰で傾向スコアを算出しPSMを実施
- 群バランスを整えた上でリフト効果を算出
✅ 最終ポイント
- VIFは通常R²で計算し、多重共線性を評価
- 変数が少なければ単純層別化、変数が多ければロジスティック回帰+PSM
- ロジスティック回帰は確率推定に適しており、Python/Rで簡単に実装可能
- 正しい手法選択により、純粋なキャンペーン効果(リフト)を正確に把握できる
🔍 備考:重回帰分析で代用できるか?
✅ 1. 目的変数の性質
- 重回帰分析は連続値を想定、ロジスティック回帰は二値(確率)を想定。
- 傾向スコアは確率であるため、本来はロジスティック回帰を使用すべき。
✅ 2. 重回帰で代用する場合の影響
- 変数削減の目安(係数の大小やp値)には利用できる。
- ただし確率の予測精度は低下し、PSMに用いる傾向スコアの品質が劣化する恐れがある。
✅ 3. Python/Rでの手間
- ロジスティック回帰は重回帰とコード量がほぼ同じ。
- PythonやRを使えば、実装の煩雑さはほとんど変わらない。
✅ 4. 結論
- VIFで変数削減 → 層別化なら重回帰でも問題ない。
- PSMで傾向スコアを推定する場合はロジスティック回帰を使う方が妥当。
- PythonやRを用いれば、重回帰とほぼ同じ感覚で扱えるため、ロジスティック回帰を採用するのが最適。
🔍 備考2:ロジスティック回帰における説明力の指標
重回帰分析の $R^2$ のように「どれくらい説明できているか」を評価する指標として、ロジスティック回帰では擬似決定係数(Pseudo $R^2$)や情報量基準が使われます。
✅ 1. McFadden’s Pseudo $R^2$
- 計算手順
- モデルありの対数尤度 $\ell_1$ を計算
- 定数項のみのモデルの対数尤度 $\ell_0$ を計算
- 次式で算出
$$R^2_{McF} = 1 – \frac{\ell_1}{\ell_0}$$
- 特徴:0.2~0.4で良好なモデルとされる。
✅ 2. Cox & Snell R²
- 計算手順
- 定数モデルの尤度 $L_0$ と完全モデルの尤度 $L_1$ を求める
- 次式で算出 $$ R^2_{CS} = 1 – \left( \frac{L_0}{L_1} \right)^{2/n} $$
- $n$:サンプル数
- 特徴:1未満にしかならない。
✅ 3. Nagelkerke R²
- 計算手順
- Cox & Snell R² を 0~1 に補正して算出:
$$R^2_{N} = \frac{R^2_{CS}}{1 – L_0^{2/n}}$$ - 特徴:$R^2$ に近い解釈が可能。
✅ 4. AIC(赤池情報量基準)
- 計算式
$$AIC = -2\ell_1 + 2k$$ - $k$:パラメータ数
- 特徴:値が小さいほど適合が良い。
✅ 5. ROC曲線とAUC
- モデルの確率予測を用いてROC曲線を描き、曲線下面積(AUC)を算出。
- AUCが0.5ならランダム、1に近いほど予測精度が高い。
💡 実務メモ
- Pythonの
statsmodels
→summary()
でMcFadden R²が自動算出 - Pythonの
sklearn.metrics.roc_auc_score
→ AUCが簡単に算出 - Nagelkerke R² → Rの
rcompanion
パッケージなどで算出可能
🔍 備考3:接触群・非接触群のサンプリング比率について
リフト効果を評価する際、母集団における接触群の割合が極端に小さい(例:1%以下)場合、そのままの比率で分析すると以下の問題が生じます。
- 非接触群が圧倒的多数 → モデルは「非接触」と予測しても高い精度になり、接触群を識別できない。
- ロジスティック回帰では少数派の接触群の特徴が埋もれ、傾向スコア推定が不安定になる。
✅ 1. サンプリングの主な方法
① 1:1 のランダムサンプリング
- 接触群全件と非接触群を同数ランダム抽出。
- メリット:接触群の特徴を明確に捉えやすい。
- デメリット:母集団比率と異なるため、推定確率は実際より高めになる。
- → 傾向スコアを確率の絶対値として解釈せず、相対比較やマッチングに使えば問題なし。
② 1:k のサンプリング(例:1:2 ~ 1:5)
- 接触群1に対し、非接触群を2~5倍サンプリング。
- メリット:非接触群の情報をある程度反映。
- デメリット:kを大きくすると再び非接触が支配的になり、接触群の特徴が弱まる。
③ 全サンプル利用+重み付け
- 全データを使用しつつ、逆確率重み付けなどで調整。
- メリット:母集団比率を反映できる。
- デメリット:実装が複雑で分析負荷が高い。
✅ 2. 実務での推奨比率
- PSMなどマッチング目的 → 1:1 または 1:2 が扱いやすい。
- 傾向スコア推定精度を優先 → 接触群全件+非接触群を数倍(1:3程度)がバランス良い。
- 母集団確率として解釈したい場合 → 重み付けの導入が必要。
💡 接触率が1%未満のケースでは
→ 1:1のマッチングサンプルで十分。
→ 推定された傾向スコアは「母集団確率」ではなく接触群らしさの指標として解釈すれば問題ありません。