分類數據的
擬合優度檢驗 卡方檢驗主要是測試樣本分類數據的分布是否符合預期分布。相信大家如果學過高中生物,都知道孟德爾——遺傳學之父,當時他根據顏色和形狀把豌豆分為四類:黃圓、綠圓、黃皺和綠皺.孟德爾根據遺傳學原理判斷這四類的比例應為9:3:3:1.為做驗證,孟德爾分別統計了這四類豌豆的個數,正是利用
檢驗證明了這令人激動的結論 在處理分類數據時,這些類別值本身對統計檢驗沒有多大用處,比如像「男性」、「女性」和「其他」這樣的類別數據沒有任何數學意義。所以處理分類變量的檢驗是基於變量計數,而不是變量本身的實際值。
下面通過生成一些虛假的人口統計數據,並通過
檢驗來檢驗它們是否不同: import numpy as np
import pandas as pd
import scipy.stats as statsnational = pd.DataFrame(["white"]*100000 + ["hispanic"]*60000 +\
["black"]*50000 + ["asian"]*15000 + ["other"]*35000)
minnesota = pd.DataFrame(["white"]*600 + ["hispanic"]*300 + \
["black"]*250 +["asian"]*75 + ["other"]*150)
national_table = pd.crosstab(index=national[0], columns="count")
minnesota_table = pd.crosstab(index=minnesota[0], columns="count")
print( "National")
print(national_table)
print(" ")
print( "Minnesota")
print(minnesota_table)National
col_0 count
0
asian 15000
black 50000
hispanic 60000
other 35000
white 100000
Minnesota
col_0 count
0
asian 75
black 250
hispanic 300
other 150
white 600
檢驗是基於 檢驗統計量。使用以下公式計算檢驗統計量的值: observed = minnesota_table
national_ratios = national_table/len(national) # 實際值
expected = national_ratios * len(minnesota) # 理論值
chi_squared_stat = (((observed-expected)**2)/expected).sum()
print(chi_squared_stat)col_0
count 18.194805
dtype: float64
檢驗假設所有預期計數均不小於5,如果某一類別的個數小於5,就將相鄰的某些類別合成為一類。 拒絕域:W={
},其實r為類別數,a為顯著性水平 crit = stats.chi2.ppf(q = 0.95, # 找到95%置信度的臨界值
df = 4) # 自由度個數
print("Critical value")
print(crit)
p_value = 1 - stats.chi2.cdf(x=chi_squared_stat, # P值
df=4)
print("P value")
print(p_value)Critical value
9.487729036781154
P value
[0.00113047]由於檢驗統計量大於P值,所以得出結論,有95%的把握認為上述兩個總體的分布不是相同的。
當然也可以使用scipy.stats.chisquare()函數,十分快捷!
stats.chisquare(f_obs= observed, # 觀察值
f_exp= expected) # 理論值Power_divergenceResult(statistic=array([18.19480519]), pvalue=array([0.00113047]))
獨立性檢驗獨立性檢驗是統計學的另一種檢驗方式,它是根據次數判斷兩類變量彼此相關或相互獨立的假設檢驗。下面生成一些虛假的選民投票數據並進行獨立性測試,用於確定教育、政治觀點和其他偏好等變量是否因性別、種族和宗教等人口因素而有所不同:
np.random.seed(10)
voter_race = np.random.choice(a= ["asian","black","hispanic","other","white"],
p = [0.05, 0.15 ,0.25, 0.05, 0.5],
size=1000)
voter_party = np.random.choice(a= ["democrat","independent","republican"],
p = [0.4, 0.2, 0.4],
size=1000)
voters = pd.DataFrame({"race":voter_race,
"party":voter_party})
voter_tab = pd.crosstab(voters.race, voters.party, margins = True)
voter_tab.columns = ["democrat","independent","republican","row_totals"]
voter_tab.index = ["asian","black","hispanic","other","white","col_totals"]
observed = voter_tab.iloc[0:5,0:3]
print(voter_tab)democrat independent republican row_totals
asian 21 7 32 60
black 65 25 64 154
hispanic 107 50 94 251
other 15 8 15 38
white 189 96 212 497
col_totals 397 186 417 1000對於獨立性測試,使用與擬合優度檢驗相同的檢驗統計量。主要區別在於,獨立性檢驗必須在二維表格中計算每個單元格的預期計數,而不是一維表格。要獲得單元格的預期計數,需要將該單元格的行總計乘以該單元格的列總計,然後除以觀察的總數。可以通過np.outer()除以總的觀察數快速獲得表中所有單元格的理論值
expected = np.outer(voter_tab["row_totals"][0:5],
voter_tab.loc["col_totals"][0:3]) / 1000
expected = pd.DataFrame(expected)
expected.columns = ["democrat","independent","republican"]
expected.index = ["asian","black","hispanic","other","white"]
print(expected)democrat independent republican
asian 23.820 11.160 25.020
black 61.138 28.644 64.218
hispanic 99.647 46.686 104.667
other 15.086 7.068 15.846
white 197.309 92.442 207.249現在可以按照之前相同的步驟來計算檢驗統計量,臨界值和p值:
chi_squared_stat = (((observed-expected)**2)/expected).sum().sum()
print(chi_squared_stat)7.169321280162059注意:調用此處使用sum()方法兩次:第一次是獲取列和,第二次是將列和相加,返回整個二維表的總和。
crit = stats.chi2.ppf(q = 0.95, #找到95%置信度的臨界值
df = 8)
print("Critical value")
print(crit)
p_value = 1 - stats.chi2.cdf(x=chi_squared_stat, # P值
df=8)
print("P value")
print(p_value)Critical value
15.50731305586545
P value
0.518479392948842獨立性測試的自由度等於每個變量中類別數減去1的乘積。在本例中,有一個5x3表,因此df=4x2=8。
同樣可以使用scipy快速進行獨立性測試
stats.chi2_contingency(observed= observed)(7.169321280162059, 0.518479392948842, 8, array([[ 23.82 , 11.16 , 25.02 ],
[ 61.138, 28.644, 64.218],
[ 99.647, 46.686, 104.667],
[ 15.086, 7.068, 15.846],
[197.309, 92.442, 207.249]]))輸出檢驗統計量的值、p值和自由度以及理論值矩陣。
7.169321280162059<15.50731305586545,落入接受域,故認為上述兩變量之間無顯著關係。