白話「卡方檢驗」

什麼是卡方檢驗

卡方檢驗是假設檢驗的一種,用於分析兩個類別變量的相關關係,是一種非參數假設檢驗,得出的結論無非就是相關或者不相關,因此有的教材上又叫「獨立性檢驗」,因此若是不是很清楚假設檢驗的朋友們,要好好複習一下假設檢驗了。提起假設檢驗,會扯出一堆東西,這裏我簡單爲你們梳理一下。python

什麼是「類別變量」?

類別變量就是取值爲離散值的變量,「性別」就是一個類別變量,它的取值只有「男」和「女」,相似還有」婚否「、」國籍「等。面試

什麼是「分析兩個類別變量的相關關係」

卡方檢驗用於分析兩個類別變量的相關關係,這是什麼意思呢?以咱們熟知的 Kaggle 平臺上的泰坦尼克號倖存者預測提供的數據爲例,」性別「對於」是否倖存「的關係研究,就屬於這方面的內容。研究代表,泰坦尼克號上的乘客秉承」女士優先,照顧弱勢羣體「的基本原則,所以女性倖存的機率比男性要大,這就說明,」性別「對於」是否倖存「有相關關係,咱們後面會使用卡方檢驗來驗證這一事實。app

假設檢驗

假設檢驗,顧名思義,就是提出一個假設,而後檢驗你提出的假設是否正確。假設檢驗的流程實際上是固定的,關鍵其實在於理解假設檢驗的設計原則。函數

什麼是假設?

那麼咱們假設什麼呢?這裏就要引入「原假設」和「備擇假設」的概念了,「原假設」是「備擇假設」的對立面。下面這個原則很重要:測試

備擇假設一般是研究者想收集證據予以支持的假設。原假設是研究者想收集證據予以推翻的假設。spa

重要的事情,我再寫兩遍:若是你想經過種種論證,證實一件事情,就要把這件事情寫成「備擇假設」。備擇假設一般用於表達研究者本身傾向於支持的見解(這很主觀),而後就是想辦法收集證據拒絕原假設,以支持備擇假設設計

特別要說明的一點是:若是你不遵照這個「原假設」和「備擇假設」設計的基本原則,你極可能會獲得相反的結論。code

假設檢驗很像司法界對於一個事實的認定,本着「疑罪從無」的原則,若是你要說明一我的有罪,你必須提供充足的證據,不然被告人的罪名就不能成立,這個說法叫「沒有充分的證據證實被告有罪」。blog

所以,若是咱們最後的結論是「原假設」成立,咱們通常不這麼說,即咱們不說「原假設」成立,咱們不說「原假設」是真的。咱們說不能拒絕「原假設」,或者說沒有充分的證據拒絕「原假設」,或者說沒有充分的證據證實「備擇假設」成立教程

卡方檢驗的「原假設」與「備擇假設」

由於咱們作假設檢驗必定是以爲兩個類別變量有關係,纔去作檢驗。再想一想那個「疑罪從無」原則,咱們是以爲一我的有罪,纔去舉證。所以卡方檢驗的「原假設」必定是假設獨立,「備擇假設」必定是假設相關,即:

原假設:類別變量 \(A\) 與類別變量 \(B\) 獨立
備擇假設:類別變量 \(A\) 與類別變量 \(B\) 不獨立

這一點應該是極其明確的,咱們的統計軟件中都是這樣設定的。

如何檢驗?

作「檢驗」這件事情,就很像咱們之前作的「反證法」,咱們假定要證實的結論的對立面成立,而後推出矛盾,即說明了咱們的假設是錯誤的,即原命題成立。請看下面這個例子:

請你證實:這個餐廳的菜很難吃。
證實:假設這個餐廳的菜很好吃,那麼週末的晚上生意必定很好,然而實際觀察下來,顧客流量和平時同樣,推出矛盾,因此假設不成立,即這個餐廳的菜很難吃。

用假設檢驗的思路,在這個例子中:

原假設:這個餐廳的菜很好吃;
備擇假設:這個餐廳的菜很難吃。

咱們把傾向於要證實的結論設置爲「備擇假設」,而推理是基於「原假設」成立進行的,推理得出矛盾,說明「原假設」錯誤,從錯誤的起點推出了錯誤的結論,所以「原假設」不成立,這就是假設檢驗裏面說的「拒絕原假設」。

所以,檢驗其實很簡單,就是一個是非論證的過程,是單選題,只有兩個選項,選擇其一。

假設檢驗如何論證

假設檢驗的論證實際上是固定的,就是基於「小几率事件在一次試驗中幾乎不可能發生」,一般,咱們獲得的矛盾就在於:

經過計算統計量,發現經過一次試驗獲得這個統計量是一個「小几率事件」,「小几率事件」在一次試驗中,竟然發生了,咱們就認爲這是很「詭異」的,必定是以前的某個環節出了問題,即「原假設」不成立,因而拒絕「原假設」,即證實了「備擇假設」成立。

爲何叫「卡方檢驗」,何爲「卡方檢驗」?

「卡方分佈」(也寫做 「\(\chi^2 分佈\)」)是統計學領域的三大分佈之一,另外兩個分佈是「\(t\) 分佈」與「\(F\) 分佈」,這些分佈都是由正態分佈推導出來的,能夠認爲它們是咱們熟知的分佈,由於它們能夠取哪些值,以及取這些值的機率都是徹底弄清楚了的。

統計學的研究任務是經過樣本研究整體,由於咱們沒法把全部的整體都作一次測試,通常可行的作法就是從整體中抽取一部分數據,根據對這一部分數據的研究,推測整體的一些性質。

而「三大分佈」就是咱們研究樣本的時候選取的參照物。通常咱們研究的思路是這樣的:若是通過分析,得出待研究的樣本符合這些咱們已知的分佈之一,由於三大分佈是被咱們的統計學家徹底研究透了的,能夠認爲是無比正確的,就能夠經過查表獲得這些分佈的信息,進而獲得樣本的一些性質,幫助咱們決策。

這裏舉一個例子,好比你是一個面試官,你手上掌握着「北京」、「上海」、「廣州」三個省市的人才信息庫(至關於上面咱們說的統計學的三大分佈),來了一個面試者,從簡歷中得知這我的來自「北京」,那麼咱們就能夠直接從「北京」市的人才信息庫中查閱到他的詳細履歷,掌握到他更全面的信息。

作假設檢驗的時候,咱們也是相似的思路,咱們須要利用整體的樣本構造出合適的統計量(或樞軸量),並使其服從或近似地服從已知的肯定分佈,這樣咱們就能夠查閱這些肯定分佈的相關信息,獲得待研究樣本所反映出來的整體的一些性質。

上面說到了「統計量」和「樞軸量」,下面簡單談一談。

統計量:不含整體分佈未知參數的函數稱爲樣本的統計量。

統計量常常做爲一個樣本的表明,例如平均數、衆數、最大值、最小值,統計量由多個數映射成一個數。

樞軸量:僅含有一個未知參數,而且分佈已知的樣本的函數,稱爲樞軸量。

樞軸量的思想其實就是解方程,或者說解不等式,這一部分很是重要的理論基礎是「抽樣分佈定理」。若是忘記了的朋友們必定要翻翻之前的教程,「抽樣分佈定理」是很是重要的。根據抽樣分佈定理,咱們常常是這樣用的:樣本的某個含有未知參數的函數符合某個已知分佈,已知分佈能夠查表,所以未知參數的性質就知道了。求「置信區間」與作「假設檢驗」一般就是這樣的思路。

卡方檢驗的統計量

\[ \chi^2=\sum\sum \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(犯罪) \times P(離異家庭) = \cfrac{450}{990} \times \cfrac{216}{990} \]

\[ P(「犯罪」而且「和氣家庭」) = P(犯罪) \times P(和氣家庭) = \cfrac{450}{990} \times \cfrac{774}{990} \]

\[ P(「未犯罪」而且「離異家庭」) = P(犯罪) \times P(離異家庭) = \cfrac{540}{990} \times \cfrac{216}{990} \]

\[ P(「未犯罪」而且「離異家庭」) = P(犯罪) \times P(離異家庭) = \cfrac{540}{990} \times \cfrac{774}{990} \]

咱們要計算指望頻數,就把上面這 \(4\) 個機率分別乘以樣本總數 \(990\) 就能夠了:

青少年行爲\家庭情況 離異家庭 和氣家庭
犯罪 \(450\times \frac{216}{990} \approx 98.18\) \(450 \times \frac{774}{990} \approx 351.82\)
未犯罪 \(540 \times \frac{216}{990} \approx 117.82\) \(540 \times \frac{774}{990} \approx 422.18\)

下面將每一個單元格的 \(\frac{(f_o-f_e)^2}{f_e}\) 加起來,就能夠獲得 \(\chi^2\) 統計量:

\[ \begin{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)\times (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()

獲得圖像以下:

Figure_1.png

能夠看到,\(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\),那麼看圖:

Figure_1.png

這個時候,統計量取 \(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]]))
相關文章
相關標籤/搜索