Главная страница

А. Б. Шипунов, Е. М. Балдин, П. А. Волкова, А. И. Коробейников, С. А. Назарова


Скачать 3.04 Mb.
НазваниеА. Б. Шипунов, Е. М. Балдин, П. А. Волкова, А. И. Коробейников, С. А. Назарова
Анкорrbook
Дата29.09.2022
Размер3.04 Mb.
Формат файлаpdf
Имя файлаrbook.pdf
ТипДокументы
#705644
страница9 из 19
1   ...   5   6   7   8   9   10   11   12   ...   19
3.468127 61.103302

Одномерные статистические тесты
85
sample estimates:
mean of x
32.28571
Это вариант теста Стьюдента для одномерных данных. Статисти- ческие тесты (в том числе и этот) пытаются высчитать так называе- мую тестовую статистику, в данном случае статистику Стьюдента (t- статистику). Затем на основании этой статистики рассчитывается «p- величина» (p-value), отражающая вероятность ошибки первого рода.
А ошибкой первого рода (ее еще называют «ложной тревогой»), в свою очередь, называется ситуация, когда мы принимаем так называемую альтернативную гипотезу, в то время как на самом деле верна нулевая
(гипотеза «по умолчанию»). Наконец, вычисленная p-величина исполь- зуется для сравнения с заранее заданным порогом (уровнем) значимо- сти
. Если p-величина ниже порога, нулевая гипотеза отвергается, если выше — принимается. Подробнее о статистических гипотезах можно прочесть в следующей главе.
В нашем случае нулевая гипотеза состоит в том, что истинное сред- нее (то есть среднее генеральной совокупности) равно вычисленному нами среднему (то есть 32.28571).
Перейдем к анализу вывода функции. Статистика Стьюдента при шести степенях свободы (df=6, поскольку у нас всего 7 значений) дает единичное p-значение, то есть 100%. Какой бы распространенный по- рог мы не приняли (0.1%, 1% или 5%), это значение все равно больше.
Следовательно, мы принимаем нулевую гипотезу. Поскольку альтерна- тивная гипотеза в нашем случае — это то, что «настоящее» среднее
(среднее исходной выборки) не равно вычисленному среднему, то по- лучается, что «на самом деле» эти цифры статистически не отличают- ся. Кроме всего этого, функция выдает еще и доверительный интервал
(confidence interval), в котором, по ее «мнению», может находиться на- стоящее среднее. Здесь он очень широк — от трех с половиной тысяч до 61 тысячи рублей.
Непараметрический (то есть не связанный предположениями о рас- пределении) аналог этого теста тоже существует. Это так называемый ранговый тест Уилкоксона:
> wilcox.test(salary2, mu=median(salary2), conf.int=TRUE)
Wilcoxon signed rank test with continuity correction data:
salary2
V = 221949, p-value = 0.8321
alternative hypothesis: true location is not equal to 21 95 percent confidence interval:
20.99999 21.00007

86
Великое в малом: одномерные данные sample estimates:
(pseudo)median
21.00004
Эта функция и выводит практически то же самое, что и t.test()
выше. Обратите, однако, внимание, что этот тест связан не со средним,
а с медианой. Вычисляется (если задать conf.int=TRUE) и доверитель- ный интервал. Здесь он значительно
0
уже, потому что медиана намного устойчивее среднего значения.
Понять, соответствует ли распределение данных нормальному (или хотя бы близко ли оно к нормальному), очень и очень важно. Напри- мер, все параметрические статистические методы основаны на предпо- ложении о том, что данные имеют нормальное распределение. Поэто- му в R реализовано несколько разных техник, отвечающих на вопрос о нормальности данных. Во-первых, это статистические тесты. Самый простой из них — тест Шапиро-Уилкса (попробуйте провести этот тест самостоятельно):
> shapiro.test(salary)
> shapiro.test(salary2)
Но что же он показывает? Здесь функция выводит гораздо мень- ше, чем в предыдущих случаях. Более того, даже встроенная справка не содержит объяснений того, какая здесь, например, альтернативная гипотеза. Разумеется, можно обратиться к литературе, благо справка дает ссылки на публикации. А можно просто поставить эксперимент:
> set.seed(1638)
> shapiro.test(rnorm(100))
Shapiro-Wilk normality test data:
rnorm(100)
W = 0.9934, p-value = 0.9094
rnorm()
генерирует столько случайных чисел, распределенных по нормальному закону, сколько указано в его аргументе. Это аналог функ- ции sample(). Раз мы получили высокое p-значение, то это свидетель- ствует о том, что альтернативная гипотеза в данном случае: «распре- деление не соответствует нормальному». Кроме того, чтобы результаты при вторичном воспроизведении были теми же, использована функция set.seed()
, регулирующая встроенный в R генератор случайных чисел так, чтобы числа в следующей команде были созданы по одному и тому же «закону».

Одномерные статистические тесты
87
Таким образом, распределение данных в salary и salary2 отлича- ется от нормального.
Другой популярный способ проверить, насколько распределение по- хоже на нормальное,— графический. Вот как это делается (рис. 14):
> qqnorm(salary2, main="")
> qqline(salary2, col=2)
−3
−2
−1 0
1 2
3 20 40 60 80 10 0
Рис. 14. Графическая проверка нормальности распределения
Для каждого элемента вычисляется, какое место он занимает в сор- тированных данных (так называемый «выборочный квантиль») и какое место он должен был бы занять, если распределение нормальное (тео- ретический квантиль). Прямая проводится через квартили. Если точки лежат на прямой, то распределение нормальное. В нашем случае мно- гие точки лежат достаточно далеко от красной прямой, а значит, не похожи на распределенные нормально.
Для проверки нормальности можно использовать и более универ- сальный тест Колмогорова—Смирнова, который сравнивает любые два

88
Великое в малом: одномерные данные распределения, поэтому для сравнения с нормальным распределением ему надо прямо указать «pnorm», то есть так называемую накопленную функцию нормального распределения (она встроена в R):
> ks.test(salary2, "pnorm")
One-sample Kolmogorov-Smirnov test data:
salary2
D = 1, p-value < 2.2e-16
alternative hypothesis: two-sided
Он выдает примерно то же, что и текст Шапиро-Уилкса.
4.4. Как создавать свои функции
Тест Шапиро-Уилкса всем хорош, но не векторизован, как и многие другие тесты в R, поэтому применить его сразу к нескольким колонкам таблицы данных не получится. Сделано это нарочно, для того чтобы подчеркнуть нежелательность множественных парных сравнений (об этом подробнее написано в главе про двумерные данные). Но в нашем случае парных сравнений нет, а сэкономить время хочется. Можно, ко- нечно, нажимая «стрелку вверх», аккуратно повторить тест для каж- дой колонки, но более правильный подход — создать пользовательскую функцию. Вот пример такой функции:
> normality <- function(data.f)
+ {
+ result <- data.frame(var=names(data.f), p.value=rep(0,
+ ncol(data.f)), normality=is.numeric(names(data.f)))
+ for (i in 1:ncol(data.f))
+
{
+
data.sh <- shapiro.test(data.f[, i])$p.value
+
result[i, 2] <- round(data.sh, 5)
+
result[i, 3] <- (data.sh > .05)
+
}
+ return(result)
+ }
Чтобы функция заработала, надо скопировать эти строчки в окно консоли или записать их в отдельный файл (желательно с расширени- ем *.r), а потом загрузить командой source(). После этого ее можно вызвать:

Как создавать свои функции
89
> normality(trees)
var p.value normality
1
Girth 0.08893
TRUE
2 Height 0.40342
TRUE
3 Volume 0.00358
FALSE
Функция не только запускает тест Шапиро-Уилкса несколько раз,
но еще и разборчиво оформляет результат выполнения. Разберем функ- цию чуть подробнее. В первой строчке указан ее аргумент — data.f.
Дальше, в окружении фигурных скобок, находится тело функции. На третьей строчке формируется пустая таблица данных такой размер- ности, какая потребуется нам в конце. Дальше начинается цикл: для каждой колонки выполняется тест, а потом (это важно!) из теста из- влекается p-значение. Процедура эта основана на знании структуры вывода теста — списка, где элемент p-value содержит p-значение. Про- верить это можно, заглянув в справку, а можно и экспериментально
(как? — см. ответ в конце главы). Все p-значения извлекаются, округ- ляются, сравниваются с пороговым уровнем значимости (в данном слу- чае 0.05) и записываются в таблицу. Затем таблица выдается «наружу».
Предложенная функция совершенно не оптимизирована. Ее легко мож- но сделать чуть короче и к тому же несколько «смышленее», скажем так:
> normality2 <- function(data.f, p=.05)
+ {
+ nn <- ncol(data.f)
+ result <- data.frame(var=names(data.f), p.value=numeric(nn),
+ normality=logical(nn))
+ for (i in 1:nn)
+
{
+
data.sh <- shapiro.test(data.f[, i])$p.value
+
result[i, 2:3] <- list(round(data.sh, 5), data.sh > p)
+
}
+ return(result)
+ }
> normality2(trees)
Результаты, разумеется, не отличаются. Зато видно, как можно до- бавить аргумент, причем сразу со значением по умолчанию. Теперь можно писать:
> normality2(trees, 0.1)

90
Великое в малом: одномерные данные var p.value normality
1
Girth 0.08893
FALSE
2 Height 0.40341
TRUE
3 Volume 0.00358
FALSE
То есть если вместо 5% взять десятипроцентный порог, то уже и для первой колонки можно отвергнуть нормальное распределение.
Уже не раз говорилось, что циклов в R следует избегать. Можно ли сделать это в нашем случае? Оказывается, да:
> lapply(trees, shapiro.test)
$Girth
Shapiro-Wilk normality test data:
X[[1L]]
W = 0.9412, p-value = 0.08893
$Height
Как видите, все еще проще! Если мы хотим улучшить зрительный эффект, можно сделать так:
> lapply(trees, function(.x) ifelse(shapiro.test(.x)$p.value >
+ .05, "NORMAL", "NOT NORMAL"))
$Girth
[1] "NORMAL"
$Height
[1] "NORMAL"
$Volume
[1] "NOT NORMAL"
Здесь применена так называемая анонимная функция, функция без названия, обычно употребляемая в качестве последнего аргумента ко- манд типа apply(). Кроме того, используется логическая конструкция ifelse()
И наконец, на этой основе можно сделать третью пользовательскую функцию (проверьте самостоятельно, как она работает):

Всегда ли точны проценты
91
> normality3 <- function(df, p=.05)
+ {
+ lapply(df, function(.x) ifelse(shapiro.test(.x)$p.value >
+ p, "NORMAL", "NOT NORMAL"))
+ }
> normality3(list(salary, salary2))
> normality3(log(trees+1))
Примеры тоже интересны. Во-первых, нашу третью функцию мож- но применять не только к таблицам данных, но и к «настоящим» спис- кам, с неравной длиной элементов. Во-вторых, простейшее логарифми- ческое преобразование сразу же изменило «нормальность» колонок.
4.5. Всегда ли точны проценты
Полезной характеристикой при исследовании данных является про- порция (доля). В статистике под пропорцией понимают отношение объ- ектов с исследуемой особенностью к общему числу наблюдений. По- скольку доля — это часть целого, то отношение части к целому нахо- дится в пределах от 0 до 1. Для удобства восприятия доли ее умножают на 100% и получают процент — число в пределах от 0% до 100%. Сле- дует внимательно относиться к вычислению долей и не забывать про исходные данные. В 1960-е годы в районном отделе по сельскому хозяй- ству было обнаружено, что падеж лошадей в одном сельском поселении составил 50%. Пришлось составить компетентную комиссию для про- верки причин такого ужасного явления. Прибыв на место, комиссия обнаружила, что в данном поселении было всего две лошади, в том числе и сдохшая недавно старая кляча, которая и послужила причиной формирования и выезда на место комиссии!
Рассмотрим проблему, которая часто встречается при проведении статистических исследований. Как узнать, отличается ли вычисленный нами процент от «истинного» процента, то есть доли интересующих нас объектов в генеральной совокупности?
Вот пример. В больнице есть группа из 476 пациентов, среди кото- рых 356 курят. Мы знаем, что в среднем по больнице доля курящих составляет 0.7 (70%). А вот в нашей группе она чуть побольше — при- мерно 75%. Для того чтобы проверить гипотезу о том, что доля куря- щих в рассматриваемой группе пациентов отличается от средней доли по больнице, мы можем задействовать так называемый биномиальный тест:
> binom.test(x=356, n=476, p=0.7, alternative="two.sided")

92
Великое в малом: одномерные данные
Exact binomial test data:
356 and 476
number of successes = 356, number of trials = 476,
p-value = 0.02429
alternative hypothesis: true probability of success is not equal to 0.7 95 percent confidence interval:
0.7063733 0.7863138
sample estimates:
probability of success
0.7478992
Поскольку p-значение значительно меньше 0.05 и альтернативная гипотеза состоит в том, что доля курильщиков (она здесь довольно издевательски называется «probability of success», «вероятность успе- ха») не равна 0.7, то мы можем отвергнуть нулевую гипотезу и при- нять альтернативную, то есть решить, что наши 74% отличаются от средних по больнице 70% не случайно. В качестве опции мы исполь- зовали alternative="two.sided", но можно было поступить иначе —
проверить гипотезу о том, что доля курящих в рассматриваемой груп- пе пациентов превышает среднюю долю курящих по больнице. Тогда альтернативную гипотезу надо было бы записать как alt="greater".
Кроме биномиального, мы можем применить здесь и так называе- мый тест пропорций. Надо заметить, что он применяется шире, потому что более универсален:
> prop.test(x=356, n=476, p=0.7, alternative="two.sided")
1-sample proportions test with continuity correction data:
356 out of 476, null probability 0.7
X-squared = 4.9749, df = 1, p-value = 0.02572
alternative hypothesis: true p is not equal to 0.7 95 percent confidence interval:
0.7059174 0.7858054
sample estimates:
p
0.7478992
Как видим, результат практически такой же.
Тест пропорций можно проводить и с двумя выборками, для это- го используется все та же функция prop.test() (для двухвыборочного

Всегда ли точны проценты
93
текста пропорций), а также mcnemar.test() (для теста Мак-Немара, ко- торый проводится тогда, когда выборки связаны друг с другом). Узнать,
как их использовать, можно, прочитав справку (и особенно примеры!)
по обеим функциям.
* * *
Ответ к задаче про функцию normality()
. Чтобы узнать, отку- да взять значения p-value, надо сначала вспомнить, что в R почти все,
что выводится на экран,— это результат «печати» различных списков при помощи невидимой команды print(). А из списка легко «достать»
нужное либо по имени, либо по номеру (если, скажем, имени у эле- ментов нет — так иногда бывает). Сначала выясним, из чего состоит список-вывод функции shapiro.test():
> str(shapiro.test(rnorm(100)))
List of 4
$ statistic: Named num 0.992
..- attr(*, "names")= chr "W"
$ p.value
: num 0.842
$ method
: chr "Shapiro-Wilk normality test"
$ data.name: chr "rnorm(100)"
- attr(*, "class")= chr "htest"
В этом списке из 4 элементов есть элемент под названием p.value,
что нам и требовалось. Проверим на всякий случай, то ли это:
> set.seed(1683)
> shapiro.test(rnorm(100))$p.value
[1] 0.8424077
Именно то, что надо. Осталось только вставить это название в нашу функцию.
Ответ к задаче про выборы из предисловия.
Для того чтобы рассчитать p-value для нашей пропорции (48% про- голосовавших за кандидата B), можно воспользоваться описанным вы- ше prop.test():
> prop.test(0.48*262, 262)
1-sample proportions test with continuity correction data:
0.48 * 262 out of 262, null probability 0.5
X-squared = 0.343, df = 1, p-value = 0.5581

94
Великое в малом: одномерные данные alternative hypothesis: true p is not equal to 0.5 95 percent confidence interval:
0.4183606 0.5422355
sample estimates:
p
0.48
Получается, что отвергнуть нулевую гипотезу о равенстве пропор- ций мы не можем, слишком велико p-value (гораздо больше «положен- ных» 0.05 и даже «либеральных» 0.1). Процент же проголосовавших может лежать в интервале от 42% до 54%! Итак, по результатам опроса нельзя сказать, что кандидат А победил.
А вот так можно рассчитать количество человек, которых надо опро- сить, чтобы быть уверенным в том, что 48% и 52% и вправду отражают реальную ситуацию (генеральную совокупность):
> power.prop.test(p1=0.48, p2=0.52, power=0.8)
Two-sample comparison of proportions power calculation n = 2451.596
p1 = 0.48
p2 = 0.52
sig.level = 0.05
power = 0.8
alternative = two.sided
NOTE: n is number in *each* group
Получается, что опросить надо было примерно 5 тысяч человек!
Мы использовали здесь так называемый power-тест, который часто применяется для прогнозирования эксперимента. Мы задали значение power = 0.8
, потому что именно такое значение является общеприня- тым порогом значимости (оно соответствует p-value < 0.1). Чуть бо- лее подробно про мощность (power) и ее связь с другими характеристи- ками теста можно прочитать в следующей главе.

Глава 5
Анализ связей: двумерные данные
Здесь речь пойдет о том, как работать с двумя выборками. Если у нас два набора цифр, то первое, что приходит в голову,— сравнить их.
Для этого нам потребуются статистические тесты.
5.1. Что такое статистический тест
Настала пора подробнее познакомиться с ядром статистики — тес- тами и гипотезами. В предыдущей главе мы уже коротко объясняли,
как строятся статистические гипотезы, но если анализ одной выборки можно сделать, не вдаваясь подробно в их смысл, то в анализе связей без понимания этих принципов не обойтись.
5.1.1. Статистические гипотезы
Из первой главы мы знаем, что статистическая выборка должна быть репрезентативной (то есть адекватно характеризовать генераль- ную совокупность, или, как ее еще называют, популяцию). Но как же мы можем знать, репрезентативна ли выборка, если мы не исследовали всю генеральную совокупность? Этот логический тупик называют пара- доксом выборки. Хотя мы и обеспечиваем репрезентативность выборки соблюдением двух основных принципов ее создания (рандомизации и повторности), неопределенность все же остается. Кроме того, если мы принимаем вероятностную точку зрения на происхождение наших дан- ных (которые получены путем случайного выбора), то все дальнейшие суждения, основанные на этих данных, будут иметь вероятностный ха- рактер. Таким образом, мы никогда не сможем на основании нашей выборки со стопроцентной уверенностью судить о свойствах генераль- ной совокупности! Мы можем лишь выдвигать гипотезы и вычислять их вероятность
Великие философы науки (например, Карл Поппер) постулировали,
что мы ничего не можем доказать, мы можем лишь что-нибудь опро- вергнуть. Действительно, если мы соберем 1000 фактов, подтверждаю- щих какую-нибудь теорию, это не будет значить, что мы ее доказали.
1   ...   5   6   7   8   9   10   11   12   ...   19


написать администратору сайта