Python 数据分析之变量之间的关系

#变量之间的关系
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from numpy import random
from pandas import Series,DataFrame
from scipy import stats

tips=pd.read_csv('tips.csv')
print(tips)

'''
1.从单变量到多变量
单变量分析:数字特征,分布
多变量分析:有没有关系,有多大关系
'''
#可视化分析:点图
fig=plt.figure(figsize=(8,6))
ax=fig.add_subplot(1,1,1)
ax.plot(np.random.rand(50).cumsum(),'.')
ax.plot(np.random.rand(50).cumsum(),'.')
ax.plot(np.random.rand(50).cumsum(),'o')
plt.show()

#可视化分析tips.csv
fig,ax=plt.subplots(1,1,figsize=(8,6))
#subplots (行,列,.....)
ax.plot(tips[tips['sex']=='Male']['tip'],'o',label='Male')
ax.plot(tips[tips['sex']=='Female']['tip'],'o',label='Female')
#label 为了画图例方便
ax.legend(loc='best')
plt.show()

#可视化优势:更容易发现'模式'
fig,ax=plt.subplots(1,1,figsize=(8,6))
ax.plot(tips[tips['sex']=='Male']['total_bill'],tips[tips['sex']=='Male']['tip'],'o',label='Male')
ax.plot(tips[tips['sex']=='Female']['total_bill'],tips[tips['sex']=='Female']['tip'],'o',label='Female')
ax.legend(loc='best')
plt.show()

tips['tips_pct']=tips['tip']/tips['total_bill']
tips['tips_pct'].hist(by=tips['sex'],bins=50,range=[0,0.8])
plt.show()

#可视化分析:箱线图
#boxplot()
rvs1=tips[tips['sex']=='Male']['tips_pct']
rvs2=tips[tips['sex']=='Female']['tips_pct']
plt.boxplot([rvs1,rvs2],labels=['Male','Female'])
plt.show()

#进一步探索变量之间的关系
#独立性检验
#1.类别型~类别型   性别与星期几的关系
count=pd.crosstab(tips.sex,tips.day)
print(count)
'''
day     Fri  Sat  Sun  Thur
sex                        
Female    9   28   18    32
Male     10   59   58    30
生成列联表
'''
count.T.plot(kind='bar')
plt.show()

print(stats.chi2_contingency(count,correction=False))
#chi2 卡方检验   contingency列联表  列联表中每个格子数量至少为5
#对性别和星期几进行卡方检验
#(13.22200137240661, 0.004180302092822257, 3, array([[ 6.77459016, 31.0204918 , 27.09836066, 22.10655738],
#       [12.22540984, 55.9795082 , 48.90163934, 39.89344262]]))
chi2,p,dof,ex=stats.chi2_contingency(count,correction=False)
#chi2表示卡方检验值,p表示P值,dof表示自由度,ex表示每个格子P(AB)应该的概率
print(p)
#0.004180302092822257
#P值很小,拒绝原假设,说明性别与星期几有关系
#独立性检验中,H0:AB无关,H1:AB有关系

#费舍尔精确检验 只能检验2*2的表
count=pd.crosstab(tips.sex,tips.smoker)
print(count)
'''
smoker  No  Yes
sex            
Female  54   33
Male    97   60
'''
oddsratio,pvalue=stats.fisher_exact(count)
print(oddsratio,pvalue)
#1.0121836925960637 1.0
#P值很大,不能拒绝H0,是否吸烟和男女没有关系

#如果修改一下列联表中数据
count.iat[0,0]=2
print(count)
oddsratio,pvalue=stats.fisher_exact(count)
print(oddsratio,pvalue)
#0.03748828491096532 3.9900059898475383e-10
#P值很小,拒绝H0,吸烟和男女有关系
#fisher精确检验的优势:每个表格中数据不一定大于五
#               劣势:只能检验2*2

'''
2.数值型~数值型
pearson:积差相关系数,反应两个变量之间的线性相关性
spearman:等级相关系数(Ranked data)
Kendall's Tau:非参数等级相关系数
'''
#pearson就是统计学中学过的相关系数
print(stats.pearsonr(tips.total_bill,tips.tip))
#(0.6757341092113643, 6.692470646864041e-34)
#线性相关度和P值

#spearman相关系数:先对所有变量进行排序,在做线性相关
# 1.与pearson不同,不假设变量为正态分布
# 2. -1~+1  衡量变量之间的单调性
#-1表示
np.random.seed(1232133)
#如果seed确定,那么x,y随机数是一样的
x=np.random.randn(100)
y=np.random.randn(100)
rho,pval=stats.spearmanr(x,y)
print(rho,pval)
#0.031383138313831375 0.7565897728405165
#P值很大,无法拒绝原假设,原假设:两个变量不相关(独立)

#pearson和spearman区别
#如果有线性模式,也有一些离散点,spearman线性相关系数要大一些,因为离散点破坏了线性相关性,但是对rank排序影响不太大
#pearson只能处理两组数据,spearman可以处理多组序列

x2n=np.random.randn(100,2)
y2n=np.random.randn(100,2)
rho,pval=stats.spearmanr(x2n,y2n)
print(rho)
print(pval)
rho,pval=stats.spearmanr(x2n.T,y2n.T,axis=1)
print(rho)
print(pval)
'''
[[ 1.          0.00536454  0.10976298 -0.01923792]
 [ 0.00536454  1.          0.09857786 -0.04513651]
 [ 0.10976298  0.09857786  1.          0.17354935]
 [-0.01923792 -0.04513651  0.17354935  1.        ]]
[[0.         0.95775479 0.27698447 0.84932628]
 [0.95775479 0.         0.3291814  0.65565667]
 [0.27698447 0.3291814  0.         0.08420292]
 [0.84932628 0.65565667 0.08420292 0.        ]]
'''

'''
3.kendall's tau相关系数
tau=(P-Q)/sqrt((P+Q+T)*(P+Q+U))
P:同步数据对数,Q:异步,T:tie in x,U:tie in y
'''
x=[1,2,3,4,5,5,4,6,-1]
y=[3,4,3,4,5,5,3,7,7]
'''
x中1-2增加,y中3-4增加,即为同步P
x中2-3增加,y中4-3减少,即为异步Q
x中两个数相等,但y中不相等,即为T
y中两个数相等,但x中不相等,即为U
'''
tau,p_value=stats.kendalltau(x,y)
print(tau,p_value)
#0.3444233600968322 0.22913623766848912

#数值型和数值型--回归分析,见下一章
'''
3.数值型~类别型(自变量类别型,因变量数值型)
男女性别中给小费是否不同
'''
rvs1=tips[tips['sex']=='Male']['tip']
rvs2=tips[tips['sex']=='Female']['tip']
print(stats.ttest_ind(rvs1,rvs2))
#Ttest_indResult(statistic=1.3878597054212687, pvalue=0.16645623503456763)
#P值较大,不能拒绝原假设:男女性别给小费的费率没有不同

#以上男女和性别不相关
#如果同一个样本重复抽样,stats.ttest_rel()需要用这个检验,但必须保证两组数据长度相等
print(stats.ttest_rel(rvs1[:87],rvs2))
#Ttest_relResult(statistic=1.3639526706337008, pvalue=0.1761417001637746)
#t检验比较的是两组数的点估计和理想值得比较

#单因素ANOVA方差分析
#对误差平方和,因素平方和进行F检验。如果F检验为1左右,认为不能拒绝原假设,AB不相关
print(stats.f_oneway(rvs1,rvs2))
#F_onewayResult(statistic=1.9261545619320048, pvalue=0.16645623503457202)

#练习:星期几对小费是否有影响
print(pd.crosstab(tips.tip,tips.day))
Thur=tips[tips['day']=='Thur']['tip']
Fri=tips[tips['day']=='Fri']['tip']
Sat=tips[tips['day']=='Sat']['tip']
Sun=tips[tips['day']=='Sun']['tip']
print(stats.f_oneway(Thur,Fri,Sat,Sun))
#F_onewayResult(statistic=1.6723551980998699, pvalue=0.1735885553040592)

'''
方差分析检验对数据得假设:
1.样本之间相互独立
2.样本均来自正态分布
3.方差齐次性:各组方差相等
'''
print(stats.fligner(rvs1,rvs2))
#FlignerResult(statistic=1.6183029033640117, pvalue=0.20332858592898514)
#P值较大,认为方差齐次

#如果不满足以上任意一条
'''
ANOVA得非参数版本
Kruskal-Wallis H-test
H0:各组中值相等
对数据也有假设:Chi2卡方分布,因此样本容量需不小于5
给出得结果宽松一些,没有ANOVA强
'''
print(stats.kruskal(rvs2,rvs1))
#KruskalResult(statistic=0.7615717066668545, pvalue=0.38283710822789807)

#帕累托分布
#P(X>x)=(x/xmin)**(-k)
#E(P)=xmin*k/(k-1)
#构造一组帕累托分布,均值为50,k值(shape为1.2),且具有大于1000的点
#size为多少才有把我里面有大于1000的数
x=stats.pareto.rvs(b=1.2,loc=50,size=1000)
p=1-stats.pareto.cdf(1000,b=1.2,loc=50)
print(p)
#0.0002671355417115384  不存在

print(1-stats.binom.cdf(1,20000,p))
#0.9696783490389687

 

posted @ 2018-07-20 13:44  Lzxanthony  阅读(6855)  评论(0编辑  收藏  举报