卡方检验,调查500人,文化程度与性别是否相互独立
[Python] 纯文本查看 复制代码 import numpy as np
import pandas as pd
from scipy import stats
sample_df = pd.read_excel('4-15.xlsx',header=0, index_col=0) # 注意要把性别列作为索引
sample_df
高中及以上 初中 小学及以下
性别
男 44 36 140
女 60 60 160
# 编写一个用于卡方检验的工具
class ChisquareTest():
def __init__(self,df):
self.data = df.copy()
self.summed_data = None
self.expected_data = None
self.chi2_data = None
self.row_sum_name = '行合计'
self.col_sum_name = '列合计'
self.caculate_sum_finished = False
self.caculate_expect_finished = False
def caculate_sum(self, df = None):
sum_original_data = df is None
if sum_original_data:
df = self.data.copy()
df[self.row_sum_name] = df.apply(lambda row:row.sum(),axis = 1 )
df.loc[self.col_sum_name] = df.apply(lambda col: col.sum(),axis = 0 )
if sum_original_data:
self.summed_data = df
self.caculate_sum_finished = True
return df
def caculate_expect(self):
if (not self.caculate_expect_finished):
self.caculate_sum()
self.expected_data = self.data.copy()
total_sum = self.summed_data.loc[self.col_sum_name , self.row_sum_name]
for i in range(len(self.data)):
for j in range(len(self.data.columns)):
row_sum = self.summed_data.iloc[i][self.row_sum_name]
col_sum = self.summed_data.loc[self.col_sum_name][j]
self.expected_data.iloc[i,j] = row_sum * col_sum / total_sum
self.expected_data = self.caculate_sum(self.expected_data)
self.caculate_expect_finished = True
return self.expected_data
def caculate_chi2(self):
if (not self.caculate_expect_finished):
self.caculate_expect()
self.chi2_data = self.data.copy()
for i in range(len(self.data)):
for j in range(len(self.data.columns)):
obs_value = self.data.iloc[i,j]
exp_value = self.expected_data.iloc[i,j]
self.chi2_data.iloc[i,j] = (obs_value - exp_value) ** 2 / exp_value
self.chi2_data = self.caculate_sum(df = self.chi2_data)
return self.chi2_data
chi2test = ChisquareTest(sample_df)
# 求和列表
chi2test.caculate_sum()
高中及以上 初中 小学及以下 行合计
性别
男 44 36 140 220
女 60 60 160 280
列合计 104 96 300 500
以上的都正常,下面的是问题
[Python] 纯文本查看 复制代码 # 期望值表
chi2test.caculate_expect()
高中及以上 初中 小学及以下 行合计
性别
男 45.76 42.24 132.0 220.0
女 60.00 60.00 160.0 280.0
列合计 105.76 102.24 292.0 500.0
这个结果和书上的不一样,书上的是
[Python] 纯文本查看 复制代码 # 卡方统计表
chi2test.caculate_chi2()
高中及以上 初中 小学及以下 行合计
性别
男 0.067692 0.921818 0.484848 1.474359
女 0.000000 0.000000 0.000000 0.000000
列合计 0.067692 0.921818 0.484848 1.474359
这个结果和书上的不一样,书上的是
问题应该是是,不对第二行“女”的数据进行处理,应该是函数中的问题,咋也没找到。
谢谢大家了! |