2024年Python最全用python进行列联表卡方检验_python列联表检验代码csdn(1)

文章讲述了如何通过Python进行数据合并,使用探索性分析检测8-9月用户登录次数的变化,并利用卡方检验分析性别、年龄段和设备类型与登录次数的关系,发现设备因素显著影响登陆次数。
摘要由CSDN通过智能技术生成

udba_na = np.sum(user_database.isnull().sum())
ulg_na = np.sum(user_login.isnull().sum())
print(udba_na,‘-----\n-----’,ulg_na)
if udba_na == 0 and ulg_na == 0:
print(‘进行下一步’)
else:
print(‘再检查’)


以上是 常规操作



#merge
new_df = pd.merge(user_login,user_database,how=‘left’,on=‘user_id’)
new_df.drop([‘app_name_x’,‘app_name_y’],axis=1,inplace=True)
new_df.log_date = pd.to_datetime(new_df.log_date)
#merge成功之后,进行探索性分析
#8-9月之间登陆次数是否有异常
logdf = new_df.groupby([‘log_date’]).count()[‘user_id’]
logdf.plot(figsize=(20,10),legend=True,fontsize=20,
label = ‘用户数’,linewidth =2,colormap = ‘BrBG_r’,marker=‘o’,
alpha=0.6,linestyle=‘–’,grid=True)
plt.legend(fontsize=20)
plt.title(‘8-9月登陆用户数趋势图’,fontsize=20)
plt.grid(which=‘y’,linestyle=‘–’,color=‘grey’,alpha=0.8)
#明显整体趋势走弱,最大断崖式下跌9月10-11-12日


这里首先进行merge,因为是两个文件,采用的是left join的形式,和SQL一样。然后根据图像进行分析。


![](https://pic1.zhimg.com/80/v2-aa87d6e682368ca98aa70aa0790885fe_hd.jpg)


整体趋势向下走,在9月初一下子降得有点严重。


进一步分析为什么会这样



#8-9月月活跃玩家整体下降
new_df.index = new_df.log_date
new_df[‘log_month’] = new_df.index.month


这里先把月份提取出来,因为做卡方检验需要分类数据


这里我写了3个自定义函数,是为了输出报告



#看哪几个因素有影响
#主因素 月份 其他因素:年龄段,性别,设备
#自定义函数,做卡方检验
def colu(df,col):
uni = df[col].unique().tolist()
return uni
def observe(df,subcol,maincol):
d = []
lst1 = colu(df,subcol)
lst2 = colu(df,maincol)
for l in lst1:
for ls in lst2:
b = len(df[(df[subcol] == l)&(df[maincol]==ls)])
d.append(b)
return d
def split_array(df,subcol,maincol):
result_lst = []
lst = observe(df,subcol,maincol)
for j in range(0,len(lst),len(colu(df,maincol))):
result = lst[j:j+len(colu(df,maincol))]
result_lst.append(result)
result_lst = np.array(result_lst)
return result_lst.T
def chi(array):
#计算理论值
#main = np.sum(array,axis=1)
#sub = np.sum(array,axis=0)
sum_ = np.sum(np.sum(gender_month))
#理论值:
#expectation_value = sum_(main/np.sum(main))(sub/np.sum(sub))
#expectation_value1 = sum_(1-main/np.sum(main))(sub/np.sum(sub))
if sum_ > 40:
print(‘样本量大于40’)
chi,p,v,exp = stats.chi2_contingency(array,correction=False)
else:
print(‘样本量小于40’)
chi,p,v,exp = stats.chi2_contingency(array,correction=True)
print (‘’’

报告
χ2值:{}
p值:{}
自由度:{}
理论值:
{}

  '''.format(chi,p,v,exp))
if p > 0.05:
    print('不拒绝原假设,无充分证据表明两个因素之间存在关系,即可认为该因素不影响登陆次数')
else:
    if p < 0.05:
        print('显著性水平α=0.05下,拒绝原假设,充分相关,建议作图分析做进一步判断到底是因子里面哪个因素起作用')
    elif p < 0.01:
        print('显著性水平α=0.01下,拒绝原假设,显著相关,建议作图详细分析')
return (chi,p,v,exp)

总的思路就是,先把属性提取出来,然后循环遍历把对应的数据总量算出来,最后转换为numpy.array格式,根据scipy的stats里面的chi2\_contingency方法做相关性检验,里面有个参数叫correction,是连续性修正,默认True,这是因为理论值全部小于5,且样本量小于40或者样本量大于40有一格或几格的理论值小于5的时候就要用这个修正。



#性别和月份检测:
#返回的是转置后的二维数组,index分别是月份,columns名是M,F
gender_month = split_array(new_df,‘gender’,‘log_month’)
print(‘--------------------性别和月份------------------------\n’)
chi(gender_month)
print(‘------------------------------------------------------\n’)
#年龄段和月份检测:
generation_month = split_array(new_df,‘generation’,‘log_month’)
print(‘--------------------年龄和月份------------------------\n’)
chi(generation_month)
print(‘------------------------------------------------------\n’)
#设备和月份检测:
device_month = split_array(new_df,‘device_type’,‘log_month’)
print(‘--------------------设备和月份------------------------\n’)
chi(device_month)
print(‘------------------------------------------------------\n’)


返回的结果



--------------------性别和月份------------------------

样本量大于40

====================================================
报告
χ2值:2.009573852892115
p值:0.1563092191352709
自由度:1
理论值:
[[46987.45685607 47197.54314393]
[38002.54314393 38172.45685607]]

不拒绝原假设,无充分证据表明两个因素之间存在关系,即可认为该因素不影响登陆次数

--------------------年龄和月份------------------------

样本量大于40

====================================================
报告
χ2值:17.246958670810887
p值:0.0017306236244977753
自由度:4
理论值:
[[33669.09192299 4789.96736323 27807.68449166 9023.75892228
18894.49729984]
[27230.90807701 3874.03263677 22490.31550834 7298.24107772
15281.50270016]]

显著性水平α=0.05下,拒绝原假设,充分相关,建议作图分析做进一步判断到底是因子里面哪个因素起作用

--------------------设备和月份------------------------

样本量大于40

====================================================
报告
χ2值:2042.142383870325
p值:0.0
自由度:1
理论值:
[[51824.41720474 42360.58279526]
[41914.58279526 34260.41720474]]

显著性水平α=0.05下,拒绝原假设,充分相关,建议作图分析做进一步判断到底是因子里面哪个因素起作用


这里两组因子都返回了p值在显著性水平0.05下小于0.05


因此进一步查看相关数据,这里是用到了pandas的交叉表,当然用pivottable也就是透视表也可以。



#研究年龄段是否真的影响
#Python学习交流群:548377875
age_df=pd.crosstab(index=new_df.log_month,
columns=new_df.generation,
values=new_df.user_id,aggfunc=‘count’)
print(age_df)


返回



generation 10 20 30 40 50
log_month
8 18785 33671 28072 8828 4829
9 15391 27229 22226 7494 3835


初步看20代、30代的玩家是该手游的主力玩家,这时候要比较8月和9月各个年龄段之间的差值以及每个月内的占比,也就是比较组间差距和组内 差距



#8-9月年龄段同比
Aug_age_df = age_df.loc[8]
Sep_age_df = age_df.loc[9]
diff_age_df = (Sep_age_df - Aug_age_df)/Aug_age_df
print(diff_age_df,‘\n40-49年龄段同比下降幅度15%,其他年龄段同比下降20%左右’)
print(Aug_age_df/Aug_age_df.sum(),‘\n’,Sep_age_df/Sep_age_df.sum())
#看整体
age_df.plot(figsize=(20,10),kind=‘bar’,rot=0,fontsize=25,stacked=True)
plt.legend(fontsize=20)
print(‘20、30代下降得比较严重’)


返回



generation
10 -0.180676
20 -0.191322
30 -0.208250
40 -0.151110
50 -0.205840
dtype: float64
40-49年龄段同比下降幅度15%,其他年龄段同比下降20%左右
generation
10 0.199448
20 0.357499
30 0.298052
40 0.093730
50 0.051271
Name: 8, dtype: float64
generation
10 0.202048
20 0.357453
30 0.291776
40 0.098379
50 0.050345
Name: 9, dtype: float64
20、30代下降得比较严重


单单这样比较起来,每个年龄段在每个月内的占比情况其实大同小异,再看组间差距,可以发现除了40代以外,其他都是维持在20%左右的降幅,作为一个异常值,可以去尝试把40代的数据挑出来再做检验


![](https://pic2.zhimg.com/80/v2-9aa48456608d0a0b09fe2f739c2f6f97_hd.jpg)



最后

🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。
🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。
🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值