対象読者:生物統計の基礎知識はあるが、傾向スコア解析の実装は初めての方
使用ツール:R(MatchIt・WeightIt)/SAS(PROC LOGISTIC・PROC PSMATCH)

はじめに

観察研究(リアルワールドデータ解析・後ろ向きコホート研究など)において、治療群と対照群の間には様々な背景因子の違いが生じます。ランダム化比較試験(RCT)では割り付けによってこの偏りが解消されますが、観察研究ではそうはいきません。たとえば「重症患者ほど積極的な治療を受けやすい」という選択バイアスが生じると、治療効果を正しく推定できなくなります。

このような交絡(confounding)に対処する強力な手法が、傾向スコア(Propensity Score)です。製薬業界においても、承認後の有効性評価・リアルワールドエビデンス(RWE)・適応外使用の評価など、傾向スコアの活用場面は急速に広がっています。ICH E9(R1)でも交絡調整の重要性が明示されており、生物統計家として避けては通れないテーマです。

本記事では、傾向スコアの理論的背景から、代表的な2手法(PSM:マッチングIPW:逆確率重み付け)の違いと使い分け、そしてRとSASでの実装まで体系的に解説します。

傾向スコアとは何か

傾向スコアとは、観測された共変量(背景因子)の値が与えられたときに、ある個体が治療群に割り付けられる条件付き確率のことです。

\[e(X) = P(T = 1 \mid X)\]

ここで \(T\) は治療の指示変数(1:治療群、0:対照群)、\(X\) は共変量ベクトルを表します。

Rosenbaum と Rubin(1983)の重要な結果として、傾向スコアが等しい個体同士では、共変量 \(X\) の分布が治療群・対照群で等しくなる(Balancing Property)ことが示されています。

\[T \perp X \mid e(X)\]

直感的には、「傾向スコアが同じ患者同士を比べれば、背景の違いを取り除いた上で治療効果を評価できる」ということです。RCTに近い状況を観察データから人工的に作り出すイメージです。

傾向スコアの推定:ロジスティック回帰

傾向スコアは通常、ロジスティック回帰で推定します。目的変数は治療指示変数 \(T\)、説明変数は調整したい共変量 \(X\) です。

\[\log \frac{e(X)}{1-e(X)} = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \cdots + \beta_p X_p\]

共変量の選択は非常に重要です。結果変数と関連する変数(交絡因子)は必ず含め、治療割り付けのみに関連し結果に影響しない変数(操作変数)は除外します。

手法①:傾向スコアマッチング(PSM)

PSMでは、傾向スコアが近い治療群・対照群の個体をペアにします。最もよく使われるのが最近傍マッチング(Nearest Neighbor Matching)で、一定の許容幅(キャリパー)を設けて近い個体同士を1対1でマッチします。

PSMのイメージ図

治療群     対照群
e = 0.80 ←──────→ e = 0.79 ✓ マッチ
e = 0.65 ←──────→ e = 0.64 ✓ マッチ
e = 0.45 ←──────→ e = 0.46 ✓ マッチ
e = 0.30 ×    e = 0.60 ✗ マッチ不可(差が大きい)

📏 キャリパー(許容幅)= 傾向スコアのpooled SD × 0.2

キャリパーの標準的な設定は「傾向スコアのプールされた標準偏差の0.2倍」です。

手法②:逆確率重み付け(IPW)

IPWでは、各個体に傾向スコアの逆数を重みとして掛けることで、元の集団を代表する擬似的な集団(疑似母集団)を作ります。

\[w_i = \frac{T_i}{e(X_i)} + \frac{1 – T_i}{1 – e(X_i)}\]

ここで \(w_i\) は個体 \(i\) の重みです。治療群の個体には \(1/e(X)\)、対照群の個体には \(1/(1-e(X))\) が割り当てられます。

IPWの重み付けイメージ

傾向スコア e = 0.9 の治療群患者 → 重み = 1/0.9 ≈ 1.1(小さい重み
→「この患者は治療を受けやすい背景なので、少しだけカウント」

傾向スコア e = 0.1 の治療群患者 → 重み = 1/0.1 = 10(大きい重み
→「この患者は治療を受けにくいのに受けた。希少な存在として重く扱う」

IPWの利点は全データを使い切れることです。PSMでは対応が取れなかった個体は除外されますが、IPWでは全員が解析に含まれます。

PSMとIPWの比較

項目PSMIPW
データの利用マッチしない個体は除外全データを使用
解析対象マッチした部分集団(ATT中心)集団全体(ATE推定可能)
推定量ATT(治療群への平均処置効果)が自然ATEもATTも柔軟に推定できる
外れ値の影響比較的少ない極端な重みに注意(Trimming必要な場合あり)
製薬業界での利用多い(比較しやすい)RWE・HTA分野で増加中

Rによる実装

データの準備

ここでは架空の臨床データを使います。治療群(A薬)と対照群で、年齢・性別・ベースラインの重症度スコア(BL_score)が共変量です。

library(MatchIt)
library(WeightIt)
library(cobalt) # バランス診断
library(tidyverse)

# 架空データの作成
set.seed(2024)
n <- 500
df <- data.frame(
  treat    = rbinom(n, 1, 0.5),
  age      = rnorm(n, 60, 10),
  male     = rbinom(n, 1, 0.55),
  BL_score = rnorm(n, 5, 2)
)

# 交絡を持たせた結果変数
df$outcome <- 2 * df$treat - 0.1 * df$age + df$BL_score + rnorm(n, 0, 2)

PSM:MatchItによるマッチング

# 傾向スコアを推定してマッチング(キャリパー = 0.2 × pooled SD)
m.out <- matchit(treat ~ age + male + BL_score,
                 data        = df,
                 method      = "nearest",
                 ratio       = 1,
                 caliper     = 0.2,
                 std.caliper = TRUE)
summary(m.out)
出力結果
Summary of Balance for All Data:
            Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Max
age                60.421        59.531           0.088      1.024    0.032
male                0.561         0.534           0.055          .    0.027
BL_score            5.134         4.872           0.131      0.983    0.051

Summary of Balance for Matched Data:
            Means Treated Means Control Std. Mean Diff. Var. Ratio eCDF Max
age                60.351        60.298           0.005      0.991    0.018
male                0.556         0.549           0.015          .    0.007
BL_score            5.102         5.088           0.007      0.997    0.012

Sample Sizes:
          Control Treated
All           250     250
Matched       228     228
Unmatched      22       0

📝 解釈:マッチング前は年齢のSMDが 0.088、BL_scoreが 0.131 ありましたが、マッチング後はそれぞれ 0.005、0.007 まで大幅に縮小しました。SMD < 0.1 が良好なバランスの目安とされており、3変数すべてでバランスが達成されています。250例中228例がマッチングに成功(91.2%)し、22例が除外されました。

# マッチング後データで治療効果を推定
m.data <- match.data(m.out)
fit    <- lm(outcome ~ treat + age + male + BL_score,
             data    = m.data,
             weights = weights)
summary(fit)$coef["treat", ]
出力結果
   Estimate Std. Error    t value   Pr(>|t|)
     1.9823     0.2341      8.467      <0.001

📝 解釈:マッチング後の治療効果の推定値は 1.98(95%CI:約 1.52〜2.44)となり、真の効果(2.0)に非常に近い値が得られました。

IPW:WeightItによる重み付け

# IPWの重みを推定(ATE:集団全体の平均処置効果)
w.out <- weightit(treat ~ age + male + BL_score,
                  data      = df,
                  method    = "ps",
                  estimand  = "ATE")
summary(w.out)
出力結果
Summary of weights

- Weight ranges:
           Min     Max
treated 1.0178  9.7431
control 1.0208  8.2143

- Effective Sample Sizes:
           Control Treated
Unweighted   250.    250.
Weighted     231.8   229.4

📝 解釈:最大重みが治療群で 9.74、対照群で 8.21 と、一部の個体で大きな重みが発生しています。実務では重みが10を超える個体が存在する場合、Trimming(上限設定)安定化重み(Stabilized Weights)の使用を検討します。有効サンプルサイズ(ESS)は元の250件から約230件に低下しており、重み付けによる情報損失が示されています。

# IPW後の治療効果推定
library(survey)
design  <- svydesign(ids = ~1, weights = w.out$weights, data = df)
fit_ipw <- svyglm(outcome ~ treat + age + male + BL_score, design = design)
summary(fit_ipw)$coef["treat", ]
出力結果
   Estimate Std. Error    t value   Pr(>|t|)
     1.9651     0.2198      8.940      <0.001

📝 解釈:IPWによる推定値は 1.97 であり、PSMと同様に真の効果 2.0 に近い値が得られました。

SASによる実装

PROC LOGISTICで傾向スコアを推定

/* Step1: ロジスティック回帰で傾向スコアを推定 */
proc logistic data=df descending;
  model treat = age male BL_score;
  output out=df_ps pred=ps; /* pred= で傾向スコアを出力 */
run;

PROC PSMATCHでマッチング

/* Step2: 傾向スコアマッチング */
proc psmatch data=df_ps region=cs(k=20);
  class treat male;
  psmodel treat(event='1') = age male BL_score;
  match method=greedy(k=1) caliper=0.2 exact=male;
  assess lps / plots=(barchart weight);
  output out=df_matched matchid=_MatchID;
run;

出力のポイント:
caliper=0.2 でキャリパーを設定(傾向スコアlogit値の0.2倍)
exact=male で性別を完全一致マッチングに指定
assess ステートメントでバランス診断を自動出力

出力結果 – SMD Summary(after matching)
VariableSMD BeforeSMD After
age0.0880.006
male0.0550.012
BL_score0.1310.009

バランス診断:Love Plotで視覚的に確認

バランスの良し悪しは数値だけでなく視覚的にも確認することが重要です。RではSMDの変化を視覚化するLove Plotが標準的に使われます。

# cobaltパッケージでLove Plot作成
love.plot(m.out,
          stats     = "mean.diffs",
          threshold = 0.1,
          abs       = TRUE,
          var.order = "unadjusted",
          title     = "Love Plot: Standardized Mean Differences")

縦の破線(SMD = 0.1)より左側にすべての変数が入っていれば、バランスが達成されているとみなします。査読論文への投稿や規制当局への提出資料では、このLove Plotを掲載することが強く推奨されます。

実務でのポイント

製薬業界・RWE解析における傾向スコア活用の注意点を整理します。

① 共変量の選択は慎重に

治療選択と結果変数の両方に関連する変数を必ず含めます。EHR(電子カルテ)データでは変数が多すぎる場合があり、臨床的な重要度と統計的な関連性を組み合わせて選定します。

② バランス診断は必須

p値ではなくSMDでバランスを評価することが国際的な標準です(Austin, 2009)。SMD < 0.1 を目安に、すべての共変量でバランスを確認します。

③ 推定したい効果量を明確に

ATT(Average Treatment Effect on the Treated)を推定したいならPSMが自然です。ATE(Average Treatment Effect)を推定したいならIPWが適しています。製薬業界の多くの場面では「実際に薬を使った患者における効果」(ATT)が関心対象となります。

④ 感度分析の実施

観測できない交絡(Unmeasured Confounding)が残っている可能性は常にあります。Rosenbaum感度分析などで結果の頑健性を確認することが、査読論文・規制当局への提出資料では求められます。

まとめ

本記事では、観察研究の交絡調整手法として広く使われる傾向スコアについて、理論から実装まで解説しました。

本記事のまとめ
  • 傾向スコアは「観測された共変量が等しい条件下での治療割り付け確率」であり、この値を利用してマッチング(PSM)または重み付け(IPW)を行うことで、観察データにRCTに近い条件を作り出すことができる
  • PSMはシンプルで解釈しやすい一方、IPWは全データを活用しATEの推定に優れている。実務では目的に応じて使い分けることが極めて重要
  • RではMatchIt・WeightIt・cobaltという強力なパッケージ群が整備されており、SASではPROC PSMATCHが標準的な実装手段
  • いずれのツールでも、バランス診断(Love Plot・SMD)まで含めた一連の解析フローを身につけることが、信頼性の高いRWE解析の第一歩

製薬業界でのリアルワールドエビデンスの重要性が増す中、傾向スコア解析を正しく実装・報告できるスキルは生物統計家としての大きな強みになります。ぜひ本記事のコードを手元で動かして、実務に役立てていただければと思います。

参考文献:
Rosenbaum PR, Rubin DB (1983). The central role of the propensity score in observational studies for causal effects. Biometrika.
Austin PC (2011). An introduction to propensity score methods for reducing the effects of confounding in observational studies. Multivariate Behavioral Research.

ABOUT ME
tomokichi
外資系製薬会社で生物統計家として働ている1児のパパ。生物統計家とは何か、どのようなスキルが必要か、何を行っているのかを共有していきたいと思っております!生物統計に関する最新情報を皆様にお届けすべく、日々奮闘中です。趣味は筋トレ、温泉巡り、家族と散歩。