#變量之間的關系 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
