Lecture 1:実証産業組織論/quantitative marketingへようこそ

計量経済学II

作者

Kei Ikegami

重要この講義で押さえたいこと
  1. 計量経済学Iの「識別・推定・推論」という3ステップと「モデル=条件付き分布の束」という考え方をおさらいし、計量経済学IIではこの道具を使って意思決定のための反実仮想シミュレーションを組み立てることを確認する。
  2. 実証ビジネス・エコノミクス、実証産業組織論(IO)、quantitative marketingという3つの隣接分野の関係を整理し、企業の意思決定が抱える4つの問い(需要・因果効果・顧客異質性・最適化)とこのコース全体の対応関係を頭に入れる。
  3. シミュレーションを通じて「予測」と「因果」がまったく別のタスクであることを、広告費と価格設定という2つの具体例で体感する。
  4. 「反実仮想(counterfactual)」という言葉が指す中身を明確にし、構造推定とは何のためにやるのかという見取り図を持つ。

前回とのつながり・今回のゴール

計量経済学Iでは、OLS・標準誤差・検定といった一般の推定・推論の道具を学び、さらにランダム化、固定効果、DiD、操作変数法、RDDを、それぞれの識別仮定のもとで因果効果を測る設計として学んだ。潜在アウトカムの枠組みで因果効果を定義し、識別のための仮定を明示し、推定量を作り、標準誤差で推論の不確実性を管理する、という一連の流れも身につけたはずだ。

計量経済学IIはその続編である。ただし今回は、「ある施策の効果を測る」だけでなく、モデルを使って「もしこうしていたら」を計算するというところまで踏み込む。値上げをしたら需要はどう変わるか。新製品を出したら既存製品からどれだけシェアを奪うか。2つの企業が合併したら価格はどう動くか。広告予算をどう配分すれば利益が最大化されるか。こうした問いに答えるには、単に「過去にこうだった」というデータの記述や、ある1つの施策の因果効果を測るだけでは足りない。まだ観測されていない世界の状態をモデルで作り出す必要がある。これが反実仮想シミュレーションであり、実証産業組織論(empirical IO)やquantitative marketingが企業や政策当局の意思決定に使われる最大の理由である。

今回は初回なので数式は最小限に抑え、計量Iの復習を1節だけ挟んだうえで、コース全体の地図を示すことに専念する。そのうえで、Rシミュレーションを2つ動かして「相関・予測・因果・反実仮想」がどう違うのかを体感してもらう。次回からは、この反実仮想シミュレーションの土台となる「離散選択モデル」の学習に入っていく。

1. 計量経済学Iの復習:3ステップとシミュレーション

計量経済学Iを貫いていた枠組みをもう一度確認しておこう。

  • この講義ではまず、統計モデルを「観測変数の条件付き分布の束」として捉える。 例えば予測モデルなら、価格などの条件を与えたときの需要の条件付き分布 \(P(\text{需要} \mid \text{価格}, \dots)\) を指定する。介入や均衡まで扱う構造モデルでは、これに加えて、どの変数を外から動かせるか、行動方程式や均衡条件が政策変更後もどう保たれるかを明示する。
  • 実証分析は次の3ステップで進む。
    1. 識別(identification):無限にデータがあれば、知りたいパラメータや効果は一意に定まるか。定まるための仮定は何か。
    2. 推定(estimation):手元の有限データから、そのパラメータの値をどう計算するか。
    3. 推論(inference):推定値には誤差がある。その誤差の大きさをどう測り、どこまで確信を持って良いかをどう表現するか。
  • そして計量Iの縦糸として繰り返し確認してきたのが、「モデルを条件付き分布として書き下せれば、コンピュータの中でそのモデルに従うデータを生成(シミュレーション)できる」という事実だった。シミュレーションができれば、推定量が真値を回収できるかを実験で確かめられるし、標準誤差の妥当性もモンテカルロで検証できる。

計量経済学IIでもこの枠組みは変わらない。ただし、シミュレーションの使い道が一段階進む。計量Iでは主に「推定量の性質を確認するための道具」としてシミュレーションを使ってきたが、計量経済学IIではシミュレーションそのものが最終目標になる。つまり、モデルのパラメータを推定したら、そのモデルを使って「もし価格を10%上げたら」「もしこの2社が合併したら」「もし広告予算を倍にしたら」というまだ起きていない状況を計算機の中に作り出す。これが構造推定(structural estimation)と呼ばれるアプローチの核心であり、このコースの全15回(うちゲスト講義2回)を通じて繰り返し出てくるテーマである。

計量Iで扱った枠組みを記号で書き直しておく。処置 \(D_i \in \{0, 1\}\)、潜在アウトカム \(Y_i(1)\)(処置を受けた場合の結果)、\(Y_i(0)\)(受けなかった場合の結果)とすると、観測されるアウトカムは

\[ Y_i = D_i Y_i(1) + (1 - D_i) Y_i(0) \]

であり、平均処置効果(ATE)は \(\tau = E[Y_i(1) - Y_i(0)]\) と定義された。ここで根本的な問題は、どの個体についても \(Y_i(1)\)\(Y_i(0)\)両方を同時に観測することはできないという点にある。これが「因果推論の根本問題」と呼ばれるものであり、計量Iで学んだランダム化・固定効果・DiD・操作変数法・RDDは、すべてこの根本問題を回避するための異なる仮定・異なる工夫だったことを思い出そう。

計量経済学IIで扱う反実仮想シミュレーションも、本質的には同じ問題への対処である。「もし価格が別の値だったら需要はどうだったか」は、まさに観測されていない潜在アウトカムを知りたいという話であり、モデル(条件付き分布の束)を使ってそれを埋め合わせるのが構造推定のアプローチだ、と理解しておくとよい。

2. 分野の整理:実証ビジネス・エコノミクス、実証IO、quantitative marketing

このコースが扱う内容は、いくつかの名前で呼ばれる。呼び方によって強調点が少し違うので整理しておこう。

  • 実証産業組織論(empirical industrial organization, empirical IO):企業の価格設定行動、製品差別化、参入・退出、合併といった市場構造を、需要と供給の構造モデルを使って分析する経済学の一分野。伝統的には独占禁止政策(合併審査など)との結びつきが強い。
  • quantitative marketing:マーケティングサイエンスの分野で、消費者の購買行動(ブランド選択、購入タイミング、数量選択)を統計・計量モデルで分析し、価格設定、広告、品揃え、顧客管理(CRM)といった企業のマーケティング施策に応用する。
  • 実証ビジネス・エコノミクス(empirical business economics):上記2つを包含しつつ、より広く「データを使って企業の意思決定を支援する」実務的な分析全般を指すことが多い言葉である。近年は多くの企業が経済学PhDホルダーを「データサイエンティスト」「エコノミスト」として採用しており、この講義で学ぶ内容はまさにその実務と直結している。

3つの分野は使う道具(離散選択モデル、最尤法、因果推論)を共有しており、明確な境界線があるわけではない。このコースでは便宜上「実証IO/quantitative marketing」とまとめて呼ぶが、要するに「データを使って、企業や政策当局の意思決定に資する形で、需要・競争・顧客行動を分析する」分野だと思ってもらえばよい。

企業の意思決定を4つの問いに分解する

データ分析チームや政策当局が直面する意思決定は、突き詰めると次の4つの問いに集約できる。このコースの13回(第5・12回のゲスト講義を除く)は、この4つの問いに対応する形で設計されている。

問い 具体例 対応する回
(a) 需要と代替性を知る この商品の価格を上げたら売上はどれくらい減る? 競合と自社製品はどれくらい代替的? 第2回(logit需要)、第3回(nested logit・IIA・価格内生性)、第4回(random coefficient logit・合併分析)
(b) 施策の因果効果を知る この広告キャンペーンは本当に売上を増やしたのか? この値下げの効果は? 第6回(コンジョイント・WTP)、第7回(A/Bテスト)、第8回(観察データの因果推論)
(c) 顧客の異質性と価値を知る どの顧客が優良顧客か? この顧客の生涯価値(CLV)はどれくらい? 第9回(階層モデル)、第10回(BG/NBD・CLV)
(d) 最適に配分・価格付けする 誰に割引クーポンを配るべきか? いつ・いくらで値付けすべきか? 第11回(uplift・policy learning)、第13回(動学的離散選択)、第14回(state dependence)、第15回(dynamic pricing)

第5回・第12回はゲスト講義(公正取引委員会、企業エコノミスト)で、実務の現場でこれらの問いがどう扱われているかを直接聞く回になる。

ノートビジネスの現場で:「この4つの問い、実際どう降ってくるか」

実務でデータ分析チームに来る依頼は、たいてい次のような形を取る。

  • 「新製品Xを出したら、既存製品YとZからどれくらい食われる(カニバリゼーション)か教えてほしい」→ (a) 需要と代替性
  • 「先月のテレビCM、本当に効果あったんですか? 感覚では『あった気がする』んですが」→ (b) 施策の因果効果
  • 「解約しそうな顧客を先に見つけて、リテンション施策を打ちたい」→ (c) 顧客の異質性
  • 「この夏のセールで、どの商品をどれだけ値下げすれば利益が最大になるか」→ (d) 最適化

依頼した本人は「これは需要分析です」「これは因果推論です」とラベル付けして持ってくるわけではない。曖昧な言葉で降ってきた依頼を、この4つの問いのどれに当たるかに翻訳する力こそが、実務で最初に鍛えられる勘所である。

3. Rシミュレーション1:広告費と売上の罠

さっそく手を動かしてみよう。ある小売チェーンで、店舗ごとの月間広告費と月間売上のデータが手に入ったとする。素朴に散布図を描いて回帰直線を引くと、広告費が多い店ほど売上が高い、という綺麗な右上がりの関係が見える。ここから「広告費を増やせば売上が増える」と結論づけてよいだろうか。

DGP(データ生成過程)を考えてみる。実際には、もともと立地が良く接客力もある「地力の強い店舗」ほど、本部が広告予算を多めに配分するという状況を考えよう。地力が強い店舗は、広告を出そうが出すまいが売上が高い。つまり地力(quality)という観測されない変数が、広告費と売上の両方に影響を与えている。これは計量Iで学んだ「交絡(confounding)」そのものだ。

まずこのDGPをコードに落とす。

n_stores <- 300

# 店舗の地力(立地・接客力など、観測されない潜在変数)
quality <- rnorm(n_stores, mean = 0, sd = 1)

# 広告費(万円/月):地力が高い店ほど本部が多く配分する + ノイズ
ad_spend <- 100 + 30 * quality + rnorm(n_stores, mean = 0, sd = 15)
ad_spend <- pmax(ad_spend, 10)

# 真の広告効果は小さい。地力の効果は大きい(交絡の源泉)
true_beta_ad <- 0.002       # 広告費が1万円増えると売上(log)が0.2%増える程度
true_beta_quality <- 0.4

log_sales_mean <- 5.0 + true_beta_quality * quality + true_beta_ad * ad_spend
log_sales <- log_sales_mean + rnorm(n_stores, mean = 0, sd = 0.15)
sales <- exp(log_sales)

store_df <- data.frame(
  store_id = 1:n_stores,
  quality = quality,
  ad_spend = ad_spend,
  sales = sales,
  log_sales = log_sales
)

head(store_df)
  store_id    quality  ad_spend     sales log_sales
1        1  1.0972203 158.32229 327.77992  5.792342
2        2  1.1241860 126.36172 215.34060  5.372221
3        3  0.6843835 120.59105 221.17181  5.398940
4        4 -1.9351903  20.35547  73.25654  4.293968
5        5 -1.9368942  10.00000  65.86206  4.187563
6        6  0.8246515 151.59929 278.07868  5.627904

まずは素朴に散布図と回帰直線を見てみよう。

ggplot(store_df, aes(x = ad_spend, y = log_sales)) +
  geom_point(alpha = 0.5, color = "steelblue") +
  geom_smooth(method = "lm", se = FALSE, color = "firebrick") +
  labs(x = "広告費(万円/月)", y = "log(売上)",
       title = "広告費と売上:一見強い正の相関")

広告費と売上(log)の関係:単純な散布図では強い正の関係に見える

回帰直線は右上がりで、広告費が売上を大きく押し上げているように見える。ここで、広告費だけを説明変数にしたOLS(地力を見ない、いわば「素朴な」分析)と、地力も入れたOLS(真のモデルに近い分析)を比較してみる。

fit_short <- lm(log_sales ~ ad_spend, data = store_df)
fit_long  <- lm(log_sales ~ ad_spend + quality, data = store_df)

summary(fit_short)$coefficients
              Estimate   Std. Error  t value      Pr(>|t|)
(Intercept) 3.97143478 0.0411238128 96.57263 6.421741e-227
ad_spend    0.01215281 0.0003881753 31.30752  3.152441e-96
summary(fit_long)$coefficients
               Estimate   Std. Error   t value      Pr(>|t|)
(Intercept) 4.978088898 0.0608435248 81.817891 9.188848e-206
ad_spend    0.002246662 0.0005936616  3.784416  1.863672e-04
quality     0.383118395 0.0205639533 18.630581  7.466642e-52
beta_short <- coef(fit_short)["ad_spend"]
beta_long  <- coef(fit_long)["ad_spend"]

comparison_df <- data.frame(
  model = c("素朴なOLS(ad_spendのみ)", "真のモデルに近いOLS(quality込み)", "真の値"),
  beta_ad = c(beta_short, beta_long, true_beta_ad)
)
knitr::kable(comparison_df, digits = 5,
             col.names = c("モデル", "広告費の係数"))
モデル 広告費の係数
素朴なOLS(ad_spendのみ) 0.01215
真のモデルに近いOLS(quality込み) 0.00225
真の値 0.00200

素朴なOLSでは広告費の係数が真の値よりもかなり大きく出る。地力という交絡因子を無視した結果、広告費が地力の効果まで「代わりに」拾ってしまっているからだ。地力をコントロールした回帰では、係数は真の値にかなり近づく。

ここで符号を図を見る前に確認しておこう。真の式を

\[ \log(\text{sales})=\beta_{\mathrm{ad}}\,\text{ad}+\beta_{q}\,\text{quality}+u \]

と書くと、qualityを落とした単回帰の係数は、大標本では

\[ \operatorname{plim}\hat\beta_{\mathrm{short}} =\beta_{\mathrm{ad}}+\beta_q\frac{\operatorname{Cov}(\text{ad},\text{quality})}{\operatorname{Var}(\text{ad})} \]

に近づく。このDGPでは \(\beta_q>0\) かつ \(\operatorname{Cov}(\text{ad},\text{quality})>0\) なので、欠落変数バイアスは上向きになる。散布図や推定結果は、この符号予想を確認している。

警告この分析、どこがまずい?

素朴な散布図と回帰直線だけを見て「広告は効果がある」と報告してしまうのが、実務でもっともよくある誤りの1つだ。相関が強いことと、その変数を動かせば結果が変わることは、まったく別の主張である。次に見るように、この2つの主張は「予測」と「因果」というまったく異なるタスクに対応している。

予測なら当たる、介入なら大外しする

ここが今回のシミュレーションの核心である。広告費入りの素朴なモデルは、「来月の売上を予測する」というタスクには実はよく機能する。なぜなら、地力の強い店舗は広告費も多いという相関関係が、これからも(本部の予算配分方針が変わらない限り)続くと考えられるからだ。広告費という変数は「地力の強さのシグナル」として機能し、予測の役には立つ。

一方で、「広告費を今の2倍にしたら売上はどうなるか」という介入(intervention)の効果を知りたい場合、素朴なモデルの係数をそのまま使うと大きく外れる。なぜなら、この介入は「地力が変わらないまま広告費だけを動かす」という操作であり、データの中にあった「地力が強いから広告費も多い」という相関関係を壊してしまうからだ。

まず予測タスクを検証する。データを学習用とホールドアウト用に分割し、素朴なモデル(広告費のみ)のホールドアウトでの当てはまりを見る。

set.seed(20261)
idx <- sample(1:n_stores)
train_idx <- idx[1:200]
test_idx  <- idx[201:300]

train_df <- store_df[train_idx, ]
test_df  <- store_df[test_idx, ]

fit_pred <- lm(log_sales ~ ad_spend, data = train_df)
pred_test <- predict(fit_pred, newdata = test_df)

ss_res <- sum((test_df$log_sales - pred_test)^2)
ss_tot <- sum((test_df$log_sales - mean(test_df$log_sales))^2)
r2_holdout <- 1 - ss_res / ss_tot

# ベースライン:広告費を使わず平均だけで予測した場合
baseline_pred <- rep(mean(train_df$log_sales), nrow(test_df))
ss_res_base <- sum((test_df$log_sales - baseline_pred)^2)
r2_base <- 1 - ss_res_base / ss_tot

data.frame(
  method = c("広告費を使う予測モデル", "ベースライン(平均のみ)"),
  holdout_R2 = c(r2_holdout, r2_base)
)
                    method   holdout_R2
1   広告費を使う予測モデル  0.717529257
2 ベースライン(平均のみ) -0.005744741
holdout_plot_df <- data.frame(
  actual = test_df$log_sales,
  predicted = pred_test
)

ggplot(holdout_plot_df, aes(x = predicted, y = actual)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_abline(slope = 1, intercept = 0, linetype = "dashed", color = "gray40") +
  labs(x = "予測されたlog(売上)", y = "実際のlog(売上)",
       title = "予測タスクとしては、素朴なモデルでも点は45度線付近に集まる")

ホールドアウトにおける実測値と予測値の対応:予測タスクとしてはよく当てはまっている

広告費を使うモデルのホールドアウトR²はかなり高く、平均だけで予測するベースラインよりずっと当てはまりが良い。上の図でも、予測値と実測値がおおむね45度線(破線)付近に集まっており、来月の売上を当てるという意味では悪くない予測モデルになっていることがわかる。つまり「来月の売上を予測する」という目的だけを考えるなら、広告費入りの素朴なモデルは十分役に立つ。

次に、介入予測を検証する。「広告費を2倍にする」という架空の施策を、(i) 真のモデル(地力を織り込んだ本当のDGP)と、(ii) 素朴なOLSモデル、それぞれで計算してみよう。

new_ad_spend <- store_df$ad_spend * 2

# 真のモデルによる効果:広告費の変化分だけがlog(売上)に影響する
true_effect <- true_beta_ad * (new_ad_spend - store_df$ad_spend)

# 素朴なOLSモデルによる(誤った)効果
ols_effect <- beta_short * (new_ad_spend - store_df$ad_spend)

effect_df <- data.frame(
  store_id = store_df$store_id,
  true_effect = true_effect,
  ols_effect = ols_effect
)

effect_summary <- data.frame(
  method = c("真の効果", "素朴なOLSによる予測"),
  mean_log_change = c(mean(true_effect), mean(ols_effect)),
  mean_pct_change = c(
    mean(exp(true_effect) - 1) * 100,
    mean(exp(ols_effect) - 1) * 100
  )
)
knitr::kable(effect_summary, digits = 3,
             col.names = c("手法", "log売上の平均変化", "店舗別の売上変化率の平均(%)"))
手法 log売上の平均変化 店舗別の売上変化率の平均(%)
真の効果 0.201 22.506
素朴なOLSによる予測 1.219 268.323

真の効果では、広告費を2倍にしても売上は2割程度しか増えない。ところが素朴なOLSモデルに基づいて予測すると、売上は3倍近くに増えるという、現実離れした数字が出てしまう。これは先ほどのホールドアウトR²が高かったのと同じモデルの話である。

true_mean_pct <- mean(exp(true_effect) - 1) * 100
ols_mean_pct <- mean(exp(ols_effect) - 1) * 100

compare_long <- bind_rows(
  data.frame(metric = "ホールドアウト", unit = "R²",
             series = c("素朴なモデル", "平均だけのベースライン"),
             value = c(r2_holdout, r2_base)),
  data.frame(metric = "広告費2倍", unit = "売上変化率(%)",
             series = c("素朴なモデル", "真の効果"),
             value = c(ols_mean_pct, true_mean_pct))
)

ggplot(compare_long, aes(x = metric, y = value, fill = series)) +
  geom_col(position = "dodge") +
  facet_wrap(~unit, scales = "free_y") +
  labs(x = NULL, y = NULL, fill = NULL,
       title = "予測タスクではよく当たるが、介入予測では大外しする") +
  theme(legend.position = "bottom")

同じモデルでも『予測』は当たり、『介入効果』は大外しする
重要ここが核心

同じ変数、同じ回帰式でも、「予測」と「因果(介入効果)」はまったく別のタスクである。 広告費と売上の相関を利用した予測モデルは、来月の売上を当てるという意味では優秀だ。しかし「広告費を動かしたらどうなるか」という問いに答えるには、その相関がどこから来ているのか(交絡因子は何か)を明示的に考えなければならない。この区別は、このコース全体を通じて何度も立ち返ることになる。

4. Rシミュレーション2:値上げすると販売数量が増える?

もう1つ、実務でよく起きる誤解を見ておこう。ある店舗の週次の価格と販売数量のデータがあるとする。log-log回帰(価格弾力性を推定する定番の方法)をかけると、価格の係数がに出ることがある。「値上げすると販売数量が増える」というのは常識的に考えて奇妙だが、これは一体何が起きているのか。

DGPを考える。繁忙期(需要が盛り上がっている時期)には、店舗側も強気の価格設定をするという状況を考えよう。需要が旺盛なタイミングでは価格を上げても売れるので、価格自体を吊り上げる。この結果、データの中では「価格が高い週ほど、需要ショックも大きいので、結果的に販売数量も多く見える」という状況が生まれる。

n_weeks <- 200

# 需要ショック(繁忙期・季節性など、観測しにくい変数)
demand_shock <- rnorm(n_weeks, mean = 0, sd = 1)

# 真の価格弾力性(負の値。需要曲線の傾き)
true_elasticity <- -1.2

# 価格設定:繁忙期には価格も強気に設定される(内生性の源泉)
gamma_price <- 0.3
log_price <- log(1000) + gamma_price * demand_shock + rnorm(n_weeks, mean = 0, sd = 0.05)
price <- exp(log_price)

# 真の需要関数:価格1,000円のときの基準数量を500に置く
phi_demand <- 0.8
log_q_mean <- log(500) + true_elasticity * (log_price - log(1000)) +
  phi_demand * demand_shock
demand_noise <- rnorm(n_weeks, mean = 0, sd = 0.1)
log_q <- log_q_mean + demand_noise
q <- exp(log_q)

price_df <- data.frame(
  week = 1:n_weeks,
  demand_shock = demand_shock,
  demand_noise = demand_noise,
  price = price,
  log_price = log_price,
  q = q,
  log_q = log_q
)

head(price_df)
  week demand_shock demand_noise     price log_price        q    log_q
1    1   0.31421111 -0.045280445 1074.8959  6.979979 563.4215 6.334028
2    2   0.35295547  0.031216091 1046.1655  6.952887 648.0907 6.474031
3    3  -0.25203424  0.287393683  877.3696  6.776928 637.3805 6.457367
4    4   0.37780491  0.136340351 1122.4189  7.023241 674.9300 6.514609
5    5  -0.34336568  0.072521568  904.7373  6.807645 460.6184 6.132570
6    6   0.03773334  0.002205603 1080.5704  6.985244 470.6023 6.154013
ggplot(price_df, aes(x = log_price, y = log_q)) +
  geom_point(alpha = 0.5, color = "darkorange") +
  geom_smooth(method = "lm", se = FALSE, color = "firebrick") +
  labs(x = "log(価格)", y = "log(販売数量)",
       title = "価格と数量:log-log回帰では正の関係に見える")

価格と販売数量(log-log):回帰線は右上がりに見える

log-log OLSで価格弾力性を推定してみる。

fit_price_ols <- lm(log_q ~ log_price, data = price_df)
summary(fit_price_ols)$coefficients
             Estimate Std. Error   t value     Pr(>|t|)
(Intercept) -3.171584 0.25097151 -12.63723 3.140887e-27
log_price    1.356950 0.03614709  37.53967 5.617124e-92
elasticity_hat_ols <- coef(fit_price_ols)["log_price"]

data.frame(
  method = c("OLS推定値", "真の弾力性"),
  elasticity = c(elasticity_hat_ols, true_elasticity)
)
              method elasticity
log_price  OLS推定値    1.35695
          真の弾力性   -1.20000

推定された価格係数はプラスになっている。真の弾力性は-1.2(値上げすれば需要は減る、という普通の需要曲線)なのに、OLSでは符号まで逆転してしまっている。これは、需要ショックという変数が価格と需要の両方を同時に押し上げているために起きる価格の内生性(price endogeneity)である。

なぜこんなことが起きるのか、真の需要曲線(需要ショックを固定して、価格だけを動かした場合にどうなるか)と、データから引かれたOLSの回帰直線を重ねて図示してみよう。

price_grid <- seq(min(price_df$price), max(price_df$price), length.out = 50)
log_price_grid <- log(price_grid)

# 真の需要曲線:需要ショックを0(平均的な状態)に固定し、価格だけを動かす
true_log_q_grid <- log(500) + true_elasticity * (log_price_grid - log(1000)) +
  phi_demand * 0
true_curve_df <- data.frame(price = price_grid, log_q = true_log_q_grid, curve = "真の需要曲線(需要ショック固定)")

# OLSの回帰直線
ols_log_q_grid <- coef(fit_price_ols)["(Intercept)"] + elasticity_hat_ols * log_price_grid
ols_curve_df <- data.frame(price = price_grid, log_q = ols_log_q_grid, curve = "OLS回帰直線(データから引いた線)")

curve_compare_df <- rbind(true_curve_df, ols_curve_df)

ggplot() +
  geom_point(data = price_df, aes(x = price, y = log_q), alpha = 0.3, color = "gray60") +
  geom_line(data = curve_compare_df, aes(x = price, y = log_q, color = curve, linetype = curve), linewidth = 1) +
  labs(x = "価格", y = "log(販売数量)", color = NULL, linetype = NULL,
       title = "真の需要曲線は右下がり、OLSの回帰直線は右上がり") +
  theme(legend.position = "bottom")

真の需要曲線(需要ショックを平均に固定)とOLS回帰直線:向きが逆転している

灰色の点は実際に観測されたデータ(価格と需要ショックが両方動いた結果)である。もし需要ショックを平均的な水準に固定して価格だけを動かせば、需要曲線は本来右下がりになるはずだが(実線)、観測データにそのままOLSを当てはめると、需要ショックの影響を吸収しきれずに右上がりの直線が引かれてしまう(破線)。この2本の線の向きの違いこそが、価格の内生性が引き起こす問題を視覚的に要約したものである。

ノートビジネスの現場で:「セール中は値下げしたのに数量が減った」の逆パターン

似た混乱は価格設定の現場で頻繁に起きる。「繁忙期に値上げしたのに販売数量が伸びた」という現象を見て、値上げそのものが数量を伸ばしたと誤解してしまうケースだ。実際には繁忙期の需要の強さが価格と数量の両方を押し上げているだけであり、同じ繁忙期にもし値上げをしなければ、もっと数量は伸びていたかもしれない。この錯覚は、次回以降で学ぶ価格の内生性の議論と直結している。

真の反実仮想とOLSに基づく反実仮想を比較する

ここでも「価格を10%上げたら販売数量・売上はどう変わるか」という反実仮想を、(i) 真のモデル、(ii) OLSで推定した(内生性に汚染された)モデル、の両方で計算してみよう。

new_price <- price_df$price * 1.10
new_log_price <- log(new_price)

# 真のモデルによる反実仮想:価格だけを動かし、需要ショックと個別ノイズは同じ値に保つ
true_new_log_q <- log(500) + true_elasticity * (new_log_price - log(1000)) +
  phi_demand * demand_shock + demand_noise
true_pct_change_q <- (exp(true_new_log_q) - price_df$q) / price_df$q * 100

# OLSモデルによる(内生性に汚染された)反実仮想
ols_intercept <- coef(fit_price_ols)["(Intercept)"]
ols_new_log_q <- ols_intercept + elasticity_hat_ols * new_log_price
ols_old_log_q_fitted <- ols_intercept + elasticity_hat_ols * price_df$log_price
ols_pct_change_q <- (exp(ols_new_log_q) - exp(ols_old_log_q_fitted)) / exp(ols_old_log_q_fitted) * 100

cf_demand_df <- data.frame(
  method = c("真のモデル", "OLSモデル"),
  mean_pct_change_q = c(mean(true_pct_change_q), mean(ols_pct_change_q))
)
knitr::kable(cf_demand_df, digits = 2,
             col.names = c("手法", "価格+10%のときの需要変化(%)"))
手法 価格+10%のときの需要変化(%)
真のモデル -10.81
OLSモデル 13.81

真のモデルでは、価格を10%上げると需要(販売数量)は1割程度減る。これは弾力性-1.2から予想される通りの、ごく普通の需要曲線の反応である。ところがOLSモデルに基づいて計算すると、価格を10%上げたら需要が増えるという、経済学の教科書をひっくり返すような結論になってしまう。

売上(revenue = 価格 × 数量)で見ても同様の食い違いが起きる。

true_new_revenue <- new_price * exp(true_new_log_q)
old_revenue <- price_df$price * price_df$q
true_rev_change <- (true_new_revenue - old_revenue) / old_revenue * 100

ols_new_revenue <- new_price * exp(ols_new_log_q)
ols_old_revenue_fitted <- price_df$price * exp(ols_old_log_q_fitted)
ols_rev_change <- (ols_new_revenue - ols_old_revenue_fitted) / ols_old_revenue_fitted * 100

cf_revenue_df <- data.frame(
  method = c("真のモデル", "OLSモデル"),
  mean_pct_change_revenue = c(mean(true_rev_change), mean(ols_rev_change))
)
knitr::kable(cf_revenue_df, digits = 2,
             col.names = c("手法", "価格+10%のときの売上変化(%)"))
手法 価格+10%のときの売上変化(%)
真のモデル -1.89
OLSモデル 25.19
cf_plot_df <- data.frame(
  metric = rep(c("需要(数量)の変化(%)", "売上の変化(%)"), each = 2),
  method = rep(c("真のモデル", "OLSモデル"), 2),
  value = c(mean(true_pct_change_q), mean(ols_pct_change_q),
            mean(true_rev_change), mean(ols_rev_change))
)

ggplot(cf_plot_df, aes(x = metric, y = value, fill = method)) +
  geom_col(position = "dodge") +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray40") +
  labs(x = NULL, y = "変化率(%)", fill = NULL,
       title = "価格+10%の反実仮想:真のモデル vs OLSモデル") +
  theme(legend.position = "bottom")

価格+10%の反実仮想:真のモデルとOLSモデルで結論が正反対になる

真のモデルでは「値上げすれば数量は減り、売上もわずかに減る(弾力性がほぼ1に近いため)」という結論になるのに対し、OLSモデルでは「値上げすれば数量も売上も大きく増える」という真逆の結論が出てしまう。もしこの誤ったモデルを信じて値上げを実行すれば、需要ショックが弱い時期に価格を上げてしまい、痛い目を見ることになるだろう。

重要次回への伏線

この価格の内生性という問題こそ、需要推定における最大の技術的難所である。第3回では、この問題にどう対処するか(操作変数法の応用、コストシフターの利用など)を、離散選択モデルの文脈で本格的に扱う。計量Iで学んだ2SLSの考え方がそのまま使えることを、次回以降で確認していく。

5. 反実仮想とは何か

ここまで見てきた「広告費を2倍にしたら」「価格を10%上げたら」という計算が、まさに反実仮想(counterfactual)である。反実仮想とは、「もしあの時、実際に起きたこととは違う選択をしていたら、結果はどうなっていたか」をモデルを使って計算することだと定義できる。

計量経済学Iで学んだ因果推論の道具(DiD、IV、RDDなど)も、広い意味では反実仮想を扱っている。「もしこの処置を受けていなかったら」という潜在アウトカムを、実際に観測されたデータの変動を利用して推定するのがそれらの手法だった。これらの設計が最も説得力を持つのは、通常、実際に観測された処置や共変量の支持範囲に近い問いである。支持範囲の外へ因果効果を外挿すること自体は不可能ではないが、効果の関数形や不変性について追加の仮定が必要になる。例えば、5%の値上げの変動から「50%値上げしたらどうなるか」「まったく新しい価格帯ならどうなるか」を答えるには、研究デザインだけでは足りない。

これに対して、需要関数や効用関数といった構造モデルを推定しておけば、データの中に実際に存在しない価格や商品構成についても、モデルの数式に従った結果を計算できる。これが構造推定(structural estimation)のアプローチであり、「構造推定とは、反実仮想シミュレーションをするためにモデルのパラメータを推定する作業である」とまとめることができる。ただし、計算可能であることと信頼できることは別である。遠い外挿ほど、効用の関数形、パラメータの政策不変性、企業行動や均衡の仮定に結果が強く依存するため、感度分析とモデル診断が欠かせない。

このコースで扱う反実仮想の具体例を、少し先取りして挙げておこう。

  • 合併審査(第4〜5回):2つの企業が合併したら、統合後の会社は価格をどう変えるインセンティブを持つか。需要の代替性(自社製品同士がどれだけ競合しているか)と供給側の価格設定モデルを組み合わせて、合併後の均衡価格をシミュレーションする。これは公正取引委員会などの独占禁止当局が実際に行っている分析そのものである。
  • 価格最適化(第15回):将来の需要変動や在庫状況を織り込んだ上で、いつ・いくらで値付けすれば利益(または売上)が最大になるかを、動的計画法を使ってシミュレーションする。

3つの概念の違いを、もう一度整理しておこう。

  • 予測(prediction):既存の相関構造を使って、観測されていない値(多くは将来の値)を当てにいくタスク。因果関係である必要はないが、学習時の相関構造が予測先でも安定していることが必要である。機械学習の多くの応用はここに属する。
  • 因果効果(causal effect):ある1つの処置・施策について、「その施策をした場合としなかった場合の差」を測るタスク。処置は通常、実際にデータの中で(一部の主体に対して)起きたものに限られる。
  • 反実仮想(counterfactual)/構造推定:モデル(需要関数、効用関数、企業の価格設定行動のモデルなど)を推定し、そのモデルを使って、データの中に実際には存在しない状況(新しい価格、新しい商品、新しい市場構造)の結果を計算するタスク。

3つは互いに排他的ではない。因果推論の道具(IV、DiDなど)は、構造モデルのパラメータを識別・推定するためにしばしば使われる(第3回のBerry反転+IV推定がその代表例)。つまりこのコースは、「予測」から「因果」を経て「反実仮想」へと視野を広げていく旅だと理解しておくとよい。

問いを受け取ったら、次の順で必要な材料を一段ずつ足すと混乱しにくい。

タスク 典型的な問い 最低限必要なもの
予測 今の運用が続くと来月の需要は? 予測精度と分布の安定性
支持範囲内の因果効果 実施された5%値上げの効果は? 比較可能な反実仮想を作る識別戦略
構造的反実仮想 未経験の価格・新商品・合併なら? 識別された行動パラメータと不変性・均衡の仮定
最適化 どの価格・配分を選ぶべきか? 反実仮想を計算するモデルに加え、目的関数と制約

6. 実証研究コーナー

ヒント実証研究コーナー:Chintagunta, Erdem, Rossi, and Wedel (2006)

研究の問い:マーケティングサイエンスにおける「構造モデリング(structural modeling)」とは何か。それは還元形(reduced-form)の分析とどう違い、どのような利点・コストを持つのか。

データ・アプローチ:この論文はMarketing Science誌の特集号の序文として書かれたレビュー論文であり、単一のデータセットを分析するものではない。むしろ、構造モデルを用いたquantitative marketingの一連の研究(ブランド選択モデル、価格設定モデル、広告効果モデルなど)を概観し、方法論としての位置づけを整理している。

識別戦略・モデル:構造モデルは、消費者や企業の意思決定を明示的な効用最大化・利潤最大化問題として定式化し、そのモデルのパラメータをデータから推定する。これにより、観測されたデータの範囲を超えた反実仮想(新製品導入、価格変更、規制変化など)のシミュレーションが可能になる、という点が還元形分析との大きな違いとして強調される。

主要な発見:この論文では、構造モデルが果たす役割を「政策の反実仮想シミュレーションを可能にすること」「観測されないパラメータ(選好の異質性など)に経済学的な解釈を与えること」の2点に整理し、複数の応用領域(少なくとも10以上の異なるマーケティング上の意思決定領域)にわたって構造モデルが使われてきたことを紹介している。

このトピックとの関係:まさに今回のシミュレーション2で見た「反実仮想を計算するにはモデルが必要だ」という主張を、方法論の言葉で正面から論じた文献である。第2回以降で学ぶ離散選択モデルは、この論文が言う「構造モデル」の最も基本的な形の1つに当たる。

ヒント実証研究コーナー:Athey and Luca (2019)

研究の問い:テック企業で働く経済学者(エコノミスト)は、実際にどのような仕事をしているのか。経済学の博士号を持つ人材が企業に採用されることは、経済学という学問にとってどのような意味を持つのか。

データ・アプローチ:Journal of Economic Perspectives誌に掲載されたこの論文は、Amazon、Microsoft、Uber、eBay、Airbnbといった主要テック企業における経済学者チームの活動を、著者らの直接の観察・インタビューに基づいて整理したものである。

識別戦略・モデル:この論文自体は特定の統計モデルを推定するものではなく、企業内でエコノミストが担う役割を類型化する記述的な研究である。エコノミストの仕事は、大きく「A/Bテストなどの実験デザインの設計・評価」「マーケットデザイン(オークション設計、マッチングアルゴリズムなど)」「予測・機械学習との連携」「経営陣への政策提言」といった領域に整理される。

主要な発見:2010年代後半にかけて、主要テック企業における経済学PhD人材の採用が急速に増加したことが指摘されている。エコノミストは単にデータ分析をするだけでなく、プラットフォームの設計そのもの(オークション形式、レコメンデーションアルゴリズム、料金体系)に関与するようになっている点が強調される。

このトピックとの関係:この講義が「公開講座として企業のデータ分析担当者も受講する」ことの背景そのものを説明している論文である。実証IO・quantitative marketingで学ぶ道具(需要推定、因果推論、構造モデル)が、まさにこの論文で描かれるような企業内エコノミストの実務で使われている。

ヒント実証研究コーナー:Einav and Levin (2014)

研究の問い:ビッグデータの登場は、経済学(特に実証経済学)の研究手法をどう変えるのか。

データ・アプローチ:Science誌に掲載されたこの論文は、企業や政府が保有する大規模なトランザクションデータ(POS、検索ログ、税務データなど)が、経済学の実証研究にとってどのような新しい機会と課題をもたらすかを論じている。

識別戦略・モデル:特定の計量モデルを推定する論文ではなく、方法論的な論考である。著者らは、ビッグデータが経済学研究にもたらす変化を、(i) 従来は観測不可能だった行動(検索、閲覧、迷いなど)が観測可能になること、(ii) リアルタイムに近いデータで政策・施策の効果を評価できるようになること、(iii) 予測タスクにおいて機械学習的な手法との融合が進むこと、の3点に整理している。

主要な発見:ビッグデータは経済学の理論的な問い(因果関係の識別、構造モデルの妥当性)を置き換えるものではなく、むしろそれらの問いに答えるための材料を豊富にするものだ、という立場が示されている。単に「データが大きくなった」だけでは因果関係は識別できず、実験デザインや構造モデルといった従来の道具の重要性はむしろ増す、という主張が中心にある。

このトピックとの関係:今回学んだ「予測と因果は別のタスクである」という教訓を、ビッグデータ時代においてどう活かすべきかを論じた文献である。データが大きくなればなるほど、相関と因果を混同する誘惑も大きくなる、という警鐘として読むとよい。

ヒントおもしろ枠:Varian (2014)

研究の問い:ビッグデータ時代に、計量経済学者は機械学習のどのような手法を「新しい道具」として取り入れるべきか。

データ・アプローチ:Journal of Economic Perspectives誌に掲載されたこの論文(“Big Data: New Tricks for Econometrics”)は、Google社のチーフエコノミストを務めた著者が、決定木、ランダムフォレスト、正則化(LASSOなど)といった機械学習の手法を、経済学者にもわかる言葉で紹介した入門的な論考である。

識別戦略・モデル:この論文自体はモデルを推定するのではなく、教育的なチュートリアルとして書かれている。回帰木やクロスバリデーションといった機械学習の基本概念を、計量経済学者が馴染んでいる回帰分析の枠組みと対比させながら説明している。

主要な発見:機械学習の手法は「予測」タスクにおいては強力だが、それだけでは「因果効果の推定」という経済学者が重視するタスクには直接使えない、という論点が明確に示されている。両者を組み合わせる(例えば傾向スコアの推定に機械学習を使う)ことで、より柔軟で頑健な因果推論が可能になる、という方向性が示唆されている。

このトピックとの関係:今回のシミュレーションで扱った「予測モデルは当たるが介入効果は外れる」という教訓の、機械学習版の解説として読める。第11回で学ぶuplift・policy learningの背景にある問題意識にもつながっている。

7. ビジネスの現場で

ノートビジネスの現場で:依頼を「予測・効果検証・最適化」に仕分ける

データ分析チームに実際に来る依頼を、次の3つのタスクに仕分ける練習をしてみよう。

  • 予測タスク:「来月の在庫、どれくらい発注すればいいですか」「この顧客は来月解約しそうですか」。過去の相関パターンをそのまま将来に当てはめてよいタスク。
  • 効果検証タスク:「先月のクーポン施策、本当に売上を増やしたんですか」「新しいアプリのUI変更は、離脱率を下げたんですか」。ある1つの施策の因果効果を測るタスク。A/Bテストができるなら理想的(第7回)だが、できない場合は観察データからの因果推論(第8回)が必要になる。
  • 最適化タスク:「どの顧客に、いくらのクーポンを配れば利益が最大になりますか」「この夏のセールで、どの商品をどれだけ値下げすべきですか」。反実仮想シミュレーションと組み合わせて、意思決定そのものを最適化するタスク。

同じ「価格を下げたら売上はどうなるか」という質問でも、「来月の売上予測に使いたいだけ」なのか、「本当にその値下げが効果があったのか検証したい」のか、「最適な値下げ幅を知りたい」のかによって、必要な分析はまったく違う。依頼の言葉をそのまま受け取らず、この3分類のどれに当たるかをまず見極めるのが実務の第一歩である。

ノートビジネスの現場で:「A/Bテストできない意思決定リスト」

実験(A/Bテスト)は因果効果を測るための最も強力な道具だが、すべての意思決定に使えるわけではない。以下は、実務でA/Bテストが難しい(あるいは事実上不可能な)意思決定の例である。

  • 全社的な値上げ:一部の店舗・顧客だけ価格を変えると、公平性の問題や顧客の不満(同じ商品なのに店舗によって値段が違う)を招きやすい。
  • テレビCM・マス広告:地域単位でしか出し分けができず、地域間で需要構造が違うため、綺麗な実験にはなりにくい。
  • 店舗の大規模改装:コストと時間がかかりすぎて、多数の店舗で同時に「改装する店」「しない店」をランダムに割り当てるのは非現実的。
  • 企業の合併:そもそも「合併する場合としない場合」を複数の世界で試すことはできない。

こうした意思決定に対しては、観察データを使った因果推論(第8回)や、需要・供給の構造モデルによる反実仮想シミュレーション(第3〜5回、第15回)が主要な武器になる。このコースの後半で学ぶ技術の多くは、まさに「実験ができない状況でどう意思決定を支えるか」という問題への答えである。

まとめ

重要まとめ
  • 計量経済学IIは、計量経済学Iで学んだ「識別・推定・推論」の3ステップと「モデル=条件付き分布の束」という考え方を土台に、意思決定のための反実仮想シミュレーションを組み立てることを目指す。
  • 実証ビジネス・エコノミクス、実証IO、quantitative marketingは、いずれも「データを使って企業・政策の意思決定を支える」という目的を共有する隣接分野であり、企業の意思決定は(a)需要と代替性、(b)施策の因果効果、(c)顧客の異質性、(d)最適な配分・価格付け、という4つの問いに整理できる。
  • 「予測」と「因果」はまったく別のタスクである。広告費と売上の相関を使ったモデルは、来月の売上予測にはよく効くが、「広告費を動かしたらどうなるか」という介入予測には大きく外れることがある。
  • 価格と需要の関係も同様の罠を持つ。繁忙期に価格も需要も同時に上がるというDGPの下では、log-log OLSの価格係数の符号すら逆転し、値上げの反実仮想を大きく見誤る。
  • 反実仮想とは「もしあの時○○していたら」をモデルで計算することであり、構造推定とはそのためのパラメータ推定作業である。合併審査や価格最適化など、このコース後半の多くのトピックがこの考え方の応用である。
  • 実験(A/Bテスト)ができない意思決定は数多く存在し、そこでは観察データの因果推論や構造モデルによる反実仮想シミュレーションが主要な武器になる。

宿題

  • ブラウザ実験室(playground1.html)で、今回のシミュレーションの数値を自分でいじって遊んでみよう。インストール不要、ブラウザだけでRが動く(初回ロードのみ30秒〜1分かかる)。
  • 計量経済学Iの自分のノートを見返し、「識別・推定・推論」の3ステップと「モデル=条件付き分布の束」という考え方について、自分の言葉で3行程度にまとめ直してみよう。
  • ChatGPT(または他の対話型AI)に「反実仮想とは何か、経済学の文脈で説明してください」と聞いてみて、自分がこのノートで学んだ内容とどう違う・同じかを比べてみよう。
  • 自分の仕事(または身近な企業)で「A/Bテストができない意思決定」を1つ挙げ、それがどうすれば分析できそうか(観察データの利用? 構造モデル?)を考えてみよう。
  • coding課題は assignment1.qmd を参照。今回の価格弾力性のシミュレーションを、店舗パネルデータに拡張し、操作変数法(2SLS)で真の弾力性を回収する練習をする。

次回予告

次回(第2回)では、今回のシミュレーション2で見た「消費者は複数の選択肢の中から1つを選ぶ」という状況を、確率的効用最大化モデル(random utility model, RUM)としてきちんと定式化する。消費者が財の効用を比較して選択するというモデルから、有名な「logitモデル」の選択確率の式を導出し、計量Iでは扱わなかった最尤法(maximum likelihood estimation)を初めて学ぶ。さらに、価格弾力性・交差弾力性の計算方法も導入する。ここから数回にわたって、離散選択モデルという、実証IO・quantitative marketingの中心的な道具を身につけていくことになる。

参考文献

  • 上武康亮・遠山祐太・若森直樹・渡辺安虎 (2025)『実証ビジネス・エコノミクス』日本評論社、第1章。
  • Chintagunta, P., Erdem, T., Rossi, P. E., and Wedel, M. (2006) “Structural Modeling in Marketing: Review and Assessment,” Marketing Science, 25(6), 604-616.
  • Athey, S. and Luca, M. (2019) “Economists (and Economics) in Tech Companies,” Journal of Economic Perspectives, 33(1), 209-230.
  • Einav, L. and Levin, J. (2014) “Economics in the Age of Big Data,” Science, 346(6210), 1243089.
  • Varian, H. R. (2014) “Big Data: New Tricks for Econometrics,” Journal of Economic Perspectives, 28(2), 3-28.