Понимание анализа мощности статистических тестов гипотез можно улучшить, выполнив некоторые и внимательно изучив результаты.
αα
Второй критерий требует, чтобы мы указали, каким образом и насколько ноль не соответствует действительности. В случае с учебниками это легко, потому что альтернативы ограничены по объему и четко определены. С тестами распределения, такими как Shapiro-Wilk, альтернатива гораздо более расплывчата: они «ненормальные». Таким образом, при выборе среди тестов распределения аналитик, вероятно, должен будет провести свое собственное одноразовое исследование мощности, чтобы оценить, насколько хорошо тесты работают в отношении более конкретных альтернативных гипотез, которые имеют отношение к рассматриваемой проблеме.
ν≥1ν
αR
rdist
имя функции для получения случайной выборки из некоторого распределения
n
Размер образцов на заказ rdist
n.iter
количество таких образцов для получения
...
rdist
ν
Остальные параметры управляют отображением результатов; они включены в основном для удобства создания цифр в этом ответе.
sim <- function(rdist, n, n.iter, prefix="",
breaks=seq(0, 1, length.out=20), alpha=0.05,
plot=TRUE, ...) {
# The simulated P-values.
# NB: The optional arguments "..." are passed to `rdist` to specify
# its parameters (if any).
x <- apply(matrix(rdist(n*n.iter, ...), ncol=n.iter), 2,
function(y) shapiro.test(y)$p.value)
# The histogram of P-values, if requested.
if (plot) {
power <- mean(x <= alpha)
round.n <- 1+ceiling(log(1 + n.iter * power * (1-power), base=10) / 2)
hist(x[x <= max(breaks)], xlab=paste("P value (n=", n, ")", sep=""),
breaks=breaks,
main=paste(prefix, "(power=", format(power, digits=round.n), ")", sep=""))
# Specially color the "significant" part of the histogram
hist(x[x <= alpha], breaks=breaks, col="#e0404080", add=TRUE)
}
# Return the array of P-values for any further processing.
return(x)
}
5100.n520.
n.iter <- 10^5 # Number of samples to generate
n.spec <- c(5, 10, 20) # Sample sizes to study
par(mfrow=c(1,length(n.spec))) # Organize subsequent plots into a tableau
system.time(
invisible(sapply(n.spec, function(n) sim(rnorm, n, n.iter, prefix="DF = Inf ")))
)
После указания параметров этот код также занимает всего одну строку. Это дает следующий вывод:
01α=0.05,.04810.0499
10.2
νν=100ν=11001000), что не занимает много времени. Теперь в коде требуется двойной цикл (а в более сложных ситуациях нам часто нужны тройные или четырехкратные циклы, чтобы учесть все аспекты, которые нам нужно варьировать): один для изучения того, как мощность изменяется в зависимости от размера выборки, и другой для изучения того, как она меняется в зависимости от степени свободы. Тем не менее, еще раз, все делается в одной строке кода (третья и последняя):
df.spec <- c(64, 16, 4, 2, 1)
par(mfrow=c(length(n.spec), length(df.spec)))
for (n in n.spec)
for (df in df.spec)
tmp <- sim(rt, n, n.iter, prefix=paste("DF =", df, ""), df=df)
Небольшое изучение этой таблицы дает хорошее представление о силе. Я хотел бы обратить внимание на его наиболее важные и полезные аспекты:
Забавно, что так много можно почерпнуть из того, что фактически составляет три строки кода: одну для имитации выборок iid из указанного дистрибутива, одну, чтобы применить это к массиву нулевых распределений, и третью, чтобы применить его к массив альтернативных распределений. Это три шага, которые входят в любой анализ мощности: остальное - это просто суммирование и интерпретация результатов.