1. 程式人生 > 實用技巧 >卡方檢驗(兩個類別變數是否獨立)以及chi2_contingency

卡方檢驗(兩個類別變數是否獨立)以及chi2_contingency

百度百科的解釋:

卡方檢驗:

就是用來驗證兩個類別變數是否獨立,還是相關

就是統計樣本的實際觀測值與理論推斷值之間的偏離程度,實際觀測值與理論推斷值之間的偏離程度就決定卡方值的大小,如果卡方值越大,二者偏差程度越大;反之,二者偏差越小;若兩個值完全相等時,卡方值就為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