t検定(分散分析)において正規性のチェックは必要か?

生データの正規性について機械的にチェックする必要はない、というお話です。


正規性について

Webサイトでよく見かけるのが、t検定や分散分析をする際はデータの正規性をチェックしなくてはいけませんという指摘です。結論から言うと、私の立場は:

(基本的に)チェックはいりません

ということになります。少なくとも、平均値の差を問題にしている限り、生データの分布に神経質になる必要はほとんどありません。

サイトのなかには、「正規性が保証されない場合はノンパラメトリック法のKruskal-Wallis検定(U検定なども同様)を使いなさい」と書いてあるものもあります。しかし、以前の記事で触れたように、これらの検定は「なにを比較しているか」が全く異なるのでおすすめできません。

中心極限定理

t検定や分散分析が分布に対して頑健なのは中心極限定理があるおかげです。

母集団がどのような分布をしているかにかかわらず、標本平均は標本サイズが十分に大きければ正規分布に従う

つまり、正規性が前提なのは「データそのもの」ではなく、「標本平均の分布」です。それぞれの群について母集団の分布はチェックすることは本質的ではありません。

シミュレーション1(標本平均の分布)

以下の図は、正規分布から大きく逸脱した分布である連続一様分布からランダムに得た標本の平均を示したものです(コード1)。

なお、一様分布はすべての事象が同じ確率で生じる平坦な分布を指します。例えば、サイコロの出目はどれも同じ確率$${1/6}$$で出現するため、一様分布(正確には離散一様分布)に従います。

わずか10個の標本の平均ですが、驚くほど正規分布に近くなります。

連続一様分布 U[0,1] から得られた標本平均の分布は正規分布(点線)に近づく(n = 10; 2000反復)

極端な例として標本数 $${n = 2}$$ のとき、t検定における第一種の過誤(本当は母平均に差がないのに「差がある」と結論する誤り)の程度はどう変わるのかを調べてみました(コード2)。

第一種の過誤を犯す確率。上が正規母集団、下が一様母集団からのサンプリングの結果。0.05が望ましい。

たしかに正規分布のほうが第一種の過誤を犯す確率($${\alpha = 0.05}$$)がコントロールされていますが、一様分布のほうも0.05から0.02未満しか上昇していません(つまり、少し甘めの検定とはなります)。いずれにせよ、今回の比較では、標本数が相当少なくても危険率に対してそれほど影響はなかったようです。

正規性が強調される理由?

なぜこれほど正規性が強調されるのでしょうか。このあたりは私の想像ですが、

  • 母集団が正規分布に従っているほうが正規分布への漸近が早い(たしかに正規分布への収束の速さは分布の歪度などに依存するそうです。この点はもう少しシミュレーションしてもよいかもしれません。)

  • 古典的な教科書の影響(母集団の正規分布を仮定)

  • その分野の伝統や慣習

  • 過剰な査読対応

などがありそうです。個人的には最後の2つが大きいのではないかと疑っています。

残差のチェック

ただし、処理の効果(主効果)を除いた後の残差の分布はチェックしておかないと問題かもしれません。

主効果の検定は、誤差分散を使って行われます。

一元配置の統計モデル(t検定も含む)は

$${y_{ij} = \mu + \alpha_i + \epsilon_{ij}}$$

と表されます。つまり、データを「全データの平均」、「群の平均(主効果)」、「誤差」に分けるモデルです。主効果の検定は$${\epsilon_{ij}}$$の分散(誤差分散)を統計量の分母として行います。そのため、

  • 誤差分散の著しい不均一性

  • 極端なゆがみや外れ値

がある場合には誤差分散が肥大し、結果が変わることもありえます。

シミュレーション2(歪んだ分布の影響)

標準正規分布とガンマ関数(shape = 0.3, scale = 1)を生成しました(コード3)。ガンマの平均はゼロに調整し。ガンマ分布は歪んでいます。

この場合、どちらの群も全く同じ平均値を持つので主効果$${\alpha_i}$$はゼロとなり、残差のみを評価することになります。

これを使ってt検定を行いました(結果は省略)。Q-Q プロットで残差の正規性を見てみると、直線から外れていることがわかります。(残差が正規分布の場合は直線状になります)

ただし、このいびつさも検定の結果にはそれほど大きな影響は与えないようです。以下のシミュレーションは、正規分布どうしの2群(図左)、または正規分布とガンマ分布の2群(図右)の間でt検定したP値の分布です(10,000反復、分散は1に統一、コード4)。

分布が違ってもとりたてて大きなP値の崩れは見られません(理論的に、検定が適切であれば帰無仮説のもとでP値は均一な一様分布となります)。

第一種の過誤を犯す確率は、前者が0.049, 後者が0.058でした。たしかに後者はわずかに上昇していますが、その差はわずかであり、致命的なレベルとは言えません。

結論

  • 生データの正規性チェックは本質ではない。(標本平均の分布は正規分布に漸近するから)

  • ただし、モデルを当てはめた後の残差の状態は確認したほうがよい。

  • 残差が正規性から多少崩れても、第一種の過誤を犯す確率はそれほど変わらない。

コード

コード1

一様分布からランダムに得た標本の平均は正規分布に従います

nrep <- 2000   # シミュレーション回数
n <- 10        # 標本数
x.bar <- numeric(nrep)

x <- runif(10000)   # 母集団(U(0,1))

for (i in 1:nrep){
  s <- sample(x, n, replace = TRUE)
  x.bar[i] <- mean(s)
}

mu <- 0.5              # U(0,1)の標本平均)
sd <- sqrt(1/(12*n))   # Var(U)=1/12 → Var(mean)=(1/12)/n

# ヒストグラム
hist(x.bar, prob = TRUE, breaks = 30,
     main = paste0("Sample mean of U(0,1), n=", n, ", nrep=", nrep),
     xlab = "x̄")
lines(density(x.bar), lwd = 2)

curve(dnorm(x, mean = mu, sd = sd), add = TRUE, lwd = 2, lty = 2) # 正規分布の密度関数

legend("topright",
       legend = c("Histogram (density)", "Kernel density", "Normal approx"),
       lty = c(NA, 1, 2), lwd = c(NA, 2, 2),
       pch = c(15, NA, NA), pt.cex = c(1.2, NA, NA), bty = "n")

コード2

標本数nが変わると、第一種の過誤はどうなるか? → n = 2でも0.01程度しかずれない。

# 第1種の過誤の比較
# 母集団が正規分布のときと一様分布のとき
# 2026-03-06

nrep <- 10000
n <- 2           # 標本数

err_norm  <- logical(nrep)
err_unif  <- logical(nrep)

for(i in 1:nrep){
	
	# 正規母集団(帰無:平均差0)
	x1 <- rnorm(n, 0, 1)
	x2 <- rnorm(n, 0, 1)
	p1 <- t.test(x1, x2, var.equal = TRUE)$p.value
	err_norm[i] <- (p1 < .05)
	
	# 一様母集団(帰無:平均差0)
	y1 <- runif(n, -sqrt(3), sqrt(3))    # 分散を正規分布にそろえるため
	y2 <- runif(n, -sqrt(3), sqrt(3))
	p2 <- t.test(y1, y2, var.equal = TRUE)$p.value
	err_unif[i] <- (p2 < .05)
}

cat("Type I error (Normal) :", mean(err_norm), "\n")
cat("Type I error (Uniform):", mean(err_unif), "\n")

コード3

正規分布とガンマ分布の誤差分布

n <- 50    # 各群の標本数

group <- as.factor(rep(c("A", "B"), each = n))

y <- c(
  rnorm(n, 0, 1),               # 群A:正規分布
  rgamma(n, shape = 0.3, scale = 1) - 0.3   # 群B:かなり右に歪む
)

dat <- data.frame(group, y)

a <- aov(y ~ group, data = dat)   # ANOVA (t-testと同等)
summary(a)


# ヒストグラム

xlim <- range(dat$y)

par(mfrow = c(2, 1))

hist(dat$y[dat$group == "A"],
     main = "Group A",
     xlab = "y",
     xlim = xlim)

hist(dat$y[dat$group == "B"],
     main = "Group B",
     xlab = "y",
     xlim = xlim)

# QQ plot

par(mfrow=c(1,1))
plot(a, which = 2)

コード4

第1種の過誤

nrep <- 10000
n <- 50   # 標本数
k <- 0.3 # ガンマ分布の shape(小さいほど歪みが強い)

p_norm  <- numeric(nrep)
p_gamma <- numeric(nrep)

for(i in 1:nrep){
  
  x1 <- rnorm(n, 0, 1)     # 正規母集団(平均0, 分散1)
  x2 <- rnorm(n, 0, 1)
  p_norm[i] <- t.test(x1, x2, var.equal = TRUE)$p.value   # 等分散のt-test(ANOVAと同等)
   
  # ガンマ母集団(平均0, 分散1)
  z <- rgamma(n, shape = k, scale = 1/sqrt(k)) - sqrt(k)  # 分散を1にそろえた
  p_gamma[i] <- t.test(x1, z, var.equal = TRUE)$p.value
}

err_nn <- mean(p_norm < 0.05)
err_ng <- mean(p_gamma < 0.05)

cat("Type I error (Normal) :", err_nn, "\n")
cat("Type I error (Gamma)  :", err_ng, "\n")

# ヒストグラム
par(mfrow = c(1, 2))
hist(p_norm,  breaks = 30, main = "Normal", xlab = "p-value")
hist(p_gamma, breaks = 30, main = "Gamma",  xlab = "p-value")

Last updated: 2026-05-01

いいなと思ったら応援しよう!