#变量之间的关系
importnumpy as npimportpandas as pdimportmatplotlib.pyplot as pltfrom numpy importrandomfrom pandas importSeries,DataFramefrom scipy importstats
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