实例讲解统计学基础知识(5):假设检验
作者:xxw9485
時間:2018/3/20
來源:https://www.jianshu.com/p/99fd951a0b8b
假設檢驗
推斷統計學一般有兩種方法,一是使用置信區間估算總體的參數,二是對總體參數的假設值進行決策。后者被稱為假設檢驗,是我們這篇文章所要探討的主題。
本文首先會介紹假設檢驗的邏輯,然后利用BRFSS數據探討富人是否更瘦這個問題,除了使用t檢驗方法外,還采用了蒙特卡洛模擬的方法來實現假設檢驗。
假設檢驗的邏輯
假設檢驗的邏輯有些類似于反證法,這里有原假設和備擇假設,它們之間是相互對立的,我們先在原假設成立的前提下進行計算,如果最終結果證明原假設不成立,我們就會接受備擇假設,所以一般我們也會將想要證明的結論作為備擇假設。
比如,在討論富人是否比普通人更瘦的問題上,原假設是:富人和普通人一般胖瘦;而備擇假設是:富人比普通人更瘦。然后我們通過實際的樣本數據,證明在原假設成立的前提下:如果得到現有樣本結果(甚至更極端的情況)的可能性微乎其微,以至于我們需要拒絕原假設而接受備擇假設;如果可能性在我們能夠接受的范圍內,我們則無法拒絕原假設。
假設檢驗一般有下面幾個步驟:
- 設置原假設和備擇假設。
- 定義檢驗統計量。
- 在原假設的基礎上,通過計算或模擬得到檢驗統計量和P值。
- 做判斷:如果P值小于你能容忍的顯著性水平時,則拒絕原假設。
這里的檢驗統計量是由樣本數據計算而來的,如果檢驗統計量的值出現在拒絕域中,則拒絕原假設。而一般我們會計算檢驗統計量出現在極端情況下的概率,也就是P值,并與事先設置的顯著性水平比較,如果P值更小,則意味著檢驗統計量處在拒絕域,需要拒絕原假設。
單個樣本均值的假設檢驗
在開始假設檢驗前,我們需要先導入相應的Python模塊和BRFSS數據,其中采用了scipy的stats統計模塊,它提供了假設檢驗計算P值的函數。
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import brfss from scipy import stats # 導入scipy的統計模塊df = brfss.ReadBrfss() # 讀取數據然后根據收入水平選取富人和普通人的bmi數據值。
df2 = df[['bmi', 'income']].dropna() bmi = df2.bmi bmi_rich = df2[df2.income == 8].bmi # 富人bmi數據 bmi_ord = df2[df2.income != 8].bmi # 普通人bmi數據我們需要判斷的問題是:富人會更瘦嗎?為了演示單個樣本的情況,這里只使用富人bmi數據和所有人總體bmi均值做比較。并假設總體的bmi均值等于樣本bmi均值,由于樣本量有40萬,根據中心極限定理可以做這樣的近似。
# 輸入 mu = np.mean(bmi) # 計算bmi均值 print(mu) # 輸出 28.18812531332513在只使用富人bmi數據的單樣本情況下,原假設為:富人bmi均值等于總體bmi均值28.188;備擇假設為:富人bmi均值小于總體bmi均值28.188,這是一個單邊檢驗。這里采用t檢驗,所以檢驗統計量為t統計量。
t檢驗一般用于變量滿足或近似正態分布且總體標準差未知的情況下,特別是在小樣本量的時候。但在大樣本情況下,t檢驗和z檢驗是近似的,因此也可使用t檢驗。在scipy.stats模塊中t檢驗的函數是ttest_1samp(),用于單個樣本和總體均值比較的情況。其返回結果是t統計量和P值。
# 輸入 t_stats, p_value = stats.ttest_1samp(bmi_rich, mu) print("p value is %.10f" % (p_value/2)) # 除以2是因為我們使用的是單邊檢驗 # 輸出 p value is 0.0000000000以上使用了所有富人的bmi數據,得到P值在目前的精度下為0,所以我們拒絕原假設,接受備擇假設,即得出結論:富人更瘦。如果我們只使用部分bmi數據,則會得到完全不一樣的結果。
# 輸入 t_stats, p_value = stats.ttest_1samp(bmi_rich[:500], mu) # 選擇前500個數據進行檢驗 print("p value is %.10f" % (p_value/2)) t_stats, p_value = stats.ttest_1samp(bmi_rich[:4000], mu) # 選擇前4000個數據進行檢驗 print("p value is %.10f" % (p_value/2)) # 輸出 p value is 0.2906513576 p value is 0.0000660545當選擇前500個數據進行t檢驗時,P值為0.29,而如果我們選擇的顯著性水平為0.1時,則無法拒絕原假設,但也不能證明原假設就成立。當選擇前4000個數據進行t檢驗,P值為0.000066, 顯著性水平為0.1時,則可以拒絕原假設。所以樣本量越大,你得到的結果越明確。
蒙特卡洛模擬之 bootstrap 方法
以上直接采用了t檢驗,有時t檢驗的前提無法滿足,我們還可以采用計算機模擬的方法,常用的是bootstrap方法。
bootstrap是一種自助的方法,即在原有的樣本中進行可重復的重新抽樣,得到更多的樣本。因為我們先假設富人和普通人的bmi值沒有差別,所以從富人的樣本數據中進行重新抽樣,其實是模擬了普通人的樣本分布。然后將原富人樣本bmi均值與多個新樣本的bmi均值比較,從而計算出極端情況下的概率,即P值。以下是實現bootstrap方法的代碼。
def bootstrap_replicate_1d(data, func): # 進行一次重新抽樣,并返回檢驗統計量return func(np.random.choice(data, size=len(data))) def draw_bs_reps(data, func, size=1):bs_replicates = np.empty(size) # 初始一個空數組for i in range(size): # 進行多次重新抽樣bs_replicates[i] = bootstrap_replicate_1d(data, func) return bs_replicates # 返回多次抽樣的檢驗統計量數組def bootstrap_pvalue_1samp(data, pop_stats, func, size=1):sample_stats = func(data) # 計算原有樣本的檢驗統計量 translated_data = data - sample_stats + pop_stats # 數據平移bs_replicates = draw_bs_reps(translated_data, func, size) # 重新抽樣p = np.sum( bs_replicates < sample_stats) / size # 計算抽樣統計量小于原有統計量的概率return p同樣,我們使用三組不同大小的數據得到了不同的結果,在大樣本的情況下P值很小,需要拒絕原假設。
# 輸入 a = bootstrap_pvalue_1samp(bmi_rich, mu, np.mean, size=10000) b = bootstrap_pvalue_1samp(bmi_rich[:500], mu, np.mean, size=10000) c = bootstrap_pvalue_1samp(bmi_rich[:4000], mu, np.mean, size=10000) print(a) print(b) print(c) # 輸出 0.0 0.7112 0.0兩個獨立樣本均值的假設檢驗
現在我們討論兩個獨立樣本的情況,即使用富人bmi數據和普通人bmi數據。原假設為:富人和普通人的bmi均值相同;備擇假設為:富人bmi均值比普通人小,仍是單邊檢驗。同樣,我們采用t檢驗,使用scipy.stats中的ttest_ind()函數,計算兩個獨立樣本t檢驗的P值。
選擇顯著性水平為0.1時,當樣本量只有500時,P值大于0.1,無法拒絕原假設。而當樣本量為1000或全部時,P值小于0.1,拒絕原假設,證明了富人比普通人更瘦。
# 輸入 t_stats, p_value = stats.ttest_ind(bmi_rich, bmi_ord) print("p value is %.10f" % (p_value/2)) t_stats, p_value = stats.ttest_ind(bmi_rich[:500], bmi_ord[:500]) print("p value is %.10f" % (p_value/2)) t_stats, p_value = stats.ttest_ind(bmi_rich[:1000], bmi_ord[:1000]) print("p value is %.10f" % (p_value/2)) # 輸出 p value is 0.0000000000 p value is 0.1219871502 p value is 0.0000846839蒙特卡洛模擬之Permutation方法
同樣,在兩個獨立樣本的情況下,我們也可以采用計算機模擬的方法,這里介紹另一種Permutation的方法。
Permutation方法的邏輯是,在原假設成立的前提下,富人bmi和普通人bmi數據沒有區別,所以可以將它們混合重新洗牌,然后重新分成兩組數據,并計算這兩組新數據均值的差值,重復多次這一操作。然后再將原有富人和普通人bmi均值之差與這些新組合的差值進行比較,計算極端情況下的概率,如果概率很小,則推翻了無差別的原假設。以下是實現Permutation方法的代碼。
def diff_of_means(data_1, data_2): diff = np.mean(data_2) - np.mean(data_1) # 計算兩組數據均值的差return diffdef permutation_sample(data1, data2): # 產生新的分組數據data = np.concatenate((data1, data2)) # 合并兩組數據permuted_data = np.random.permutation(data) # 對合并后的數據進行重新排列perm_sample_1 = permuted_data[:len(data1)] # 分成新的兩組數據perm_sample_2 = permuted_data[len(data1):]return perm_sample_1, perm_sample_2def draw_perm_reps(data_1, data_2, func, size=1): # 進行多次重新分組的操作perm_replicates = np.empty(size)for i in range(size):perm_sample_1, perm_sample_2 = permutation_sample(data_1, data_2)perm_replicates[i] = func(perm_sample_1, perm_sample_2)return perm_replicatesdef permutation_pvalue(data_1, data_2, func, size=1): # 計算P值empirical_test_stats = func(data_1, data_2)perm_replicates = draw_perm_reps(data_1, data_2, func, size)p = np.sum(perm_replicates > empirical_test_stats) / len(perm_replicates)return p同樣,我們使用了大小不同的三組樣本數據進行測試,得到與上述t分布一致的判斷結果。
# 輸入 A = permutation_pvalue(bmi_rich, bmi_ord, diff_of_means, size=10000) B = permutation_pvalue(bmi_rich[:500], bmi_ord[:500], diff_of_means, size=10000) C = permutation_pvalue(bmi_rich[:1000], bmi_ord[:1000], diff_of_means, size=10000) print(A) print(B) print(C) # 輸出 0.0 0.1227 0.0002總結
以上是生活随笔為你收集整理的实例讲解统计学基础知识(5):假设检验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 运营日常工具使用
- 下一篇: ubuntu 16.04 安装anaco