百度百科的解釋:
卡方檢驗:
就是用來驗證兩個類別變量是否獨立,還是相關
就是統計樣本的實際觀測值與理論推斷值之間的偏離程度,實際觀測值與理論推斷值之間的偏離程度就決定卡方值的大小,如果卡方值越大,二者偏差程度越大;反之,二者偏差越小;若兩個值完全相等時,卡方值就為0,表明理論值完全符合。
例子:
|
男
|
女
|
||
|
化妝
|
15(55)
|
95(55)
|
110
|
|
不化妝
|
85(45)
|
5(45)
|
90
|
|
100
|
100
|
200
|
如果性別和化妝與否沒有關系,四個格子應該是括號里的數(期望值,用極大似然估計55=100*110/200,其中110/200可理解為化妝的概率,乘以男人數100,得到男人化妝概率的似然估計),這和實際值(括號外的數)有差距,理論和實際的差距說明這不是隨機的組合。
應用擬合度公式
=
129.3>10.828
顯著相關,作此推論成立的概率p>0.999,即99.9%。
至於這個10.828,不重要,我們只需要看p值,p值需要查表。
python 卡方檢驗:
scipy.stats.chi2_contingency 列聯表中變量獨立性的卡方檢驗
chi2_contingency(observed, correction=True, lambda_=None)
參數:
observed:列聯表,可有pd.crosstab,生成
correction :如果為True,並且自由度為1,則應用Yates校正以保持連續性。校正的效果是將每個觀察值向相應的期望值調整0.5
lambda_ :float或str,可選。默認情況下,此測試中計算的統計量是Pearson的卡方統計量。 lambda_允許使用Cressie-Read功率散度族的統計量來代替。有關power_divergence詳細信息,請參見 。
返回:
chi2:float,卡方值
p:float,p值
dof:int,自由程度
expected:ndarray,預期頻率,基於表的邊際總和
官網例子:https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.chi2_contingency.html#r564
from scipy.stats import chi2_contingency obs = np.array([[10, 10, 20], [20, 20, 20]]) chi2_contingency(obs) ''' obs 輸出: array([[10, 10, 20], [20, 20, 20]]) 卡方檢驗輸出: (2.7777777777777777, 0.24935220877729622, 2, array([[12., 12., 16.], [18., 18., 24.]])) '''
我們也可以寫函數處理
def chi_test(x, y): """皮爾遜卡方獨立檢驗: 衡量特征的區分度 \n 參數: ----------- x: array-like, 一維,離散型特征變量 \n y: array-like,一維,另一個離散型特征變量。當 y 為目標變量時,此檢驗可以衡量特征區的分度 \n 返回值: ---------- chi_result: dict, 卡方檢驗結果, 其中: \n 鍵'Value'是卡方值, \n 鍵'Prob'是檢驗的 p 值,值越小, x 與 y 之間的關聯性越強/ 區分度越大 \n 鍵'LLP'是 -log(Prob),值越大, x 與 y 之間的關聯性越強 \n 鍵'DF'是卡方值的自由度. """ from scipy.stats import chi2_contingency tab = pd.crosstab(x, y).fillna(0) chi_value, p_value, def_free, _ = chi2_contingency(tab) return {'DF': def_free, 'Value': chi_value, 'Prob': p_value, 'LLP': -np.log(p_value)}
當類別型變量特別多的時候,我們需要寫一個for循環去處理
#main_people是裝有類別變量明細數據的表 chi_df_1 = pd.DataFrame(columns=['name1','name2','chi_value','chi_p','DF','LLP']) #首先創造一個空的表,用於下面的append使用 for i in range(2,17): #這個是類別變量位置 for j in range(i+1,17): #主要為了不重復計算 chi_df = pd.DataFrame() #臨時存放數據,打工的 chi_df['name1'] = [list(main_people.columns)[i]] #記住要lis,不能是string chi_df['name2'] = [list(main_people.columns)[j]] chi_result = pc.chi_test(main_people.iloc[:,i].values,main_people.iloc[:,j].values) chi_df['chi_value'] = [chi_result['Value']] chi_df['chi_p'] = [chi_result['Prob']] chi_df['chi_DF'] = [chi_result['DF']] chi_df['chi_LLP'] = [chi_result['LLP']] chi_df_1 = chi_df_1.append(chi_df) chi_df_1
