# $\chi^2$ 检验
## 卡方分布
卡方分布可以通过原假设,得到一个统计量来表示期望结果和实际结果之间的偏离程度,进而根据分布,自由度和假设成立的情况,得出观察频率极值的发生概率(比当前统计结果更加极端的概率)。计算方法是对概率分布中的每个频率,用期望频数和实际频数差的平方除以期望频数,最后把所有结果相加。
$$ \chi^2=\sum \frac {(O-E)^2} {E} $$
得到的统计量结果越大,说明差别越显著,数值越小说明观察和期望的差别越小,当观察频数和期望频数一致是卡方为0。其实就是在比较观测到的比例和期望的比例的关系。
```{r}
ggplot() + xlim(-10,10) +
geom_function(mapping = aes(color="normal Distribution"),
fun = dnorm, args = list(mean = 0, sd = 1),
)+
geom_function(mapping = aes(color="chi-square Distribution"),
fun = dchisq, args = list(df = 1 ,ncp=0),
)+
scale_color_manual(values = c("normal Distribution" = "red",
"chi-square Distribution" = "blue"))+
labs(color = "Distribution")
```
卡方分布就可以用来检验某个分类变量各类的出现概率是否等于指定概率,可以检验数据的拟合优度(指定的一组数据与指定分布的吻合度),也可以用来检验两个变量的独立性(两个变量之间是否存在某种关联)。
在使用卡方检验时,需要的一个参数被称为自由度,指的是独立变量的个数(组数减去限制数)。通常,二项分布已知 $\pi$ ,泊松分布已知 $\lambda$ ,正态分布已知 $\mu$ 和 $\sigma^2$ 时的自由度是n-1。进行独立性检验时,n行m列联列表的自由度是(n-1) x (m-1)。
Pearson’s $\chi^2$ 检验 用于检验涉及**双向无序多分类变量**的概率或比例。
## 2×2列联表
独立性:判断两个或多个分类变量之间是否存在关联或取值互不影响,分析联合概率分布是否可以分解为各自概率分布的乘积。
### 卡方检验
对于频数表中每个单元格的期望频数都比较大(大于 5)的大样本,`correct`设为`FALSE`,不进行连续校正。
```{r}
x <- matrix(c(97,73,7,30),2,dimnames = list(c("experiment","control"),c("+","-")))
x
(k1 <- chisq.test(x,correct = F))
# 期望频数列联表
k1$expected
k1$parameter # degrees of freedom
```
### Yate’s 校正
某些单元格的期望频数接近于或小于 5 时,进行 Yates' 连续校正以修正卡方统计量提高准确性。
```{r}
x <- matrix(c(1004, 325, 20, 1), 2,
dimnames = list(c("experiment", "control"), c("+", "-")))
x
chisq.test(x,correct = F)$expected
# 校正
(k2 <- chisq.test(x,correct = T))
```
### Fisher's Exact 检验
Fisher 精确概率检验(Fisher's Exact Test)通常在以下情况中使用:
1. 总样本数 n 小于 40;
2. 列联表中任何一个单元格的期望频数小于 5。
```{r}
x <- matrix(c(7,2,7,17),2,dimnames = list(c("A","B"),c("Yes","No")))
x
(k5 <- fisher.test(x))
chisq.test(x)
E <- chisq.test(x)$expected
chisq <- sum((x-E)^2/E)
chisq
p_value_asymptotic <- 1 - pchisq(chisq, df = 1)
```
### **超几何分布**
```{r warning=FALSE}
tibble(
x = -10:10,
y_hyper = dhyper(x, m = 10,n = 7,k = 8),
) %>%
ggplot()+
geom_col(aes(x=x,y = y_hyper,color="Hypergeometric Distribution"),fill=NA)+
geom_function(aes(color="Normal Distribution"),
fun= dnorm, args = list(mean = 0, sd = 1))+
scale_color_manual(values = c("Normal Distribution" = "red",
"Hypergeometric Distribution" = "blue"))+
labs(color = "Distribution")
```
## 配对四格表
### 二项分布
```{r}
tibble(
x = -5:15,
y_binom = dbinom(x, size = 10,prob = 0.5),
) %>%
ggplot()+
geom_col(aes(x=x,y=y_binom,color="binomal Distribution"),fill=NA)+
geom_function(mapping = aes(color="normal Distribution"),
fun = dnorm, args = list(mean = 5, sd = 1),
)+
scale_color_manual(values = c("normal Distribution" = "red",
"binomal Distribution" = "blue"))+
labs(color = "Distribution")
```
### McNemar's 检验
20 \< **b+c =**5 + 34 \< 40
```{r}
x <- matrix(c(36,34,5,135),2,dimnames = list(c("A+","A-"),c("B+","B-")))
x
(k3 <- mcnemar.test(x,correct = F))
# 对于配对四格表,如果样本量较小(不一致的结果的总数小于 40 ) ,则需要进行连续性校正。
(k4 <- mcnemar.test(x,correct = T))
```
```{r}
# 某实验室分别用免疫荧光法和乳胶凝集法对 58 名疑似系统性红斑狼疮患者血清中抗 核抗体进行测定
result<- matrix(c(11, 2, 12, 33), nrow = 2,dimnames = list(c("+","-"),c("+","-")))
result
# 对于配对四格表,如果样本量较小(不一致的结果的总数小于 40 ) ,则需要进行连续性校正。
mcnemar.test(result,correct = TRUE)
```
### 精确 McNemar's 检验
**b+c = 7 + 1 \<20**
二项分布B(b+c,0.5),k=min(b,c)
$$
P=\sum_{i≤k} p_i
$$
```{r}
x <- matrix(c(3,1,7,9),2,dimnames = list(c("A+","A-"),c("B+","B-")))
x
P_two_sided <- 2*sum(dbinom(x=0:1,size = 8,prob = 0.5))
P_two_sided
```
## R×C列联表
### 卡方检验
在 R×C 列联表的情况下,如果表中的单元格期望频数满足以下条件:
1. **期望频数** T \< 5 的单元格不超过 1/5。
2. **没有单元格期望频数** T \< 1 。
那么可以选择不进行连续校正
```{r}
x <- matrix(c(150,184,198,50,16,2),3,dimnames = list(c("A","B","C"),c("Yes","No")))
x
(k <- chisq.test(x,correct = F))
```
```{r}
(k <- chisq.test(x,correct = T))
k$expected
```
### 多重比较
$$
\alpha'=\frac {\alpha}{比较的次数=\frac{k(k-1)}{2}}
$$
#### 卡方分割法
卡方分割法与Bonferroni方法调整p值是两种不同的统计分析方法,主要用于处理多重比较问题。它们的区别如下: 1. 卡方分割法 - **定义**:卡方分割法通常用于对卡方检验结果进行后续分析,以确定哪些具体的类别或组之间存在显著差异。该方法基于检验统计量在每对比较中的分布进行分析。 - **应用**:常用于发现哪些特定组(行或列)之间存在差异,通常需要进行后续的成对比较。 - **目的**:帮助识别在显著性结果中,具体是哪些组之间存在显著差异。
#### Bonferroni方法
- **定义**:Bonferroni方法是一种用于控制多重比较的显著性水平的校正方法。在进行多次假设检验时,原始的显著性水平(例如0.05)会被除以比较次数,从而得出新的显著性水平。
- **应用**:适用于多个独立检验结果的显著性水平调整,以减少因多重比较导致的假阳性率。
- **目的**:降低第一类错误的概率(即假阳性),确保在多次检验中保持整体的显著性水平。
- **卡方分割法**更侧重于分析具体的类别差异,而**Bonferroni方法**则专注于调整p值以控制错误率。
- 如果你已经通过卡方检验发现某些组之间有显著差异,卡方分割法可以帮助你进一步了解哪些组之间有差异。而Bonferroni方法在初步检验前就帮助控制多重比较的问题,确保分析结果的可靠性。 '
```{r}
# 创建频率矩阵
data <- matrix(c(251, 225,
368, 347,
132, 16,
54, 22,
9, 18,
21, 110,
4, 30,
46, 93),
nrow = 8,
byrow = TRUE)
# 为矩阵添加行和列名称
rownames(data) <- c("团队", "球员", "教练", "品牌", "管理", "历史", "文化", "其他")
colnames(data) <- c("Period 1", "Period 2")
# 执行卡方检验
chi_square_result <- chisq.test(data, correct=T)
# 显示结果
print(chi_square_result)
# 提取卡方值,自由度和p值
chi_square_value <- chi_square_result$statistic
degrees_of_freedom <- chi_square_result$parameter
p_value <- chi_square_result$p.value
# 打印结果
cat("卡方值:", chi_square_value, "\n")
cat("自由度:", degrees_of_freedom, "\n")
cat("显著性水平 (p值):", p_value, "\n")
# 进行多重卡方检验
chi_square_results <- apply(data, 1, function(x) chisq.test(matrix(x, nrow=2)))
# 提取卡方,自由度,p值
X2 <- sapply(chi_square_results, function(x) x$statistic)
p_values <- sapply(chi_square_results, function(x) x$p.value)
df <- sapply(chi_square_results, function(x) x$parameter)
# 多重比较调整
adjusted_p_values <- p.adjust(p_values, method = "bonferroni")
signifcance <- case_when(
adjusted_p_values<0.001 ~ "***",
adjusted_p_values<0.01 ~ "**",
adjusted_p_values<0.05 ~ "*",
.default = "ns"
)
results <- tibble(
dimension = rownames(data),
chisq_statistic = X2,
p_value = p_values,
p_adjust = adjusted_p_values,
signifcance = signifcance
)
print(results)
```
## 拟合优度检验
Pearson’s $\chi^2$ goodness-of-fit test
## Cochran-Mantel-Haenszel $\chi^2$ 检验
又叫行均分检验,常用于按照某个变量进行分层后的检验,**用于检验两个有序分类变量是否存在线性相关**,但实际上用途很广泛,比如因变量是有序变量的单向有序列联表,也可以用。
两个变量的关联有可能受到第三个变量的影响,因此我们有必要检验两个分类变量在 调整(控制)第三个变量的情况下是否独立。 Cochran-Mantel-Haenszel χ 2 检验常用于探索 变量间的混杂因素。其零假设是:两个分类变量在第三个变量的每一层都是条件独立的。函数 mantelhaen.test( ) 可以用来进行该检验。
```{r}
Rabbits <-
array(c(0, 0, 6, 5,
3, 0, 3, 6,
6, 2, 0, 4,
5, 6, 1, 0,
2, 5, 0, 0),
dim = c(2, 2, 5),
dimnames = list(
Delay = c("None", "1.5h"),
Response = c("Cured", "Died"),
Penicillin.Level = c("1/8", "1/4", "1/2", "1", "4")))
Rabbits
mantelhaen.test(Rabbits)
```