Тест хи-квадрат используются в основном с двумя целями: 1. Проверить, что распределение соответствует заданному. 2. Проверить, что два фактора независимы.
Поговорим про первый тип задач, приводящий к распределению хи-квадрат. Модельный пример здесь такой: из большого ящика с разноцветными шариками вы вытягиваем наугад несколько шариков и пытаемся на основе этой выборки что-то сказать о распределении шариков в ящике в целом. Допустим, у нас есть предположение, что в ящике 60% красных шариков, 30% синих и 10% чёрных. Мы вытянули 7 шариков, из них 4 оказались красными, 3 синими и 1 чёрный. Согласуется ли такой результат с нашей гипотезой? Для ответа на этот вопрос нужно использовать функцию chisq.test.
chisq.test(c(4,3,1), p=c(0.6,0.3,0.1))
## Warning in chisq.test(c(4, 3, 1), p = c(0.6, 0.3, 0.1)): Chi-squared
## approximation may be incorrect
##
## Chi-squared test for given probabilities
##
## data: c(4, 3, 1)
## X-squared = 0.3333, df = 2, p-value = 0.8465
Видно, что p-value очень большое и уж явно больше, чем 0.05, так что ответ: имеющаяся выборка не противоречит предположению о том, что шарики распределены в соответствии с указанными процентами. Заметим, однако, что R предупреждает нас о возможной некорректности (Chi-squared approximation may be incorrect): это связано с тем фактом, что хи-квадрат работает «плохо», если числа маленькие. В этом случае можно использовать параметр simulate.p.value=TRUE, позволяющий найти p-value более точно за счёт применения генератора случайных чисел:
chisq.test(c(4,3,1), p=c(0.6,0.3,0.1), simulate.p.value = T)
##
## Chi-squared test for given probabilities with simulated p-value
## (based on 2000 replicates)
##
## data: c(4, 3, 1)
## X-squared = 0.3333, df = NA, p-value = 0.8836
Видно, что всё равно p-value очень большое и наша выборка не противоречит нулевой гипотезе о том, что распределение имеет вид «60% красных, 30% синих, 10% чёрных». А вот, скажем, результат «0 красных, 0 синих и 10 чёрных» противоречил бы:
chisq.test(c(0,0,10), p=c(0.6,0.3,0.1), simulate.p.value = T)
##
## Chi-squared test for given probabilities with simulated p-value
## (based on 2000 replicates)
##
## data: c(0, 0, 10)
## X-squared = 90, df = NA, p-value = 0.0004998
Если бы выборка была большая, мы могли бы получить корректное p-value и без симуляции:
chisq.test(c(412,322,121), p=c(0.6,0.3,0.1))
##
## Chi-squared test for given probabilities
##
## data: c(412, 322, 121)
## X-squared = 51.3509, df = 2, p-value = 7.068e-12
Условный (придуманный не-лингвистом) пример задачи: мы хотим написать программу, которая бы корректно определила, сколько в большом тексте встречается существительных, сколько глаголов и сколько остальных слов. Точнее, мы её уже написали, и хотим проверить, правильно ли она работает. Допустим, программа сообщаем нам результат: 33% существительных, 20% глаголов. Теперь мы можем выбрать из всего текста 50 случайных слов, вручную посчитать, сколько среди них существительных, сколько глаголов и сколько остальных слов, и с помощью хи-квадрат проверить, согласуются ли наши ручные выводы с выводами программы. Если мы увидим, что различие значимо, то это будет означать, что программа работает скорее всего неверно. Обратное, впрочем, не очевидно: чтобы доказать, что программа работает скорее всего верно, нужен более аккуратный анализ.
| СМИ | Научные статьи | |
|---|---|---|
| на | 15 | 5 |
| в | 10 | 7 |
Критерий хи-квадрат позволяет проверить, правда ли, что факторы является не независимыми. Иными словами, нулевая гипотеза состоит в том, что и в СМИ, и в научных статьях процент употребления «в» и «на» одинаковый. Можно представить себе, что каждое употребление — это шарик, на котором написано «в» или «на», и мы наугад вытаскиваем шарики из двух урн: на одной написано «СМИ», на другой «Научные статьи». Нулевая гипотеза (о независимости) говорит, что содержимое урн одинаково. Альтернатива состоит в том, что содержимое не одинаково.
Чтобы проверить гипотезу о независимости с помощью хи-квадрат сперва нужно подготовить матрицу, содержащую наши данные. Делается это, например, так.
conj <- matrix(c(15,10,5,7),nrow = 2)
conj
## [,1] [,2]
## [1,] 15 5
## [2,] 10 7
Теперь можно использовать хи-квадрат:
chisq.test(conj)
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: conj
## X-squared = 0.4833, df = 1, p-value = 0.4869
Из-за маленьких чисел хи-квадрат включил так называемую поправу Йейтса. Можно также использовать симуляцию p-value или точный тест Фишера, работающий как раз для матриц сопряженности 2×2.
fisher.test(conj)
##
## Fisher's Exact Test for Count Data
##
## data: conj
## p-value = 0.4821
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
## 0.4216082 10.8587425
## sample estimates:
## odds ratio
## 2.057288
Видно, что в данном случае тест Фишера (он точный) даёт примерно такой же результат, как хи-квадрат с поправкой Йейтса. В любом случае, p-value больше, то есть нулевую гипотезу опровергнуть не удаётся: наших данных недостаточно, чтобы заявить о наличии зависимости между типом текста и использованием «в» или «на». ### Вычисление таблицы сопряженности по датафрейму с факторами Допустим, у нас были бы не готовые числа, а табличка, каждая строчка которой соответствовала бы одному словоупотреблению. Примерно такая:
df <- data.frame(vna = as.factor(c("v","v","na","v","na","v","na")), type = as.factor(c("smi","smi","papers","papers","smi","smi","papers")))
df
## vna type
## 1 v smi
## 2 v smi
## 3 na papers
## 4 v papers
## 5 na smi
## 6 v smi
## 7 na papers
Чтобы по такой табличке построить таблицу сопряженности (матрицу, аналогичной той, что была выше), можно использовать функцию table
conj <- table(df)
conj
## type
## vna papers smi
## na 2 1
## v 1 3
Она автоматически посчитает, сколько раз какая пара факторов встретилась. Теперь можно скормить получившуюся матрицу хи-квадрату:
chisq.test(conj)
## Warning in chisq.test(conj): Chi-squared approximation may be incorrect
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: conj
## X-squared = 0.1094, df = 1, p-value = 0.7409
А лучше тесту Фишера (числа совсем маленькие):
fisher.test(conj)
##
## Fisher's Exact Test for Count Data
##
## data: conj
## p-value = 0.4857
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
## 0.1130507 467.0049386
## sample estimates:
## odds ratio
## 4.449596