白话“卡方检验”
什么是卡方檢驗
卡方檢驗是假設檢驗的一種,用于分析兩個類別變量的相關關系,是一種非參數假設檢驗,得出的結論無非就是相關或者不相關,所以有的教材上又叫“獨立性檢驗”,所以如果不是很清楚假設檢驗的朋友們,要好好復習一下假設檢驗了。提起假設檢驗,會扯出一堆東西,這里我簡單為大家梳理一下。
什么是“類別變量”?
類別變量就是取值為離散值的變量,“性別”就是一個類別變量,它的取值只有“男”和“女”,類似還有”婚否“、”國籍“等。
什么是“分析兩個類別變量的相關關系”
卡方檢驗用于分析兩個類別變量的相關關系,這是什么意思呢?以我們熟知的 Kaggle 平臺上的泰坦尼克號幸存者預測提供的數據為例,”性別“對于”是否幸存“的關系研究,就屬于這方面的內容。研究表明,泰坦尼克號上的乘客秉承”女士優先,照顧弱勢群體“的基本原則,因此女性幸存的概率比男性要大,這就說明,”性別“對于”是否幸存“有相關關系,我們后面會使用卡方檢驗來驗證這一事實。
假設檢驗
假設檢驗,顧名思義,就是提出一個假設,然后檢驗你提出的假設是否正確。假設檢驗的流程其實是固定的,關鍵其實在于理解假設檢驗的設計原則。
什么是假設?
那么我們假設什么呢?這里就要引入“原假設”和“備擇假設”的概念了,“原假設”是“備擇假設”的對立面。下面這個原則很重要:
備擇假設通常是研究者想收集證據予以支持的假設。原假設是研究者想收集證據予以推翻的假設。
重要的事情,我再寫兩遍:如果你想通過種種論證,證明一件事情,就要把這件事情寫成“備擇假設”。備擇假設通常用于表達研究者自己傾向于支持的看法(這很主觀),然后就是想辦法收集證據拒絕原假設,以支持備擇假設。
特別要說明的一點是:如果你不遵守這個“原假設”和“備擇假設”設計的基本原則,你很可能會得到相反的結論。
假設檢驗很像司法界對于一個事實的認定,本著“疑罪從無”的原則,如果你要說明一個人有罪,你必須提供充足的證據,否則被告人的罪名就不能成立,這個說法叫“沒有充分的證據證明被告有罪”。
因此,如果我們最后的結論是“原假設”成立,我們一般不這么說,即我們不說“原假設”成立,我們不說“原假設”是真的。我們說不能拒絕“原假設”,或者說沒有充分的證據拒絕“原假設”,或者說沒有充分的證據證明“備擇假設”成立。
卡方檢驗的“原假設”與“備擇假設”
因為我們做假設檢驗一定是覺得兩個類別變量有關系,才去做檢驗。再想想那個“疑罪從無”原則,我們是覺得一個人有罪,才去舉證。因此卡方檢驗的“原假設”一定是假設獨立,“備擇假設”一定是假設相關,即:
原假設:類別變量 (A) 與類別變量 (B) 獨立
備擇假設:類別變量 (A) 與類別變量 (B) 不獨立
這一點應該是極其明確的,我們的統計軟件中都是這樣設定的。
如何檢驗?
做“檢驗”這件事情,就很像我們以前做的“反證法”,我們假定要證明的結論的對立面成立,然后推出矛盾,即說明了我們的假設是錯誤的,即原命題成立。請看下面這個例子:
請你證明:這個餐廳的菜很難吃。
證明:假設這個餐廳的菜很好吃,那么周末的晚上生意一定很好,然而實際觀察下來,顧客流量和平時一樣,推出矛盾,所以假設不成立,即這個餐廳的菜很難吃。
用假設檢驗的思路,在這個例子中:
原假設:這個餐廳的菜很好吃;
備擇假設:這個餐廳的菜很難吃。
我們把傾向于要證明的結論設置為“備擇假設”,而推理是基于“原假設”成立進行的,推理得出矛盾,說明“原假設”錯誤,從錯誤的起點推出了錯誤的結論,因此“原假設”不成立,這就是假設檢驗里面說的“拒絕原假設”。
因此,檢驗其實很簡單,就是一個是非論證的過程,是單選題,只有兩個選項,選擇其一。
假設檢驗如何論證
假設檢驗的論證其實是固定的,就是基于“小概率事件在一次試驗中幾乎不可能發生”,通常,我們得到的矛盾就在于:
通過計算統計量,發現通過一次試驗得到這個統計量是一個“小概率事件”,“小概率事件”在一次試驗中,居然發生了,我們就認為這是很“詭異”的,一定是之前的某個環節出了問題,即“原假設”不成立,于是拒絕“原假設”,即證明了“備擇假設”成立。
為什么叫“卡方檢驗”,何為“卡方檢驗”?
“卡方分布”(也寫作 “(chi^2 分布)”)是統計學領域的三大分布之一,另外兩個分布是“(t) 分布”與“(F) 分布”,這些分布都是由正態分布推導出來的,可以認為它們是我們熟知的分布,因為它們可以取哪些值,以及取這些值的概率都是完全弄清楚了的。
統計學的研究任務是通過樣本研究總體,因為我們無法把所有的總體都做一次測試,一般可行的做法就是從總體中抽取一部分數據,根據對這一部分數據的研究,推測總體的一些性質。
而“三大分布”就是我們研究樣本的時候選取的參照物。一般我們研究的思路是這樣的:如果經過分析,得出待研究的樣本符合這些我們已知的分布之一,因為三大分布是被我們的統計學家完全研究透了的,可以認為是無比正確的,就可以通過查表得到這些分布的信息,進而得到樣本的一些性質,幫助我們決策。
這里舉一個例子,比如你是一個面試官,你手上掌握著“北京”、“上海”、“廣州”三個省市的人才信息庫(相當于上面我們說的統計學的三大分布),來了一個面試者,從簡歷中得知這個人來自“北京”,那么我們就可以直接從“北京”市的人才信息庫中查閱到他的詳細履歷,掌握到他更全面的信息。
做假設檢驗的時候,我們也是類似的思路,我們需要利用總體的樣本構造出合適的統計量(或樞軸量),并使其服從或近似地服從已知的確定分布,這樣我們就可以查閱這些確定分布的相關信息,得到待研究樣本所反映出來的總體的一些性質。
上面說到了“統計量”和“樞軸量”,下面簡單談一談。
統計量:不含總體分布未知參數的函數稱為樣本的統計量。
統計量經常作為一個樣本的代表,例如平均數、眾數、最大值、最小值,統計量由多個數映射成一個數。
樞軸量:僅含有一個未知參數,并且分布已知的樣本的函數,稱為樞軸量。
樞軸量的思想其實就是解方程,或者說解不等式,這一部分非常重要的理論基礎是“抽樣分布定理”。如果忘記了的朋友們一定要翻翻以前的教程,“抽樣分布定理”是非常重要的。根據抽樣分布定理,我們經常是這樣用的:樣本的某個含有未知參數的函數符合某個已知分布,已知分布可以查表,因此未知參數的性質就知道了。求“置信區間”與做“假設檢驗”通常就是這樣的思路。
卡方檢驗的統計量
[chi^2=sumsum frac{(f_o-f_e)^2}{f_e}
]
說明:(f_o) 是觀測頻數(實際值),(f_e) 是期望頻數(可以認為是理論值),期望頻數的計算公式我們馬上會介紹到。這個統計量服從自由度為 ((r-1)(c-1)) 的 (chi^2) 分布,(r) 為行數,(c) 為列數。
這里一定要舉例才能說清楚了:
以下內容摘抄自中國人民大學龍永紅主編《概率論與數理統計》(第三版)P190 “獨立性檢驗”一節例 5.32。
研究青少年行為與家庭狀況的關系,調查結果如下:
| 青少年行為家庭狀況 | 離異家庭 | 和睦家庭 | 合計 |
|---|---|---|---|
| 犯罪 | (178) | (272) | (450) |
| 未犯罪 | (38) | (502) | (540) |
| 合計 | (216) | (774) | (990) |
分析:“青少年行為”是離散型變量,有“犯罪”與“未犯罪”兩個取值;“家庭狀況”是也離散型變量,有“離異家庭”與“和睦家庭”兩個取值,從直覺上,我們認為它們是相關的。因此
第 1 步:建立統計假設。
原假設:“青少年行為”與“家庭狀況”獨立。
備擇假設:“青少年行為”與“家庭狀況”不獨立。
第 2 步:計算期望頻數與檢驗統計量。
要計算出檢驗統計量,關鍵是計算出期望頻數。我們之前說到了,假設檢驗是基于原假設進行論證,因此,我們的期望頻數應該是基于【“青少年行為”與“家庭狀況”獨立】得到的。因此有:
兩個類別的交叉項的概率可以根據獨立事件的概率乘法公式得到。具體是這樣做的,從上面那張表中:
一行一行看,這 (990) 個青少年里,(P(犯罪)=cfrac{450}{990}),(P(未犯罪)=cfrac{540}{990});
一列一列看,這 (990) 個青少年里,(P(離異家庭)=cfrac{216}{990}),(P(和睦家庭)=cfrac{774}{990});
在【“青少年行為”與“家庭狀況”獨立】這個假設下有:
[P(“犯罪”并且“離異家庭”) = P(犯罪) imes P(離異家庭) = cfrac{450}{990} imes cfrac{216}{990}
]
[P(“犯罪”并且“和睦家庭”) = P(犯罪) imes P(和睦家庭) = cfrac{450}{990} imes cfrac{774}{990}
]
[P(“未犯罪”并且“離異家庭”) = P(犯罪) imes P(離異家庭) = cfrac{540}{990} imes cfrac{216}{990}
]
[P(“未犯罪”并且“離異家庭”) = P(犯罪) imes P(離異家庭) = cfrac{540}{990} imes cfrac{774}{990}
]
我們要計算期望頻數,就把上面這 (4) 個概率分別乘以樣本總數 (990) 就可以了:
| 青少年行為家庭狀況 | 離異家庭 | 和睦家庭 |
|---|---|---|
| 犯罪 | (450 imes frac{216}{990} approx 98.18) | (450 imes frac{774}{990} approx 351.82) |
| 未犯罪 | (540 imes frac{216}{990} approx 117.82) | (540 imes frac{774}{990} approx 422.18) |
下面將每個單元格的 (frac{(f_o-f_e)^2}{f_e}) 加起來,就可以得到 (chi^2) 統計量:
[egin{aligned}
chi^2 &= cfrac{(178-98.18)^2}{98.18} + cfrac{(272-351.82)^2}{351.82} + cfrac{(38-117.82)^2}{117.82} + cfrac{(502-422.18)^2}{422.18} \
& approx 64.89 + 18.11 + 54.06 + 15.09 \
& approx 152.15
end{aligned}
]
上面說服從自由度為 ((r-1)(c-1)) 的 (chi^2) 分布,(r) 為行數,(c) 為列數,即服從 ((2-1) imes (2-1) = 1) 的 (chi^2) 分布,接下來,我們就要看得到這個統計量的概率有多大:
from scipy import stats
import seaborn as sns
import matplotlib.pyplot as plt
samples = stats.chi2.rvs(size=10000, df=1)
sns.distplot(samples)
plt.title('$chi^2$,df=1')
plt.show()
得到圖像如下:
可以看到,(152.15) 都不在能圖像顯示到的范圍之內,說明這個概率很低。下面我們或者使用 Python 查一下,這個概率是多少:
from scipy import stats
stats.chi2.pdf(152.15, df=1)
得到:(2.956796099836173e-35),確實是一個幾乎為 (0) 的數。這說明了什么呢?
說明了,在我們的假設【“青少年行為”與“家庭狀況”獨立】下,得到這組觀測數據的概率很低很低,基于小概率事件在一次試驗中幾乎不會發生,但它卻發生了,就證明了我們的“原假設”是不正確的,即有充分證據決絕“原假設”。(這一部分有點繞,其實很簡單,多看幾遍就非常清楚了。)
其實到這里,我們對卡方檢驗就已經介紹完了,是不是覺得很簡單。但是在實際操作的過程中,我們還會引入 (p) 值,很多統計軟件也會幫我們計算出 (p) 值,這個 (p) 值是個什么鬼呢?下面先給出我的結論:
什么是 (p) 值?
(p) 值統一了假設檢驗的比較標準,把計算統計量的概率大小統一變成計算 (p) 值,如果這個 (p) 值小于一個預先設定好的數,我們稱之為“顯著性水平”,用 (alpha) 表示,一般取 (alpha = 0.05),則拒絕原假設,如果 (p) 值大于“顯著性水平”,則說明沒有充分證據拒絕原假設。使用 (p) 值進行假設檢驗的時候,會更便利。因此,使用 (p) 值進行假設檢驗的評判標準就只要一個,就是記住這句話“小拒大接”,即比 (0.05) 小,就拒絕“原假設”,比 (0.05) 大,結論是“沒有理由拒絕原假設”。
特別說明:這個結論是我根據對 (p) 值的理解自己總結的,是人話,但不一定準確。
(p) 值在不同的檢驗問題中,計算方法會不同,在這里,我們就以卡方檢驗為例,如果我們計算出來的統計量的值為 (1),那么看圖:
這個時候,統計量取 (1) 的概率就很高了,從圖中可以看出大于 (0.2)。我們作如下分析:
(chi^2) 分布長尾在右邊,是個右偏分布,在 (0) 附近的概率是非常高的,我們要找一個臨界值,如果統計量取到這個臨界值,以及這個臨界值的右邊,我們認為這樣的事情發生的概率是很低的,這里就要借助累計概率和分位點的概念;
(說明:累計積分和分位點的概念都是十分重要的,在這里就不贅述了,讀者可以查閱相關統計學的教材。)
我們認為,在 (chi^2) 分布,如果一個點到右邊無窮的累計積分小于“顯著性水平”,我們就認為這個點以及右邊所有的點的取值,都是小概率事件。
于是,對于卡方檢驗而言,得到的統計量,我們可以計算這個從統計量到正無窮的積分,如果這個積分值小于“顯著性水平”,即認為這個統計量的概率一定在“顯著性水平”所確定的臨界點的右邊,即它是比“小概率事件”發生的概率還小的“小概率事件”。
下面,我們自己寫一個函數來實現卡方檢驗相關的計算,實現和 scipy 軟件包提供的卡方檢驗同樣的效果。
from scipy import stats
from scipy.stats import chi2_contingency
def custom_chi2_contingency(observed):
"""
自己編寫的卡方檢驗的函數,返回
"""
# 每一行求和
row = observed.sum(axis=1)
# 每一列求和
col = observed.sum(axis=0)
# 總數求和
all_sum = observed.sum()
# meshgrid 生成網格
x1, x2 = np.meshgrid(col, row)
# 期望頻數
expected_count = x1 * x2 / all_sum
# 統計量,即卡方值
chi2 = ((observed - expected_count)**2 / expected_count).sum()
# 自由度
df = (len(row) - 1) * (len(col) - 1)
# 計算 p 值,這里用到了卡方分布的概率積累函數,
# 因為這個 cdf 是計算從左邊到這點的累計積分,因此用 1 減它
p = 1 - stats.chi2.cdf(chi2, df=df)
return chi2, p, df, expected_count
下面驗證自定義函數的正確性:
obs = np.array([[178, 272], [38, 502]])
result1 = custom_chi2_contingency(obs)
result2 = chi2_contingency(obs)
print('自定義卡方檢驗的函數返回:')
print(result1)
print()
print('scipy 提供的卡方檢驗返回:')
print(result2)
顯示:
自定義卡方檢驗的函數返回:
(152.16271892047084, 0.0, 1, array([[ 98.18181818, 351.81818182],
[117.81818182, 422.18181818]]))
scipy 提供的卡方檢驗返回:
(150.2623232486362, 1.5192261812214016e-34, 1, array([[ 98.18181818, 351.81818182],
[117.81818182, 422.18181818]]))
總結
- 上一篇: 项目常用的PHP代码
- 下一篇: 怎么创建具有真实纹理的CG场景岩石?