克萊姆V(克萊姆相關係數、克萊姆關聯繫數、獨立係數)的MATLAB計算

        前些時間需要衡量多個分類數據之間兩兩相關程度,想找出最相關的一對分類數據;於是想到了曾經看過的克萊姆相關係數,但在網上搜了好久之後,即沒發現Matlab現成的built-in函數,也沒找到別人分享的Matlab代碼,於是決定自己動手寫一個~

        克萊姆V(Cramer’s V),又稱爲克萊姆相關係數、克萊姆關聯繫數、獨立係數等,是雙變量相關分析的一種方法,專門用於衡量分類數據與分類數據之間相關程度。該係數取值範圍爲0到1,0表示兩個變量無關,1表示完全相關。

        這裏主要參考【高橋 信/著, 陳剛/譯. 漫畫統計學. 科學出版社, 2009: 127-142.】中的內容,基於matlab實現計算克萊姆V的函數。首先給出函數代碼:

function [ cramer_V ] = CramersV( x1,x2 )
%Author: https://blog.csdn.net/jbb0523
%Version: 1.0@2019-05-27
%Description: compute variable Cramer's V between x1&x2
%Reference: 高橋 信/著, 陳剛/譯. 漫畫統計學. 科學出版社, 2009: 127-142.
    %Step 1: Observed frequency(contigency table )
    sym_x1 = unique(x1);
    sym_x2 = unique(x2);
    contigency_tab = zeros(length(sym_x1),length(sym_x2));
    for i=1:length(sym_x1)
        for j=1:length(sym_x2)
            ind_x1 = (x1==sym_x1(i));
            ind_x2 = (x2==sym_x2(j));
            contigency_tab(i,j) = sum(ind_x1&ind_x2);
        end
    end

    %Step 2: Expected frequency
    contigency_mean = zeros(length(sym_x1),length(sym_x2));
    for i=1:length(sym_x1)
        for j=1:length(sym_x2)
            contigency_mean(i,j) = sum(contigency_tab(i,:))*sum(contigency_tab(:,j))/sum(contigency_tab(:));
        end
    end

    %Step 3&4: Pearson chi-square statistic
    chi_square = sum(sum(((contigency_tab - contigency_mean).^2)./contigency_mean));

    %Step 5: Cramer's V
    cramer_V = sqrt(chi_square/sum(contigency_tab(:))/(min(length(sym_x1),length(sym_x2))-1));
end

整個計算過程其實很簡單,這裏簡要解釋一下:

        Step1對應於Reference中的步驟1(P130),即計算列聯表(contingency table),也就是下圖中框內的數據:

        Step2對應於Reference中的步驟2(P130),計算期望次數,方框內的每個元素實際上就是第1步列聯表對應的該行元素之和乘以該列元素之和再除以所有元素之和(例如女性行、打電話列爲148*72/300,148爲女性行元素之和(34+61+53),72爲打電話列元素之和(34+38),300爲所有元素之和(34+61+53+38+40+74)):

        接下來計算皮爾森卡方統計量之值,在Reference中分兩步完成,這裏合二爲一:

其中((contigency_tab - contigency_mean).^2)./contigency_mean對應於Reference中的步驟3(P131):

        然後用兩層sum求和實現計算矩陣元素之和,即Reference步驟4(P132):

        最後一行計算Cramer’s V,這裏計算列聯表元素之和用sum(contigency_tab(:))實現,其中(:)表示將矩陣變爲一個向量,即步驟5(P133):

有了以上函數之後,可以執行以下三行代碼計算Reference中第127~133頁的例子:

x1 = [ones(148,1);2*ones(152,1)];
x2 = [ones(34,1);2*ones(61,1);3*ones(53,1);ones(38,1);2*ones(40,1);3*ones(74,1)];
cramer_V= CramersV(x1,x2)

程序輸出爲0.1634,說明程序是正確的。

 

        Reference的第138頁還有一個例題,列聯表如下:

執行以下三行代碼:

x1=[ones(43,1);2*ones(51,1);3*ones(29,1);ones(33,1);2*ones(53,1);3*ones(41,1)];
x2=[ones(123,1);2*ones(127,1)];
cramer_V= CramersV(x1,x2)

程序輸出爲0.1157,與Reference第141頁給出的結果相同。

 

        注意:以上均使用1、2、3等表示分類數據中的類別,具體問題隨意,只要輸入的x1和x2是兩個包含有限類別個數的向量即可,至於用哪個數據表示哪個類別並沒有限制,因爲在最開始給出的CramersV函數裏使用了Matlab的built-in函數unique來識別包含哪些類別。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章