前言
关于卡方分布的介绍,可以通过与皮尔逊相关比较,能有一个更清晰的认识。
引用《行为科学统计》一书中的话:
独立性卡方检验与皮尔逊相关都是用来评估两个变量间关系的统计技术。从研究中得到的数据类型,决定了应该使用着两个统计过程中的哪一个。
当两个变量都由数值组成时,应使用皮尔逊相关评估变量间的关系;另一个方面,如果数据是由将个体归类到类别中而得到的,应使用独立性卡方检验。
举例来说:
1.研究人员想要知道身高和年龄的关系,通过样本最终会的到两组数值,分别对应身高和年龄这两个变量,此时应该使用皮尔逊相关,因为这两个变量:身高和年龄,对应的是具体的数值。
2.研究人员想要知道吃辣程度和省份的关系,通过样本只能得到频数统计,因为‘吃辣程度’和‘省份’对应的是类别,而没用数值,所以此时就应该使用卡方检验。
卡方分布的特征
卡方值是通过计算期望值和真实值差值的平方和得来的,因此它永远都是大于等于0的值,这同时说明卡方分布是正偏态的。
卡方
=
∑
(
d
−
e
)
2
e
,其中
d
代表真实值,
e
为期望值
卡方={\sum\frac{(d-e)^2}{e}} ,其中d代表真实值,e为期望值
卡方=∑e(d−e)2,其中d代表真实值,e为期望值
从公式也可以看出,卡方值越大,说明差异性越大,在卡方分布上就越靠近右侧,那么它的临界区域就位于卡方分布的右侧,因此卡方检验也是个单侧检验。
例子数据
150个10岁儿童的样本的自尊与学习成绩的频数分布:
自尊水平-高 | 自尊水平-中 | 自尊水平-低 | |
---|---|---|---|
学习成绩-高 | 17 | 32 | 11 |
学习成绩-低 | 13 | 43 | 34 |
代码实现
maven
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
计算方法
package com.math.statistics;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.math3.distribution.ChiSquaredDistribution;
/***
* 卡方检验
* @author miaoyibo
*
*/
public class ChiSquaredTest {
private double[][] data;
private int free;
ChiSquaredDistribution cs;
public ChiSquaredTest(double[][] data) {
this.data = data;
free=(data.length-1)*(data[0].length-1);
cs=new ChiSquaredDistribution(free);
}
public double calculateChisquare() {
double sum=0;
Map<Integer,Double> col_data=new HashMap<>();
Map<Integer,Double> row_data=new HashMap<>();
for(int i=0;i<data.length;i++) {
for(int j=0;j<data[i].length;j++) {
sum=sum+data[i][j];
setData(col_data, j, data[i][j]);
setData(row_data, i, data[i][j]);
}
}
double chisquare=0;
for(int i=0;i<data.length;i++) {
for(int j=0;j<data[i].length;j++) {
double col_sum= col_data.get(j);
double percent=col_sum/sum;
double row_sum=row_data.get(i);
//期望值
double expect=row_sum*percent;
//真实值-期望值
chisquare=chisquare+(Math.pow(data[i][j]-expect, 2)/expect);
}
}
return chisquare;
}
/***
* 获取p值
* 单侧检验
* @return
*/
public double getPValue() {
double chi=calculateChisquare();
return 1-cs.cumulativeProbability(chi);
}
private void setData(Map<Integer, Double> data, int key, double v) {
Double d1 = data.get(key);
if(d1!=null) {
data.put(key, d1+v);
}else {
data.put(key, v);
}
}
}
例子数据结果
public static void main(String[] args) {
double[][] data= {{17,32,11},{13,43,34}};
ChiSquaredTest ct=new ChiSquaredTest(data);
//卡方值
System.out.println(ct.calculateChisquare());
//P值
System.out.println(ct.getPValue());
}
参考
[1]《行为科学统计》
[2] https://javadoc.io/doc/org.apache.commons/commons-math3/latest/index.html