404 Not Found

404 Not Found


nginx

Rによる仮説検定:t.test、prop.test、chisq.testの完全チュートリアル

前回のレッスンでは、確率分布について――その理論――を学びました。今回のレッスンでは、仮説検定――標本を用いて母集団について結論を導き出す方法――について詳しく見ていきます。これが統計学の核心です。「売上が20%増加」と謳う広告は本当なのか、それとも単なる誇大宣伝なのか? 2つのデータセットの差は偶然によるものなのか、それとも必然的なものなのか? Rを使えば、たった4行のコードでこの疑問に答えることができます。

このレッスンを修了すると、R を使用して、t 検定(平均値の比較)、割合の検定(合格率の比較)、カイ二乗検定(独立性の検定)、および分散分析(複数の群の比較)を行うことができるようになります。

1. 学習内容



2. A/Bテストに関する話

(1) 課題:広告は効果があるのか?

ボブはA/Bテストを実施しました:

マネージャーは「この2%の差は本当なのか、それとも単なる偶然なのか?」と尋ねた。

(2) Rを用いた解決策

R
# Two-Proportion Test
prop.test(c(80, 100), c(1000, 1000))
# 2-sample test for equality of proportions
# X-squared = 2.46, df = 1, p-value = 0.117
# Conclusion: p > 0.05, Differences Not significant (It might be a coincidence.)

1行のコード → p値 → 決定



3. 仮説検定の5段階のプロセス

(1) 5つのステップ

100%
graph TB
    A[1. Propose a hypothesis] --> B[2. Calculate the statistic]
    B --> C[3. Calculation p-value]
    C --> D[4. Decision-making]
    D --> E[5. Report]
    
    A --> A1["H0 Null Hypothesis<br/>H1 Alternative Hypothesis"]
    B --> B1["t/z/Chi-square/F"]
    C --> C1["P Data Visualization H0 An equally extreme probability"]
    D --> D1["p < 0.05 → Reject H0"]
    E --> E1["Report p-value + Effect size + Confidence Interval"]
    
    style A fill:#fff3cd
    style B fill:#cce5ff
    style C fill:#d4edda
    style D fill:#f8d7da
    style E fill:#e1d4ff

(2) 主要な概念

概念 意味
H0(帰無仮説) デフォルトの仮定:2つのグループは区別がつかない(差は偶然によるもの)
H1(対立仮説) 私たちが本当に証明したいこと:2つのグループには違いがあるということ
統計量 「差がどれほど大きいか」を測る数値(t、z、χ²、F)
p値 H0が真であると仮定した場合に、現在の結果またはそれよりも極端な結果が観測される確率
α(有意水準) p値の閾値。一般に0.05
H0を棄却 p < 0.05、差は統計的に有意
H0を棄却しない p ≥ 0.05;差があるとは結論づけられない(≠ 差がない)
⚠️ 重要なポイント:「H0を棄却しないこと ≠ H0を受け入れること」。p値が0.05より大きいということは、単に「証拠が不十分」であることを示すだけであり、「2つの群が真に等しい」ことを意味するわけではない。



4. t.test(): 平均値の比較

(1) t検定の3つの種類

タイプ シナリオ R構文
単一サンプル 1群対既知値 t.test(x, mu = 0)
2つの独立した標本 2つの独立した標本 t.test(x, y)
対応のある標本 同一被験者を対象とした事前・事後テスト t.test(x, y, paired = TRUE)

(2) 1標本t検定

R
# Example: Product Weight Standard 100g, test 10 products
weights <- c(98, 102, 99, 101, 100, 97, 103, 99, 101, 100)

t.test(weights, mu = 100)
# One Sample t-test
# t = 0, df = 9, p-value = 1
# 95% CI: [98.7, 101.3]
# mean of x = 100
# Conclusion: p = 1, Don't reject H0, the mean is equal to 100g

(3) 2標本独立t検定

R
# Example: A/B Testing the conversion times for two groups
group_a <- c(12, 15, 14, 13, 16, 14, 15, 13, 14, 15)
group_b <- c(10, 11, 12, 13, 11, 10, 12, 11, 13, 12)

t.test(group_a, group_b)
# Welch Two Sample t-test
# t = 5.32, df = 14.6, p-value = 0.0001
# 95% CI: [1.36, 3.24]
# Conclusion: p < 0.05, Reject H0, Group A was significantly slower than Group B

(4) 対応のあるt検定

R
# Example: Before medication vs after medication in the same group of patients
before <- c(180, 175, 190, 170, 185)
after <- c(165, 160, 175, 160, 170)

t.test(before, after, paired = TRUE)
# Paired t-test
# t = 8.5, df = 4, p-value = 0.001
# Conclusion: p < 0.05, Significant decline (The medication is effective)

(5) 主要なパラメータ

パラメータ 意味 デフォルト
mu 単一サンプルの既知値 0
paired ペアリングされていますか? FALSE
var.equal 同分散性の仮定 FALSE (ウェルチ)
alternative 別の方向 「two.sided」
conf.level 信頼水準 0.95
R
# One-sided test (right-tailed)
t.test(x, mu = 100, alternative = "greater")

# One-sided test (left-tailed)
t.test(x, mu = 100, alternative = "less")


5. prop.test(): 比例性の検定

(1) 1つの比率の検定

R
# Example: Historical Product Pass Rate 95%, now 92 out of 100 are Qualified
prop.test(92, 100, p = 0.95)
# 1-sample proportions test
# X-squared = 1.27, df = 1, p-value = 0.26
# Conclusion: p > 0.05, Pass Rate No significant decrease

(2) 二比例検定(A/Bテストの中核)

R
# Example: Group A 1000 people, 80 conversions; Group B 1000 people, 100 conversions
prop.test(c(80, 100), c(1000, 1000))
# 2-sample test for equality of proportions
# X-squared = 2.46, df = 1, p-value = 0.117
# 95% CI: [-0.046, 0.006]
# Conclusion: p > 0.05, The difference is not significant (It might be a coincidence.)

(3) prop.test 対 chisq.test



6. chisq.test(): カイ二乗検定

(1) 2つの主な用途

目的 シナリオ 計算式
適合度 観測値と予測値の比較 chisq.test(observed)
独立性 2つのカテゴリ変数には相関があるか? chisq.test(table(x, y))

(2) 適合度検定

R
# Example: Dice Fairness Test (toss 60 times)
observed <- c(8, 12, 10, 11, 9, 10)  # Number of times each face appears
expected <- rep(10, 6)  # Expect uniformity

chisq.test(observed, p = expected / sum(expected))
# Chi-squared test
# X-squared = 1.2, df = 5, p-value = 0.945
# Conclusion: p > 0.05, Dice is fair (Do not reject the uniformity assumption)

(3) 独立性の検定

R
# Example: Gender vs Purchasing Behavior
gender <- c("M", "M", "F", "F", "M", "F", "M", "F")
purchase <- c("Buy", "Not buying", "Buy", "Buy", "Not buying", "Buy", "Buy", "Not buying")

tab <- table(gender, purchase)
print(tab)
#      Not buying Buy
#   M    1  3
#   F    1  3

chisq.test(tab)
# X-squared = 0, df = 1, p-value = 1
# Conclusion: p > 0.05, Gender and Purchasing Independent

# Note: Any 2x2 Table with Expected Frequencies < 5, use Fisher's Exact Test
fisher.test(tab)

(4) 期待される頻度に関する要件

R
# Chi-Square Test Requirements: Expected Frequency for Each Cell >= 5
# Use Fisher's Exact Test when not satisfied
result <- chisq.test(tab)
result$expected  # View Expected Frequency


7. aov() 分散分析(ANOVA)

(1) 適用されるシナリオ

3つ以上のグループ間の平均値の比較(t検定は2つのグループに限定されます)。

(2) 実践的な応用

R
# Example: Effect of 3 Fertilizer Types on Crop Yields
fertilizer <- c(rep("A", 10), rep("B", 10), rep("C", 10))
yield <- c(20, 22, 21, 19, 23, 20, 21, 22, 19, 20,   # A
           25, 26, 24, 27, 25, 26, 27, 25, 24, 26,  # B
           18, 19, 17, 18, 19, 20, 19, 18, 19, 20)  # C

df <- data.frame(fertilizer, yield)

# Single-factor ANOVA
model <- aov(yield ~ fertilizer, data = df)
summary(model)
#              Df Sum Sq Mean Sq F value Pr(>F)    
# fertilizer     2  220.0   110.0   91.7  <2e-16 ***
# Residuals     27   32.4     1.2
# Conclusion: p < 0.05, 3 Fertilizer Types Significant difference

# Post-hoc comparison: Tukey HSD
TukeyHSD(model)
#   diff        lwr        upr     p adj
# B-A   5.0  3.91       6.09    0.000
# C-A  -1.5 -2.59      -0.41    0.005
# C-B  -6.5 -7.59      -5.41    0.000


8. wilcox.test() 非パラメトリック検定

(1) いつ使うべきか?

(2) 実践的な応用

R
# Non-parametric paired test (Wilcoxon signed-rank)
before <- c(180, 175, 190, 170, 185)
after <- c(165, 160, 175, 160, 170)

wilcox.test(before, after, paired = TRUE)
# V = 15, p-value = 0.0625
# Conclusion: p > 0.05 (Not significant), however, the sample size is small

# Independent non-parametric (Mann-Whitney U)
group_a <- c(12, 15, 14, 13, 16)
group_b <- c(10, 11, 12, 13, 11)
wilcox.test(group_a, group_b)
# W = 25, p-value = 0.028
# Conclusion: p < 0.05, the difference is significant


9. p値の解釈とよくある落とし穴

(1) p値の正しい理解

解釈 説明
✅ 正解 H0が真である場合に、現在の結果またはそれ以上の極端な結果が観測される確率
❌ エラー 「H0が真である確率」
❌ エラー 「この差は偶然によるものである」
❌ エラー 「差の大きさ」

(2) よくある5つの落とし穴

100%
graph TB
    A[p Value Trap] --> B[p-hacking<br/>After trying it several times p<0.05]
    A --> C[Large sample size p Bi Xiao<br/>Depends on the effect size]
    A --> D[p<0.05 Does not mean it is useful<br/>Check effect size]
    A --> E[Don't refuse ≠ Accept H0]
    A --> F[Significance ≠ Practical Significance]
    
    style A fill:#fff3cd
    style B fill:#f8d7da
    style C fill:#cce5ff
    style D fill:#d4edda
    style E fill:#e1d4ff
    style F fill:#ffe1d4

(3) 効果量

p値だけを見るだけでは不十分です。効果量、つまりその差がどれほど大きいかを確認する必要があります:

検定 効果量
t検定 コーエンのd = (m1 - m2) / s_pooled
ANOVA η²(エータ二乗)
カイ二乗 クレイマーのV
相関 r(相関係数)
R
# Cohen's d Calculation
cohens_d <- function(x, y) {
  n1 <- length(x)
  n2 <- length(y)
  s_pooled <- sqrt(((n1-1)*var(x) + (n2-1)*var(y)) / (n1 + n2 - 2))
  (mean(x) - mean(y)) / s_pooled
}
コーエンのd 意味
0.2 効果が小さい
0.5 中程度の効果
0.8 大きな効果


10. 完全な例:A/Bテスト+多群比較

以下は、このレッスンで取り上げた仮説検定の概念をすべて結びつけた完全なワークフローの例です。

▶ サンプル:マーケティングキャンペーンの成果に関する包括的な評価

R
# ============================================
# Comprehensive Evaluation of Marketing Campaign Performance
# Features: t-test / Proportionality Test / ANOVA combined
# ============================================

set.seed(42)

# 1. A/B Test Conversion Time
group_a <- rnorm(50, mean = 15, sd = 3)  # Original Page
group_b <- rnorm(50, mean = 13, sd = 3)  # New Page

cat("=== A/B Test: Conversion Time ===\n")
cat("A Group Mean:", round(mean(group_a), 2), "s\n")
cat("B Group Mean:", round(mean(group_b), 2), "s\n")
cat("Differences:", round(mean(group_a) - mean(group_b), 2), "s\n\n")

# 2. t-test
t_result <- t.test(group_a, group_b)
print(t_result)
cat("\n")

# 3. Cohen's d
n1 <- length(group_a)
n2 <- length(group_b)
s_pooled <- sqrt(((n1-1)*var(group_a) + (n2-1)*var(group_b)) / (n1+n2-2))
cohens_d <- (mean(group_a) - mean(group_b)) / s_pooled
cat("Cohen's d (Effect size):", round(cohens_d, 3), "\n")
cat("Effect Size:", ifelse(abs(cohens_d) > 0.8, "L",
                  ifelse(abs(cohens_d) > 0.5, "Mid", "S")), "\n\n")

# 4. A/B Testing Conversion Rates
convert_a <- 80
convert_b <- 100
visitors_a <- 1000
visitors_b <- 1000

cat("=== A/B Test: Conversion Rate ===\n")
cat("A Group Conversion Rate:", round(convert_a / visitors_a * 100, 2), "%\n")
cat("B Group Conversion Rate:", round(convert_b / visitors_b * 100, 2), "%\n\n")

# 5. Proportionality Test
prop_result <- prop.test(c(convert_a, convert_b),
                          c(visitors_a, visitors_b))
print(prop_result)
cat("\n")

# 6. Comparison of 3 Marketing Strategies (ANOVA)
strategy <- c(rep("Email", 20), rep("Text Message", 20), rep("Push", 20))
sales <- c(rnorm(20, 100, 15),
           rnorm(20, 110, 15),
           rnorm(20, 105, 15))
df_strategy <- data.frame(strategy, sales)

cat("=== Comparison of 3 Sales Strategies (ANOVA) ===\n")
model <- aov(sales ~ strategy, data = df_strategy)
summary(model)
cat("\nPost-hoc comparison:\n")
print(TukeyHSD(model))

# 7. Gender and Purchasing Behavior (Chi-square)
gender <- sample(c("M", "F"), 200, replace = TRUE)
purchase <- sample(c("Buy", "Not buying"), 200, replace = TRUE,
                   prob = c(0.3, 0.7))
tab <- table(gender, purchase)
cat("\n=== Gender vs Purchase Chi-Square Test ===\n")
print(tab)
cat("\n")
chisq_result <- chisq.test(tab)
print(chisq_result)

# 8. Comprehensive Report
cat("\n=== Summary of Decisions ===\n")
cat("1. Conversion Time: Group A is", round(cohens_d, 2), "standard deviations slower than Group B",
    ifelse(t_result$p.value < 0.05, " (Significant)", " (Not significant)"), "\n", sep = "")
cat("2. Conversion Rate: A vs B Difference",
    ifelse(prop_result$p.value < 0.05, "Significant", "Not significant"), "\n")
cat("3. 3 Strategies:",
    ifelse(summary(model)[[1]]$`Pr(>F)`[1] < 0.05, "Significant difference", "No difference"), "\n")
▶ 試してみよう

期待される出力(抜粋):

R
=== A/B Test: Conversion Time ===
A Group Mean: 14.87 s
B Group Mean: 12.94 s
Differences: 1.93 s

Welch Two Sample t-test
t = 3.18, df = 96.3, p-value = 0.002
Cohen's d (Effect size): 0.643
Effect Size: Mid

=== Summary of Decisions ===
1. Conversion Time: Group A is 0.64 standard deviations slower than Group B (Significant)
2. Conversion Rate: A vs B The difference is not significant
3. 3 Strategies: Significant difference

❓ よくある質問

Q カイ二乗検定の要件は何ですか?
A 各セルにおける期待頻度が 5 以上でなければなりません

📖 まとめ


📝 練習問題

  1. 基本問題:30人の学生の得点(平均80、標準偏差10)をシミュレーションし、75点から有意な乖離があるかどうかを判断するために1標本t検定を行う。次に、別の30人の学生の得点(平均78)をシミュレーションし、2標本t検定を行う。p値を記録せよ。

  2. 基本問題:A/Bテストをシミュレートする(グループA:1,000人、コンバージョン数50件;グループB:1,000人、コンバージョン数80件)。prop.testを用いて、この差が統計的に有意であるかどうかを検定する。コーエンのdによる効果量を算出する。

  3. 基本演習:3×3の分割表(3つの広告チャネル × クリックの有無)を作成し、chisq.test を使用して、チャネルとクリックが独立しているかどうかを検定してください。result$expected を確認してください。すべての期待頻度は 5 以上ですか?

  4. 応用演習:3つの指導法(各グループ20名)のテスト得点をシミュレートし、aov を使用して分散分析(ANOVA)を行い、その後 TukeyHSD を使用して、どの2つのグループの間に最も大きな差が見られるかを特定してください。

  5. 課題:完全なA/Bテストを実施してください。2つのページ(各1,000ユーザー)について、コンバージョン時間とコンバージョン率をシミュレートします。t検定、prop.test、およびコーエンのdを用いて包括的な評価を行い、意思決定レポート(p値、効果量、およびビジネス上の提言を含む)を作成してください。スクリーンショットを撮影し、保存してください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%