為什么要叫“卡方”?因為原名是“chi-squared”,一半是音譯,一半是意譯。其中,chi 是希臘字母 的讀音,其實讀音更像是“開”,而不是“卡”。square表示平方,因此在英語中,卡方分布寫作 distribution。
成都創(chuàng)新互聯(lián)公司是一家以網(wǎng)絡(luò)技術(shù)公司,為中小企業(yè)提供網(wǎng)站維護、網(wǎng)站設(shè)計、做網(wǎng)站、網(wǎng)站備案、服務(wù)器租用、域名注冊、軟件開發(fā)、小程序設(shè)計等企業(yè)互聯(lián)網(wǎng)相關(guān)業(yè)務(wù),是一家有著豐富的互聯(lián)網(wǎng)運營推廣經(jīng)驗的科技公司,有著多年的網(wǎng)站建站經(jīng)驗,致力于幫助中小企業(yè)在互聯(lián)網(wǎng)讓打出自已的品牌和口碑,讓企業(yè)在互聯(lián)網(wǎng)上打開一個面向全國乃至全球的業(yè)務(wù)窗口:建站服務(wù)電話:028-86922220
在理解卡方檢驗之前,應(yīng)當理解卡方分布??ǚ椒植际且环N連續(xù)概率分布。
如果一個隨機變量 服從標準正態(tài)分布,即 ,那么 就服從自由度為1的卡方分布。記作 或者
而如果 都服從標準正態(tài)分布,那么它們的平方和服從自由度為 的卡方分布,記作:
或者寫作 。
對于非負自變量 的自由度為 的卡方分布的概率密度函數(shù) (簡稱"pdf"):
(1)為什么 非負?因為根據(jù)定義,卡方分布的自變量是一個平方和。
(2)這里的 是一個函數(shù)。關(guān)于這個函數(shù)具體是什么,以及上門的概率密度函數(shù)如何推導(dǎo),這里不展開,只需要知道有這么個函數(shù)即可。實在是好奇的,可以 參考這里 。
(3)卡方分布的均值為 ,而標準差為 。
(4)自由度越大,該函數(shù)圖像越對稱。
(5)為什么這里 需要正態(tài)分布,我的理解是,如果零假設(shè)為真,那么觀測值和期望值之間的波動程度,應(yīng)該是正態(tài)分布的,或者說“噪聲”應(yīng)該是正態(tài)分布的。
卡方檢驗有兩個用途:
擬合優(yōu)度檢驗 chi-squared test goodness of fit
獨立性檢驗 chi-squared test of independence
某新聞?wù)f某個籃球明星的原地兩連投的單次命中率是0.8,根據(jù)歷次比賽的數(shù)據(jù)匯總得到下面的表格:
意思是說,在比賽中,有5次兩連投是一次都沒中,有82次是在兩連投中命中1次。現(xiàn)在,我們來用卡方檢驗驗證新聞?wù)f的0.8的命中率是否正確。零假設(shè)如下:
:兩連投的成功次數(shù)符合二項分布,且概率為
(1)先根據(jù)零假設(shè)計算“期望”的命中次數(shù)分布:
由于總的觀察次數(shù)為 ,于是在 成立的前提下,可以計算每種兩連投結(jié)果的期望次數(shù):
0次命中:
1次命中:
2次命中:
顯然,期望的觀察次數(shù)和實際的觀察次數(shù)是有偏差的,那么問題在于這個偏差是否大到具有統(tǒng)計顯著性,進而可以否定零假設(shè)。
(2)我們來構(gòu)造卡方檢驗統(tǒng)計量(chi-squared test statistic):
這個值是把表里每個格子的實際值和期望值進行對比。為什么要用平方?目的在于規(guī)避正負號的影響。為什么要除以期望值?目的在于消除數(shù)量絕對值的影響。例如你預(yù)算3塊錢的水,商家加價50元,那么這個波動是你無法忍受的,而你預(yù)算20萬的車,商家加價50元,則變得可以忍受。也就是說,除以期望值目的在于聚焦于變化率,而不是變化量。
之后,把這些“變化率”加總得到 。而計算自由度有一個公式:
其中 R 表示行數(shù),C 表示列數(shù)。對于本例:
從另一個角度解釋為什么 :前面的定義是如果是 個符合標準正態(tài)分布的 相加,則自由度是 ,但是這里自有兩個格子可以自由變化,第三個格子可以用總觀察數(shù)減出來,例如 。
因此,真正自由的只有2個格子,所以自由度是2。
好了,將格子的數(shù)據(jù)代入,求出檢驗統(tǒng)計量:
(3)根據(jù)自由度為2的卡方分布,找到檢驗統(tǒng)計量對應(yīng)的位置:
不難理解,隨著統(tǒng)計量增大,表示預(yù)期的分布和實際的分布的差異也就越來越大。
另外,由于通常意義上,p值是越小越能推翻零假設(shè),那么顯然我們需要用右側(cè)的面積來表示p值,這里用Python計算來代替查表:
輸出:statistic: 17.26, pvalue: 0.0002
由于p值很?。僭O(shè)我們的顯著性水平的0.05),那么我們可以推翻零假設(shè)。
進一步的,我們來探索下,該運動員的兩連投的成功次數(shù)分數(shù)是否真的符合二項分布。零假設(shè):
:兩連投的成功次數(shù)符合二項分布。
既然符合二項分布,那么我們需要先估算一下最合理的 概率,那當然是用總命中數(shù)除以總投籃數(shù)來計算了:
然后,用該概率值重復(fù)之前的計算,也就是先計算出一個期望的表格:
注意,這里的 ,這是因為,我們每從數(shù)據(jù)估計一個參數(shù),那么我們就損失一個自由度。這里用了一個平均命中的概率,因此自由度只有 。
這時候,在使用 Python 進行計算時,注意調(diào)整默認的自由度:
這里的 ddof 就是額外損失的自由度,本意是“delta degree of freedom”
輸出:statistic: 0.34, pvalue: 0.56
可以看到p值很大,因此不足以推翻零假設(shè),也就是說該運動員的投籃命中次數(shù)可能真的是二項分布。
下面表格表示喝酒頻率和與警察發(fā)生麻煩的頻數(shù)。
以第一列為例,表示從不喝酒的人中,4992人不發(fā)生麻煩,71人會發(fā)生麻煩。
現(xiàn)在的問題是,能否從以下數(shù)據(jù)推斷說喝酒頻率和與警察發(fā)生麻煩這兩個事件相互獨立?
我們的零假設(shè)應(yīng)該如何設(shè)計?如果要說明兩者相互獨立,那么上表的分布應(yīng)該滿足乘法公式。也就是說兩個獨立事件一起發(fā)生的概率等于分別發(fā)生的概率之積。
于是我們有:
發(fā)生麻煩的總?cè)藬?shù)除以總?cè)藬?shù)
不喝酒的總?cè)藬?shù)除以總?cè)藬?shù)
進一步,根據(jù)總?cè)藬?shù)算出不喝酒而發(fā)生麻煩的人數(shù)的期望(下標表示零假設(shè)):
用類似的算法,計算每一個格子在零假設(shè)成立的情況下的值,寫在原表數(shù)據(jù)下的括號里:
仔細觀察可以看出,其實每個格子就是對應(yīng)的:
另外可以看到,零假設(shè)下的各個格子的行列之和與原來相同。這不是偶然的,我們用字母代替計算一下就知道了:
于是第一列的兩個格子應(yīng)該是:
對于其他格子、行的總和,都一樣,這里不多說了。
好,繼續(xù)分析。我們直接用上表計算卡方統(tǒng)計量和p值:
這部分計算方法和擬合優(yōu)度是一樣的,就不贅述了。計算發(fā)現(xiàn)這個p值非常小,接近0,因此我們可以推翻零假設(shè)。也就是說,喝酒的頻率和被警察找麻煩的并不是獨立的,而是相關(guān)的。
關(guān)于獨立性檢驗,有一個比卡方檢驗更精準的檢驗,叫 fisher's exact test。它通過直接計算否定零假設(shè)的概率,也就直接得到了一個準確的p值。有一個經(jīng)典的女士品茶的統(tǒng)計學(xué)故事。有一個女士號稱可以區(qū)分出一杯茶是先倒入了奶還是先倒入了茶。統(tǒng)計學(xué)家 Fisher 為了驗證她的說法,做了一個實驗。拿了8杯茶,4杯是先茶后奶,4杯是先奶后茶。
實驗結(jié)果是全部說對了。那么問題是,這是否具有統(tǒng)計顯著性呢?比如說一個人猜對了一次硬幣,他的預(yù)測能力靠譜嗎?
我們假設(shè)女士的判斷是完全隨機的,這個是我們的零假設(shè)。那么8杯里面抽中4杯全對的概率是:
如果顯著性水平是0.01,那么我們不能推翻零假設(shè),即不敢確定這位女士真有這個識別能力。如果顯著性水平定在0.05,則我們可以認為她確實有這個識別能力。
如果讓實驗結(jié)果有更大的說服力呢?一個簡單的辦法就是增加茶的數(shù)量,比如我們設(shè)定為兩種茶各10杯,要求10杯都判斷正確,那么p值為多少呢?
這個算起來比較麻煩,這里我寫一個 python 腳本來計算:
計算結(jié)果:
這個p值就小得很夸張了,基本可以斷定零假設(shè)不成立了。
那么,回到實驗本身,如果女士只選對了三杯,那么在零假設(shè)的前提下,這個發(fā)生的概率是多少?
這個概率比較大了,原大于通常使用的顯著性水平 0.05,因此我們沒有辦法推翻零假設(shè)。為什么要這樣 乘 呢?這個是因為一共有這么多種取法。你把所有可能的取法羅列處理,就是16種,然后除以總的取法數(shù),就是隨機取到這樣結(jié)果的概率。
比較 Fisher's exact test 和 chi-squared test,可以 參考這篇文章 。
一般來說,兩者都適用的情況下,應(yīng)該優(yōu)先選擇 Fisher's exact test,因為它是精確值。如果實驗觀察的數(shù)量很?。ㄐ∮?0),應(yīng)該不使用 chi-squared test。
下面使用一個腳本來計算:
python可以對大數(shù)據(jù)進行卡方檢驗
需要澄清兩點之后才可以比較全面的看這個問題:
1. 百萬行級不算大數(shù)據(jù)量,以目前的互聯(lián)網(wǎng)應(yīng)用來看,大數(shù)據(jù)量的起點是10億條以上。
2. 處理的具體含義,如果是數(shù)據(jù)載入和分發(fā),用python是很高效的;如果是求一些常用的統(tǒng)計量和求一些基本算法的結(jié)果,python也有現(xiàn)成的高效的庫,C實現(xiàn)的和并行化的;如果是純粹自己寫的算法,沒有任何其他可借鑒的,什么庫也用不上,用純python寫是自討苦吃。
python的優(yōu)勢不在于運行效率,而在于開發(fā)效率和高可維護性。針對特定的問題挑選合適的工具,本身也是一項技術(shù)能力。
創(chuàng)建結(jié)構(gòu)元素: clear;close all SE = strel('rectangle',[40 30]); %注意:結(jié)構(gòu)元素必須具有適當?shù)拇笮?既可以刪電流線又可以刪除矩形.
def calc_chiSquare(sampleSet, feature, target):
'''
計算某個特征每種屬性值的卡方統(tǒng)計量
params:
? ? sampleSet: 樣本集
? ? feature: 目標特征
? ? target: 目標Y值 (0或1) Y值為二分類變量
return:
? ? 卡方統(tǒng)計量dataframe
? ? feature: 特征名稱
? ? act_target_cnt: 實際壞樣本數(shù)
? ? expected_target_cnt:期望壞樣本數(shù)
? ? chi_square:卡方統(tǒng)計量
'''
# 計算樣本期望頻率
target_cnt = sampleSet[target].sum()
sample_cnt = len(sampleSet[target])
expected_ratio = target_cnt * 1.0/sample_cnt
# 對變量按屬性值從大到小排序
df = sampleSet[[feature, target]]
col_value = list(set(df[feature]))?
# 計算每一個屬性值對應(yīng)的卡方統(tǒng)計量等信息
chi_list = []; target_list = []; expected_target_list = []
for value in col_value:
? ? df_target_cnt = df.loc[df[feature] == value, target].sum()
? ? df_cnt = len(df.loc[df[feature] == value, target])
? ? expected_target_cnt = df_cnt * expected_ratio
? ? chi_square = (df_target_cnt - expected_target_cnt)**2 / expected_target_cnt
? ? chi_list.append(chi_square)
? ? target_list.append(df_target_cnt)
? ? expected_target_list.append(expected_target_cnt)
# 結(jié)果輸出到dataframe, 對應(yīng)字段為特征屬性值, 卡方統(tǒng)計量, 實際壞樣本量, 期望壞樣本量
chi_stats = pd.DataFrame({feature:col_value, 'chi_square':chi_list,
? ? ? ? ? ? ? ? ? ? ? ? ? 'act_target_cnt':target_list, 'expected_target_cnt':expected_target_list})
return chi_stats[[feature, 'act_target_cnt', 'expected_target_cnt', 'chi_square']]
def chiMerge_maxInterval(chi_stats, feature, maxInterval=5):
'''
卡方分箱合并--最大區(qū)間限制法
params:
? ? chi_stats: 卡方統(tǒng)計量dataframe
? ? feature: 目標特征
? ? maxInterval:最大分箱數(shù)閾值
return:
? ? 卡方合并結(jié)果dataframe, 特征分割split_list
'''
group_cnt = len(chi_stats)
split_list = [chi_stats[feature].min()]
# 如果變量區(qū)間超過最大分箱限制,則根據(jù)合并原則進行合并
while(group_cnt maxInterval):
? ? min_index = chi_stats[chi_stats['chi_square']==chi_stats['chi_square'].min()].index.tolist()[0]
? ? # 如果分箱區(qū)間在最前,則向下合并
? ? if min_index == 0:
? ? ? ? chi_stats = merge_chiSquare(chi_stats, min_index+1, min_index)
? ? # 如果分箱區(qū)間在最后,則向上合并
? ? elif min_index == group_cnt-1:
? ? ? ? chi_stats = merge_chiSquare(chi_stats, min_index-1, min_index)
? ? # 如果分箱區(qū)間在中間,則判斷與其相鄰的最小卡方的區(qū)間,然后進行合并
? ? else:
? ? ? ? if chi_stats.loc[min_index-1, 'chi_square'] chi_stats.loc[min_index+1, 'chi_square']:
? ? ? ? ? ? chi_stats = merge_chiSquare(chi_stats, min_index, min_index+1)
? ? ? ? else:
? ? ? ? ? ? chi_stats = merge_chiSquare(chi_stats, min_index-1, min_index)
? ? group_cnt = len(chi_stats)
chiMerge_result = chi_stats
split_list.extend(chiMerge_result[feature].tolist())
return chiMerge_result, split_list
def chiMerge_minChiSquare(chi_stats, feature, dfree=4, cf=0.1, maxInterval=5):
'''
卡方分箱合并--卡方閾值法
params:
? ? chi_stats: 卡方統(tǒng)計量dataframe
? ? feature: 目標特征
? ? maxInterval: 最大分箱數(shù)閾值, default 5
? ? dfree: 自由度, 最大分箱數(shù)-1, default 4
? ? cf: 顯著性水平, default 10%
return:
? ? 卡方合并結(jié)果dataframe, 特征分割split_list
'''
threshold = get_chiSquare_distuibution(dfree, cf)
min_chiSquare = chi_stats['chi_square'].min()
group_cnt = len(chi_stats)
split_list = [chi_stats[feature].min()]
# 如果變量區(qū)間的最小卡方值小于閾值,則繼續(xù)合并直到最小值大于等于閾值
while(min_chiSquare threshold and group_cnt maxInterval):
? ? min_index = chi_stats[chi_stats['chi_square']==chi_stats['chi_square'].min()].index.tolist()[0]
? ? # 如果分箱區(qū)間在最前,則向下合并
? ? if min_index == 0:
? ? ? ? chi_stats = merge_chiSquare(chi_stats, min_index+1, min_index)
? ? # 如果分箱區(qū)間在最后,則向上合并
? ? elif min_index == group_cnt-1:
? ? ? ? chi_stats = merge_chiSquare(chi_stats, min_index-1, min_index)
? ? # 如果分箱區(qū)間在中間,則判斷與其相鄰的最小卡方的區(qū)間,然后進行合并
? ? else:
? ? ? ? if chi_stats.loc[min_index-1, 'chi_square'] chi_stats.loc[min_index+1, 'chi_square']:
? ? ? ? ? ? chi_stats = merge_chiSquare(chi_stats, min_index, min_index+1)
? ? ? ? else:
? ? ? ? ? ? chi_stats = merge_chiSquare(chi_stats, min_index-1, min_index)
? ? min_chiSquare = chi_stats['chi_square'].min()
? ? group_cnt = len(chi_stats)
chiMerge_result = chi_stats
split_list.extend(chiMerge_result[feature].tolist())
return chiMerge_result, split_list
def get_chiSquare_distuibution(dfree=4, cf=0.1):
'''
根據(jù)自由度和置信度得到卡方分布和閾值
params:
? ? dfree: 自由度, 最大分箱數(shù)-1, default 4
? ? cf: 顯著性水平, default 10%
return:
? ? 卡方閾值
'''
percents = [0.95, 0.90, 0.5, 0.1, 0.05, 0.025, 0.01, 0.005]
df = pd.DataFrame(np.array([chi2.isf(percents, df=i) for i in range(1, 30)]))
df.columns = percents
df.index = df.index+1
# 顯示小數(shù)點后面數(shù)字
pd.set_option('precision', 3)
return df.loc[dfree, cf]
def merge_chiSquare(chi_result, index, mergeIndex, a = 'expected_target_cnt',
? ? ? ? ? ? ? ? b = 'act_target_cnt', c = 'chi_square'):
'''
params:
? ? chi_result: 待合并卡方數(shù)據(jù)集
? ? index: 合并后的序列號
? ? mergeIndex: 需合并的區(qū)間序號
? ? a, b, c: 指定合并字段
return:
? ? 分箱合并后的卡方dataframe
'''
chi_result.loc[mergeIndex, a] = chi_result.loc[mergeIndex, a] + chi_result.loc[index, a]
chi_result.loc[mergeIndex, b] = chi_result.loc[mergeIndex, b] + chi_result.loc[index, b]
chi_result.loc[mergeIndex, c] = (chi_result.loc[mergeIndex, b] - chi_result.loc[mergeIndex, a])**2 /chi_result.loc[mergeIndex, a]
chi_result = chi_result.drop([index])
chi_result = chi_result.reset_index(drop=True)
return chi_result
for col in bin_col:
chi_stats = calc_chiSquare(exp_f_data_label_dr, col, 'label')
chiMerge_result, split_list = chiMerge_maxInterval(chi_stats, col, maxInterval=5)
print(col, 'feature maybe split like this:', split_list)
名稱欄目:卡方檢驗python函數(shù) 卡方檢驗命令
文章來源:http://jinyejixie.com/article4/dossdoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、網(wǎng)站排名、網(wǎng)站建設(shè)、App開發(fā)、動態(tài)網(wǎng)站、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)