假如要對一份統計數據進行分析,一般其來源來自於社會調研/普查,所以數據不是總體而是一定程度的抽樣。對於抽樣數據的分析,就可以結合上篇統計量及其抽樣分布的內容,判斷數據符合哪種分布。使用已知分布特性,可以完成對總體的統計分析。
本文使用python函數判斷數據集是否符合特定抽樣分布。
數據來源
本次試驗使用kagglehttps://www.kaggle.com/datasets上的公開數據集,可以通過搜索框進行數據集搜索。
通過搜索「income」關鍵值,最后決定使用https://www.kaggle.com/goldenoakresearch/us-household-income-stats-geo-locations/version/1#US_Income_Kaggle.csv這個數據集,其中包含抽樣區域的家庭收入均值,中位數和標准差。通過頁面中的pdf文件鏈接,可以獲取每個字段的說明。
抽樣分布驗證
讀入數據
import pandas as pd
import numpy as np
us_income = pd.read_csv("US_Income_Kaggle.csv", encoding="ISO-8859-1")
需要注意,csv文件的 編碼是Latin-1
,因此需要顯式指定編碼讀取。
畫出收入均值的直方圖
import seaborn as sns
sns.distplot(us_income['Mean'], color="b", bins=10, kde=True)
從圖形看,在低收入側,有一個數量的下降,並不符合正態分布的曲線。
使用函數判斷是否服從正態分布
from scipy import stats
stats.kstest(us_income['Mean'], 'norm')
Out[23]: KstestResult(statistic=0.980404837353683, pvalue=0.0)
因為kstest可以做多種分布的驗證,這里需要指定驗證的分布類型為正態分布,即第2個參數。
stats.shapiro(us_income['Mean'])
UserWarning: p-value may not be accurate for N > 5000.
warnings.warn("p-value may not be accurate for N > 5000.")
Out[25]: (0.9653068780899048, 0.0)
shapiro函數不適合樣本數>5000的正態分布檢驗,所以這里提示warning。
stats.normaltest(us_income['Mean'],axis=0)
Out[27]: NormaltestResult(statistic=1170.1750576510913, pvalue=7.938067739808798e-255)
normaltest函數專門用於正態分布分布檢驗,其中axis=0
表示按行讀取數據。
通過以上的函數,可以得到所有的pvalue都小於0.05,這種情況下,我們認為區域收入平均值不服從正態分布。
是否服從t分布
np.random.seed(1)
ks = stats.t.fit(us_income['Mean'])
df = ks[0]
loc = ks[1]
scale = ks[2]
t_estm = stats.t.rvs(df=df, loc=loc, scale=scale, size=len(us_income['Mean']))
stats.ks_2samp(us_income['Mean'], t_estm)
Out[40]: Ks_2sampResult(statistic=0.07327168078639335, pvalue=1.7671996893936462e-36)
這里的思路是先用t分布擬合區域收入均值,然后使用ks_2samp
函數比較區域收入均值和t分布的隨機變量。因為pvalue小於0.05,認為該數據集不服從t分布。用以下方法可以畫出擬合數據和數據集的對比圖。
from matplotlib import pyplot as plt
plt.figure()
us_income['Mean'].plot(kind = 'kde')
t_distribution = stats.t(ks[0], ks[1],ks[2])
x = np.linspace(t_distribution.ppf(0.01), t_distribution.ppf(0.99), 100)
plt.plot(x, t_distribution.pdf(x), c='orange')
plt.xlabel('location based income')
plt.title('income on t_distribution', size=20)
plt.legend(['income_data', 't_distribution'])
是否服從卡方分布
np.random.seed(1)
chi_square = stats.chi2.fit(us_income['Mean'])
df = chi_square[0]
loc = chi_square[1]
scale = chi_square[2]
chi_estm = stats.chi2.rvs(df=df, loc=loc, scale=scale, size=len(us_income['Mean']))
stats.ks_2samp(us_income['Mean'], chi_estm)
Out[40]: Ks_2sampResult(statistic=0.07327168078639335, pvalue=1.7671996893936462e-36)
同樣采用擬合值與原數據集比較,pvalue小於0.05,認為該數據不服從卡方分布。擬合數據和數據集的對比圖方法同上,此處從略。
總結
對於數據集的抽樣分布類型,可以使用scipy.stats
包中的相應函數進行判斷。其中,正態分布可以使用kstest
,normaltest
等函數;對於t分布和卡方分布,可以先對數據進行相應分布的擬合,然后用ks_2samp
函數對擬合的數據同原始數據比較,獲得兩個數據是否服從相同的分布。
歡迎掃描二維碼進行關注