🎓 レベル:標準 | 重要度:A(必須)
📎 関連:第7章 実験と因果推論 目次 | 前提:ターゲティングとペルソナ設計・A/Bテストの設計と分析
要点(BLUF)
- ターゲティングとペルソナ設計 で触れた「反応率が高い ≠ 施策効果が高い」を、ここで本格化します。反応率の高い層には「施策を打たなくても、どうせ買う人」が混じり、彼らに接触しても売上は変わらずコストだけかかる無駄打ち。本当に狙うべきは「施策を打ったから態度が変わる人=説得可能層(persuadables)」です。顧客は施策への反応で4類型に分かれます——説得可能(処置で買う)・鉄板(放っても買う)・無関心(どうせ買わない)・天邪鬼(処置で逆に買わなくなる=負の効果)。
- この「施策で態度がどれだけ変わるか」を顧客ごとに測る量が、アップリフト=個別の処置効果(CATE) です。A/Bテストの設計と分析 が全体平均の効果を測ったのに対し、アップリフトは効果の異質性(誰に効くか)を測ります。推定は T-learner——処置群モデル と対照群モデル を別々に作り、その差 。本ノートの4セグメント(各 人・A/B でランダム割付)で、真のアップリフト を と回復し、天邪鬼の負の効果も 信頼区間 で有意に負だと確認できます。
- ターゲティングの結果が劇的に変わります。同じ 人を処置する予算で、処置CVR(反応率)が高い順に狙うと、鉄板(処置CVR で最高だが放っても買う)に無駄打ちし、CVR の天邪鬼まで掴んで逆効果——増分はわずか 件(全員処置の 件すら下回る)。アップリフトが正の層を狙うと、説得可能を最優先し天邪鬼を外して増分 件。アップリフト曲線は上位 で頂点 件、欲張って まで処置すると天邪鬼が混じり 件へ転落します。
1. 反応率の高さではなく「施策で動く人」を狙う(4類型)
ターゲティングとペルソナ設計 の§⚠️で、最も根深い誤解として「反応率が高い=施策効果が高い、ではない」を挙げました。本ノートはそこを出発点にします。
反応率(接触したときに買う確率)が高いセグメントを狙えば成果が出る——直感的ですが、半分間違いです。反応率の高い層には2種類の人が混ざっています。ひとつは「施策がきっかけで買った人」、もうひとつは「施策がなくても、もともと買っていた人」。後者にいくら接触しても売上は1円も増えません。コストだけかかる無駄打ちです。施策の価値を生むのは前者だけ——「施策を打ったから態度が変わった人」で、これを**説得可能層(persuadables)**と呼びます。
顧客を「放っておいても買うか」と「施策を打つと買うか」の2軸で切ると、4類型が現れます。
| 類型 | 放っておくと | 施策を打つと | アップリフト τ | 施策すべきか |
|---|---|---|---|---|
| 説得可能(persuadables) | 買わない | 買う | 大きく正 | ◎ 狙う |
| 鉄板(sure things) | 買う | 買う | ほぼ 0 | × 無駄打ち |
| 無関心(lost causes) | 買わない | 買わない | ほぼ 0 | × 無駄打ち |
| 天邪鬼(sleeping dogs) | 買う | 買わなくなる | 負 | ×× 触ると損 |
狙うべきは説得可能だけです。鉄板と無関心は、施策の有無で結果が変わらない()ので接触してもコストの持ち出し。とりわけ危険なのが天邪鬼——放っておけば買ってくれたのに、施策がかえって逆効果になる層です。しつこいリマインドメールが「うっとうしい」と解約を誘発する、不要なクーポンが「定価で買うのは損」と通常購入を止める、押しの強い営業電話が顧客を遠ざける——現実によくある現象で、触れば触るほど売上を減らす(負のアップリフト)。英語の sleeping dogs(寝た子)=「寝た子を起こすな」がぴったりの層で、ここには手を出さないのが最善手です。
ここで反応率(処置時CVR)が役に立たない理由がはっきりします。反応率は「処置したとき買う確率」しか見ないので、説得可能(処置で買う)と鉄板(処置でも対照でも買う)を区別できません——両者とも処置時CVRは高いのです。両者を分けるのは「処置したときとしなかったときの差」だけ。この差こそアップリフトで、§2でこれを定式化します。
flowchart TB
ST["施策(処置)を打つ相手は?"] --> Q1{"放っておいても買う人か"}
Q1 -->|"買わない"| B0{"施策を打つと"}
Q1 -->|"買う"| B1{"施策を打つと"}
B0 -->|"買うようになる"| PERS["説得可能(persuadables)<br/>対照で買わず処置で買う/τ が正<br/>=狙うべき層"]
B0 -->|"やはり買わない"| LOST["無関心(lost causes)<br/>どうせ買わない/τ ほぼ0<br/>=無駄打ち"]
B1 -->|"変わらず買う"| SURE["鉄板(sure things)<br/>放っても買う/τ ほぼ0<br/>=無駄打ち"]
B1 -->|"逆に買わなくなる"| DOG["天邪鬼(sleeping dogs)<br/>触ると離れる/τ が負<br/>=触ると損"]
2. アップリフト=個別の処置効果 CATE と T-learner(数式)
A/Bテストの設計と分析 が測った処置効果 は、全員をひとまとめにした**平均処置効果(ATE)**でした。アップリフトはそれを顧客の属性 (セグメント・年齢・購買履歴など)ごとに分解した量で、**条件つき平均処置効果(CATE)**と呼びます。
アウトカム が買う/買わない()なら、 は「属性 の人を処置したときの反応率」、 は「同じ人を処置しなかったときの反応率」で、その差 がその層に施策が生む増分です。ATE はこの CATE を母集団全体で平均したものにすぎません。
A/B が「施策は平均してプラスか」に答えるのに対し、アップリフトは「誰に効くのか」という効果の異質性に答えます。§1の4類型は、 の符号と大きさによる分類に他なりません(説得可能 、鉄板・無関心 、天邪鬼 )。
をデータから推定する最も素直な方法が T-learner(Two-model learner)です。処置群だけで「処置したときの反応率」を当てるモデル と、対照群だけで「処置しなかったときの反応率」を当てるモデル を別々に作り、その差をとります。
本ノートでは =セグメント(カテゴリ)なので、各モデルは「セグメントごとの平均反応率」という単純な表になります。 は処置群でのそのセグメントの CVR、 は対照群での CVR、差が 。T-learner が正しく CATE を当てられるのは、各 の中で処置群と対照群が比較可能なとき——つまり A/Bテストの設計と分析 のランダム化が効いているときだけです。観察データでは処置を受けた人と受けない人が や見えない要因で元から違い(交絡)、 は効果と素性の差を混ぜてしまいます。だから本ノートはA/B(ランダム割付)データを前提にします。
推定したアップリフトは、ターゲティングに直結します。処置する顧客集合を とすると、施策の総増分は各顧客のアップリフトの和です。
これを最大化する狙い方は明快です。 が負の顧客(天邪鬼)は絶対に処置しない——足すと総増分が減るからです。そのうえで予算(処置できる人数)の範囲で、 が大きい順に処置する。これが最適なターゲティングで、反応率 の高い順ではありません。反応率順は説得可能(高反応率・高 )と鉄板(高反応率・低 )を混同し、CVR が中程度の天邪鬼(負 )すら掴んでしまいます。
顧客を の降順に並べ、上位 を処置したときの累積増分 を描いた曲線をアップリフト曲線と呼びます。曲線の頂点が「何%まで狙うべきか」を教えます(頂点を超えて処置を広げると、 が負の層が混じり増分が減る)。無作為に処置したときの直線(対角線)からどれだけ上に膨らむかを面積で測ったのが Qini 係数で、アップリフトモデルの良さの要約指標です(分類でいう AUC のアップリフト版)。
3. T-learner でアップリフトを推定する(コード)
4セグメント(各 人)を作り、各人を A/B でランダムに処置/対照へ割付して、アウトカム を生成します。真のアップリフトは設計上 。これを T-learner(処置群モデル と対照群モデル の差)で推定し、真値を回復できるか、そして各推定の 信頼区間を確かめます。
import numpy as np
import pandas as pd
from scipy import stats
rng = np.random.default_rng(0)
# 4セグメント×2500人。(対照反応率 → 処置反応率) = 真のアップリフト τ
segs = ["説得可能", "鉄板", "無関心", "天邪鬼"]
N_each = 2500
p_ctrl = {"説得可能": 0.10, "鉄板": 0.80, "無関心": 0.02, "天邪鬼": 0.50}
p_treat = {"説得可能": 0.40, "鉄板": 0.85, "無関心": 0.03, "天邪鬼": 0.30}
# 真のτ = +0.30 +0.05 +0.01 −0.20
segment = np.repeat(segs, N_each) # 各人のセグメント(長さ10000)
N = segment.size
treat = rng.integers(0, 2, N) # A/B:1=処置, 0=対照(ランダム化)
pc = np.array([p_ctrl[s] for s in segment])
pt = np.array([p_treat[s] for s in segment])
Y = rng.binomial(1, np.where(treat == 1, pt, pc)) # アウトカム Y(0/1)
df = pd.DataFrame({"segment": segment, "treat": treat, "Y": Y})
# T-learner:処置群モデル mu1=E[Y|T=1,seg] と対照群モデル mu0=E[Y|T=0,seg] を別々に作り、差をとる
g1 = df[df["treat"] == 1].groupby("segment")["Y"]
g0 = df[df["treat"] == 0].groupby("segment")["Y"]
mu1, mu0 = g1.mean().reindex(segs), g0.mean().reindex(segs) # 処置時CVR・対照時CVR
n1, n0 = g1.size().reindex(segs), g0.size().reindex(segs)
tau_hat = mu1 - mu0 # アップリフト推定 = 差
tau_true = pd.Series({s: p_treat[s] - p_ctrl[s] for s in segs}).reindex(segs)
# 差の95%信頼区間(各群の二項分散から)
se = np.sqrt(mu1 * (1 - mu1) / n1 + mu0 * (1 - mu0) / n0)
zc = stats.norm.ppf(0.975)
lo, hi = tau_hat - zc * se, tau_hat + zc * se
tbl = pd.DataFrame({"対照CVR": mu0, "処置CVR": mu1, "推定τ": tau_hat,
"真のτ": tau_true, "95CI下": lo, "95CI上": hi}).reindex(segs)
print("=== T-learner:セグメント別アップリフト τ の推定(A/Bデータから)===")
print(tbl.to_string(formatters={
"対照CVR": "{:.3f}".format, "処置CVR": "{:.3f}".format,
"推定τ": "{:+.3f}".format, "真のτ": "{:+.3f}".format,
"95CI下": "{:+.3f}".format, "95CI上": "{:+.3f}".format}))
出力:
=== T-learner:セグメント別アップリフト τ の推定(A/Bデータから)===
対照CVR 処置CVR 推定τ 真のτ 95CI下 95CI上
説得可能 0.090 0.394 +0.304 +0.300 +0.273 +0.335
鉄板 0.798 0.847 +0.049 +0.050 +0.019 +0.079
無関心 0.020 0.036 +0.016 +0.010 +0.003 +0.029
天邪鬼 0.497 0.303 -0.194 -0.200 -0.232 -0.157
出力の意味:まず対照CVR と処置CVR の2列を見れば、4類型がそのまま読めます。鉄板は両方とも高い(、放っても買う)、無関心は両方とも低い(、どうせ買わない)、説得可能は対照で低く処置で跳ね上がる()、そして天邪鬼は処置すると下がる()——施策が反応率を減らしています。この「下がる」が負のアップリフトの正体です。
T-learner は真のアップリフトを回復しています。推定 は説得可能 (真 )、鉄板 ()、無関心 ()、天邪鬼 ()。処置群と対照群の平均をセグメント別にとって引くだけで、施策の個別効果が当たります。とりわけ重要なのは天邪鬼の 信頼区間 が を含まず明確に負なこと——「触ると損」はノイズではなく統計的に有意な負の効果です。一方、無関心の区間 はぎりぎり を超えるものの、点推定 は真値 から 割もずれています。アップリフトは2つの反応率の差なので、効果が小さい層では誤差が相対的に大きくなり、推定が難しい(§⚠️)。信頼できるのは説得可能 ・天邪鬼 という大きなシグナルで、ターゲティングはそこで決まります。
4. アップリフトでターゲティングを設計する(コード)
推定したアップリフトで、実際に狙い方を設計します。3つの施策を比べます——(1) 全員処置、(2) アップリフトが正の層だけ処置、(3) 同じ人数を処置CVR(反応率)の高い順に処置。各施策が生む総増分コンバージョンを、真のアップリフトで採点します(合成データなので「実際にいくつ増えたか」を真値で評価できます)。(2) と (3) は同じ人数を処置するので、差は純粋に「誰を選ぶか」から来ます。
import numpy as np
import pandas as pd
rng = np.random.default_rng(0)
segs = ["説得可能", "鉄板", "無関心", "天邪鬼"]
N_each = 2500
p_ctrl = {"説得可能": 0.10, "鉄板": 0.80, "無関心": 0.02, "天邪鬼": 0.50}
p_treat = {"説得可能": 0.40, "鉄板": 0.85, "無関心": 0.03, "天邪鬼": 0.30}
segment = np.repeat(segs, N_each)
N = segment.size
treat = rng.integers(0, 2, N)
pc = np.array([p_ctrl[s] for s in segment])
pt = np.array([p_treat[s] for s in segment])
Y = rng.binomial(1, np.where(treat == 1, pt, pc))
df = pd.DataFrame({"segment": segment, "treat": treat, "Y": Y})
# T-learner(§3と同じ):処置時CVR mu1 と アップリフト推定 tau_hat
mu1 = df[df["treat"] == 1].groupby("segment")["Y"].mean().reindex(segs) # 処置時CVR
mu0 = df[df["treat"] == 0].groupby("segment")["Y"].mean().reindex(segs) # 対照時CVR
tau_hat = mu1 - mu0 # アップリフト
N_seg = pd.Series({s: N_each for s in segs}).reindex(segs)
tau_true = pd.Series({s: p_treat[s] - p_ctrl[s] for s in segs}).reindex(segs)
# 各施策が実際に生む増分 = 処置した人数 × 真のアップリフト(合成データなので真値で採点できる)
def increment(sel):
return float((N_seg[sel] * tau_true[sel]).sum())
# (1) 全員処置:全セグメントに打つ
inc_all = increment(list(segs))
# (2) アップリフト施策:推定アップリフトが正のセグメントだけ処置(効果が正の人だけ狙う)
uplift_sel = [s for s in segs if tau_hat[s] > 0]
n_budget = int(N_seg[uplift_sel].sum())
inc_uplift = increment(uplift_sel)
# (3) 反応率施策:同じ予算(同じ処置人数)を、処置CVRが高い順に充てる
cvr_sel, cum = [], 0
for s in mu1.sort_values(ascending=False).index:
if cum >= n_budget:
break
cvr_sel.append(s); cum += int(N_seg[s])
inc_cvr = increment(cvr_sel)
print(f"処置人数の予算 = {n_budget}人(アップリフトが正の層の人数にそろえる)")
print(f"(1) 全員処置({N}人) : 増分CV {inc_all:+.0f} 件 対象={'・'.join(segs)}")
print(f"(2) アップリフト施策({n_budget}人) : 増分CV {inc_uplift:+.0f} 件 対象={'・'.join(uplift_sel)}")
print(f"(3) 反応率(処置CVR)施策({n_budget}人): 増分CV {inc_cvr:+.0f} 件 対象={'・'.join(cvr_sel)}")
print(f"アップリフト施策 − 反応率施策 = {inc_uplift - inc_cvr:+.0f} 件")
print(f"アップリフト施策 − 全員処置 = {inc_uplift - inc_all:+.0f} 件(天邪鬼を外して回収)")
出力:
処置人数の予算 = 7500人(アップリフトが正の層の人数にそろえる)
(1) 全員処置(10000人) : 増分CV +400 件 対象=説得可能・鉄板・無関心・天邪鬼
(2) アップリフト施策(7500人) : 増分CV +900 件 対象=説得可能・鉄板・無関心
(3) 反応率(処置CVR)施策(7500人): 増分CV +375 件 対象=鉄板・説得可能・天邪鬼
アップリフト施策 − 反応率施策 = +525 件
アップリフト施策 − 全員処置 = +500 件(天邪鬼を外して回収)
出力の意味:
全員処置( 件)。3つの良い層(説得可能 ・鉄板 ・無関心 )は合計 件を生むのに、天邪鬼が 件を差し引くため、全員に打つと正味 件しか残りません。「とりあえず全員に配る」は、天邪鬼の逆効果をまるごと抱え込みます。
アップリフト施策( 件)。推定アップリフトが正のセグメントだけ(説得可能・鉄板・無関心の 人)を処置すると、天邪鬼に触れないので 件を満額回収。全員処置より 件多く、この差は天邪鬼の赤字 件を回避した分にちょうど一致します。ターゲティングとペルソナ設計 で「期待利益が正のセグメントだけ狙えばブランケットに勝つ」と見たのと同じ構造で、ここでは判断軸が**期待利益から個別の処置効果(アップリフト)**に変わっています。「効果が正の人だけ狙う」が、施策の世界での最適なターゲティングです。
反応率(処置CVR)施策( 件)。ここが本ノートの核心です。同じ 人を処置するのに、処置CVR の高い順に選ぶと、対象は鉄板・説得可能・天邪鬼になります。CVR ランキングは鉄板()を真っ先に拾うので、説得可能と同じ枠を「放っても買う鉄板」に無駄打ちし、さらに CVR の天邪鬼を「反応率が高い良い客」と勘違いして掴みます。結果、増分は 件——全員処置の 件すら下回る大失敗。アップリフトで選んだ場合( 件)との差は 件で、同じ人数に接触しながら 倍の開きです。狙う人数も予算も同じ。違うのは「反応率(誰が買うか)で選ぶか、アップリフト(誰が施策で変わるか)で選ぶか」だけ——これが成果を倍以上動かします。
最後に、セグメント別アップリフト(正=狙う/負=触らない)と、アップリフト曲線(アップリフト降順に顧客を並べ、上位 を処置したときの累積増分)を1枚に描きます。比較のため、処置CVR降順・無作為(対角線)も重ねます。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
rng = np.random.default_rng(0)
segs = ["説得可能", "鉄板", "無関心", "天邪鬼"]
N_each = 2500
p_ctrl = {"説得可能": 0.10, "鉄板": 0.80, "無関心": 0.02, "天邪鬼": 0.50}
p_treat = {"説得可能": 0.40, "鉄板": 0.85, "無関心": 0.03, "天邪鬼": 0.30}
segment = np.repeat(segs, N_each)
N = segment.size
treat = rng.integers(0, 2, N)
pc = np.array([p_ctrl[s] for s in segment])
pt = np.array([p_treat[s] for s in segment])
Y = rng.binomial(1, np.where(treat == 1, pt, pc))
df = pd.DataFrame({"segment": segment, "treat": treat, "Y": Y})
mu1 = df[df["treat"] == 1].groupby("segment")["Y"].mean().reindex(segs)
tau_hat = mu1 - df[df["treat"] == 0].groupby("segment")["Y"].mean().reindex(segs)
tau_true = {s: p_treat[s] - p_ctrl[s] for s in segs}
# 各人を「予測アップリフト(自分のセグメントの推定τ)」の降順に並べ、上位x%を処置したときの累積増分
pred = np.array([tau_hat[s] for s in segment]) # 並べ替えのキー(アップリフト)
gain = np.array([tau_true[s] for s in segment]) # 採点:処置で実際に生む増分(真のτ)
cvrk = np.array([mu1[s] for s in segment]) # 比較用:反応率(処置CVR)
def curve(order):
cum = np.concatenate([[0.0], np.cumsum(gain[order])])
return np.arange(0, N + 1) / N * 100, cum
f, c_up = curve(np.argsort(-pred, kind="stable")) # アップリフト降順
_, c_cv = curve(np.argsort(-cvrk, kind="stable")) # 処置CVR降順
peak = int(np.argmax(c_up)) # 累積増分が最大になる位置
fig, (axb, axc) = plt.subplots(1, 2, figsize=(10.4, 4.4))
colors = ["C0" if tau_hat[s] > 0 else "C3" for s in segs] # 正=青(狙う), 負=赤(触らない)
axb.bar(segs, [tau_hat[s] for s in segs], color=colors)
axb.axhline(0, color="black", lw=1)
for i, s in enumerate(segs):
axb.text(i, tau_hat[s] + (0.012 if tau_hat[s] > 0 else -0.012), f"{tau_hat[s]:+.2f}",
ha="center", va="bottom" if tau_hat[s] > 0 else "top", fontsize=10)
axb.set_ylabel("推定アップリフト τ")
axb.set_title("セグメント別アップリフト(正=狙う/負=触らない)")
axb.grid(alpha=0.3, axis="y")
axc.plot(f, c_up, color="C2", lw=2.2, label="アップリフト降順で処置")
axc.plot(f, c_cv, color="C1", lw=1.8, label="処置CVR降順で処置")
axc.plot([0, 100], [0, c_up[-1]], color="gray", ls="--", lw=1.3, label="無作為に処置")
axc.scatter([f[peak]], [c_up[peak]], color="C2", zorder=5)
axc.annotate(f"頂点 {c_up[peak]:.0f}件(上位{f[peak]:.0f}%)", (f[peak], c_up[peak]),
textcoords="offset points", xytext=(-12, -40), fontsize=9, ha="center")
axc.set_xlabel("処置した顧客の割合(%)"); axc.set_ylabel("累積の増分CV(件)")
axc.set_title("アップリフト曲線:上位何%を狙うと増分が最大か"); axc.legend(loc="lower right")
axc.grid(alpha=0.3)
fig.suptitle("アップリフトモデリング:誰が施策で動くかで狙う")
fig.tight_layout()
plt.show()
左パネルはセグメント別の推定アップリフトです。説得可能の青い棒が と突出し、鉄板 ・無関心 は小さく、天邪鬼だけが赤くゼロ線の下()に沈みます。棒の符号が「狙う/触らない」の境界——ゼロより上だけを処置対象にするのが、§4の「アップリフトが正の層だけ狙う」操作です。
右パネルがアップリフト曲線です。緑(アップリフト降順)は、説得可能から処置するので最初に急上昇し(上位 で 件)、鉄板・無関心で緩やかに伸びて上位 で頂点 件に達し、そこから先(天邪鬼)を処置に加えると転落して 件になります。この頂点が「 まで狙え、それ以上は天邪鬼が混じるからやめろ」と教えてくれます。橙(処置CVR降順)は鉄板から始めるため立ち上がりが鈍く、説得可能で跳ね、 で天邪鬼を踏んで急降下——反応率順がいかに不安定かが見えます。灰の対角線は無作為(狙わない)で、緑がそこから上に膨らんだ面積が Qini=アップリフトモデルの稼ぎです。
⚠️ よくある誤解
- 反応率モデルとアップリフトモデルは別物:反応率予測(CVR 予測)は「誰が買うか」を当てるモデル、アップリフトは「誰が施策で態度を変えるか」を当てるモデルで、目的関数が違います。反応率が高い人を狙うと、放っても買う鉄板に無駄打ちし、§4のように成果が伸びません。施策の ROI を上げたいなら、当てるべきは反応率ではなく**アップリフト(処置あり/なしの差)**です。「買いそうな人」と「施策で動く人」は重ならないことが多い、と肝に銘じてください。
- 天邪鬼に触ると損(負のアップリフト):「施策は打てば打つほど良い」は誤りです。天邪鬼(sleeping dogs)に接触すると、リマインドが解約を誘発する・しつこい広告が離反を招く・不要なクーポンが通常購入を止める、といった形で売上が減ります。§3で天邪鬼の負のアップリフトは 信頼区間でも有意でした。負のアップリフトの層は見つけて外すのが鉄則で、これは反応率モデルでは絶対に見えません(処置しない世界と比べて初めて分かる)。
- アップリフト推定は反応率予測より難しい:アップリフトは2つの反応率の差なので、それぞれのノイズが重なり、推定の誤差が大きくなります。§3で無関心の点推定()が真値()から 割ずれたのがその例。効果が小さい層ほど、差はノイズに埋もれます。だからアップリフトモデルは反応率モデルより多くのデータと慎重な検証を要し、信頼できるのは大きなシグナル(説得可能・天邪鬼)です。小さな の順位はあてになりにくい、と割り引いて読みます。
- ランダム化 A/B が前提(観察データだと交絡):T-learner の がアップリフトになるのは、各層で処置群と対照群が比較可能なとき、すなわち A/Bテストの設計と分析 のランダム割付があるときだけです。施策を「打ちたい人に打った」観察データでは、処置群と対照群が元から違い(交絡)、差は効果と素性の違いを混ぜてしまいます。本ノートが A/B データから出発したのはこのためで、観察データからアップリフトを取り出すには傾向スコアなどの追加の仮定・手法が要ります。
- メタ学習器・因果機械学習の体系は別テキスト:本ノートはアップリフトの考え方を、セグメント別の処置/対照の差(T-learner)という最小構成で示しました。連続的な特徴量で を回帰する S/T/X-learner などのメタ学習器、推定のバイアスを抑える**二重頑健(doubly robust)**や Double Machine Learning、それらの理論は因果推論テキストの領域です。マーケティングへの本格的な応用(多数の特徴量・因果機械学習でのアップリフト最適化)は第9章(発展トピック)で扱います。なお、 を最適化して「誰に何を出すか」を逐次学習する枠組みは、機械学習サイトの強化学習(バンディット)とも接続します。
関連ノート
- ターゲティングとペルソナ設計(前提・反応率ではなく効果で狙う。「反応率が高い≠施策効果が高い」を、本ノートでアップリフト=個別の処置効果として定式化した)
- A/Bテストの設計と分析(前提・アップリフトは A/B が測る平均効果 δ を顧客ごとに個別化した CATE。T-learner が成立するのはランダム化のおかげ)
- 第7章 実験と因果推論 目次
- メタ学習器(S/T/X-learner)・二重頑健・Double ML の理論は因果推論テキスト、多数の特徴量を使う因果機械学習×マーケティングのアップリフト最適化は第9章(発展トピック)で扱います
- マーケティング・サイエンス 全体目次