RでA/Bテスト:平均値の比較

Rで A/Bテスト:平均値の比較 を試みます。

A/Bテストのシナリオは以下の通りです。

背景

あなたは若者向けファッションECサイトのマーケティング担当者です。顧客一人当たりの購入単価(Average Order Value, AOV)を向上させる施策を検討しています。より高品質な商品を訴求するキャッチコピーに変更することで、ユーザーが少し高価な商品を選ぶようになり、結果として平均購入単価が上昇するのではないかという仮説を立てました。

テストの目的

新しいキャッチコピーが、既存のコピーよりも平均購入単価を向上させるかどうかを統計的に検証します。

テスト設計

  1. Aグループ(コントロール群): 既存のキャッチコピーを表示するユーザーグループ。
    1. キャッチコピー: 「豊富な品揃え、あなたにぴったりの一着を」
    2. 過去のデータから、このグループの平均購入単価は 5,000円、標準偏差は 1,500円であると分かっています。
  2. Bグループ(テスト群): 新しいキャッチコピーを表示するユーザーグループ。
    1. キャッチコピー: 「長く愛せる、ワンランク上のこだわりアイテム」
    2. この変更により、平均購入単価が 5,500円に向上すると期待しています(+500円の改善)。標準偏差は変わらず1,500円と仮定します。

統計的仮説

  1. 帰無仮説 (H₀): 新旧キャッチコピーでの平均購入単価に差はない (μₐ = μₑ)。
  2. 対立仮説 (H₁): 新しいキャッチコピーBの平均購入単価は、既存のコピーAよりも高い (μₐ < μₑ)。

続いて A/Bテストに入ります。

ステップ1: 事前設計(サンプルサイズの計算)

# 期待する効果(平均単価の差)を検出するために、どれくらいのサンプル(購入者)が
# 必要か計算します。

# パラメータ設定
power <- 0.80 # 検出力
sig_level <- 0.05 # 有意水準
mu_A <- 5000 # Aグループのベースライン平均購入単価
mu_B <- 5500 # Bグループの期待する平均購入単価
delta <- mu_B - mu_A # 期待する差
sd <- 1500 # 両グループの標準偏差(共通と仮定)

# サンプルサイズの計算 (2標本t検定)
# H1: μ_A < μ_B を検証したいため、alternative = "one.sided"
power_test_result <- power.t.test(
  delta = delta,
  sd = sd,
  power = power,
  sig.level = sig_level,
  type = "two.sample",
  alternative = "one.sided"
)

# 計算結果の表示
print(power_test_result)

# 各グループに必要なサンプルサイズ(購入者数)を抽出
sample_size_per_group <- ceiling(power_test_result$n)
cat(paste("\n各グループに必要なサンプルサイズ(購入者数):", sample_size_per_group, "人\n"))
cat("注意: これはサイト訪問者数ではなく、実際に購入したユーザーの数です。\n")

     Two-sample t test power calculation 

              n = 111.9686
          delta = 500
             sd = 1500
      sig.level = 0.05
          power = 0.8
    alternative = one.sided

NOTE: n is number in *each* group


各グループに必要なサンプルサイズ(購入者数): 112 人
注意: これはサイト訪問者数ではなく、実際に購入したユーザーの数です。

ステップ2: シミュレーションデータの生成

# 上記で計算したサンプルサイズに基づき、架空の購入金額データを生成します。
# データは正規分布に従うと仮定します。

seed <- 20250610
set.seed(seed)

# シミュレーションのパラメータ
n_A <- sample_size_per_group # Aグループの購入者数
n_B <- sample_size_per_group # Bグループの購入者数

# 「真の」パラメータ (シナリオ通りに設定)
true_mean_A <- 5000
true_mean_B <- 5500
true_sd <- 1500

# 正規分布に従う乱数を生成して、各購入者の購入金額をシミュレート
# rnorm(n, mean, sd)
data_A <- rnorm(n_A, mean = true_mean_A, sd = true_sd)
data_B <- rnorm(n_B, mean = true_mean_B, sd = true_sd)

# 生成されたデータの一部を確認(購入金額なので小数点以下は切り捨てて表示)
cat("\nAグループの購入単価データ(最初の10件):", floor(data_A[1:10]), "\n")
cat("Bグループの購入単価データ(最初の10件):", floor(data_B[1:10]), "\n")

Aグループの購入単価データ(最初の10件): 1931 4823 5304 3883 6559 3586 6327 5686 3907 3986 
Bグループの購入単価データ(最初の10件): 5097 5111 5010 5525 4349 5555 4490 4380 7529 9221 

ステップ3: 集計と統計的検定

# 生成したデータを使って、実際に平均単価を計算し、統計的な差があるかt検定で検証します。

# 各グループの観測された平均値と標準偏差を計算
observed_mean_A <- mean(data_A)
observed_mean_B <- mean(data_B)
observed_sd_A <- sd(data_A)
observed_sd_B <- sd(data_B)

cat("\n--- テスト結果の集計 ---\n")
cat(paste("Aグループ: 購入者数", n_A, "人, 平均単価", round(observed_mean_A), "円, 標準偏差", round(observed_sd_A), "円\n"))
cat(paste("Bグループ: 購入者数", n_B, "人, 平均単価", round(observed_mean_B), "円, 標準偏差", round(observed_sd_B), "円\n"))

# 2標本t検定 (Welch's t-test)
# Bグループの平均がAグループより大きいか検証したいので alternative = "greater" を指定
# t.test(y, x) の形式で、y > x を検証します。
test_result <- t.test(
  data_B,
  data_A,
  alternative = "greater",
  conf.level = 0.95
)

# 検定結果の表示
cat("\n--- 統計的検定の結果 (Welch's t-test) ---\n")
print(test_result)

--- テスト結果の集計 ---
Aグループ: 購入者数 112 人, 平均単価 5056 円, 標準偏差 1497 円
Bグループ: 購入者数 112 人, 平均単価 5431 円, 標準偏差 1558 円

--- 統計的検定の結果 (Welch's t-test) ---

    Welch Two Sample t-test

data:  data_B and data_A
t = 1.8346, df = 221.64, p-value = 0.03395
alternative hypothesis: true difference in means is greater than 0
95 percent confidence interval:
 37.32806      Inf
sample estimates:
mean of x mean of y 
 5430.734  5056.207 

ステップ4: 結果の解釈と結論

# p値を取得
p_value <- test_result$p.value

cat("\n--- 結論 ---\n")
cat(paste("p値:", round(p_value, 4), "\n"))
cat(paste("有意水準:", sig_level, "\n\n"))

if (p_value < sig_level) {
  cat("結論: p値が有意水準 (0.05) よりも小さいため、帰無仮説を棄却します。\n")
  cat("新しいキャッチコピーBは、既存のコピーAに比べて平均購入単価を統計的に有意に向上させると言えます。\n")
  cat("ビジネス判断: 新しいキャッチコピーを採用することを推奨します。\n")
} else {
  cat("結論: p値が有意水準 (0.05) よりも大きいため、帰無仮説を棄却できません。\n")
  cat("新しいキャッチコピーBが平均購入単価を向上させるという統計的に有意な証拠は得られませんでした。\n")
  cat("ビジネス判断: 現状では、新しいキャッチコピーへの変更は見送るべきです。\n")
}

--- 結論 ---
p値: 0.034 
有意水準: 0.05 

結論: p値が有意水準 (0.05) よりも小さいため、帰無仮説を棄却します。
新しいキャッチコピーBは、既存のコピーAに比べて平均購入単価を統計的に有意に向上させると言えます。
ビジネス判断: 新しいキャッチコピーを採用することを推奨します。

以上です。