python正态检验_Python检验数据是否正态分布
在對數據進行處理前,有事需要判斷數據是否呈正態分布,比如線性回歸,比如使用3-sigma判斷數據是否異常。常用的正態分布檢測方法:
Shapiro-Wilk test
Shapiro-Wilk test是一種在頻率上統計檢驗中檢驗正態性的方法。該檢驗的零檢驗是樣本$x_1,\cdots ,x_n$來自于一個正態分布的母體。這個檢驗的統計量是:
$$W = \frac{(\sum_{i=1}^{n}a_{i}x_{(i)})^2}{\sum_{i=1}^{n}(x_i-\bar{x})^2}$$
其中:
$x_{(i)}$用括號包含下標索引i的;不與x混淆,它是第i階統計量,即樣本中的第i個最小數
$\overline {x}=(x_{1}+\cdots +x_{n})/n$是樣本的平均值。
常量$a_i$通過公式$(a_1,\dots ,a_n)=\frac{m^{T}V^{-1}}{\sqrt{(m^{T}V^{-1}V^{-1}m)}}, m=(m_1,\dots ,m_n)^T$,其中$m_1,\dots ,m_n$是從一個標準的正態分布隨機變量上采樣的有序獨立同分布的統計量的期望值。V是這些有序統計量的協方差。
這個統計檢驗的假設是樣本來自于一個正態母體,因此,一方面,如果p值小于選擇的顯著度水平(通常0.05),那么在更大概率下我們應該拒絕零假設,數據的證據顯示我們的樣本不是來自一個正態分布母體。另一方面,如果p值比選擇的顯著度水平大,那么我們沒有證據拒絕零假設,數據來自于一個正態分布。
Python代碼:
import numpy as np
from scipy import stats
np.random.seed(0)
x = np.random.randn(1, 1000)
print(stats.shapiro(x[0]))
# (0.9985557794570923, 0.5914123058319092)
# 輸出(統計量W的值,P值)
# W的值越接近1就越表明數據和正態分布擬合得越好,P值>指定水平, 不拒絕原假設,可以認為樣本數據服從正態分布
# 不適合樣本>5000的情況
參考鏈接:
Kolmogorov-Smirnov test
Kolmogorov-Smirnov是比較一個頻率分布f(x)與理論分布g(x)或者兩個觀測值分布的檢驗方法。其原假設H0:兩個數據分布一致或者數據符合理論分布。D=max|f(x)- g(x)|,當實際觀測值D>D(n,α)則拒絕H0,否則接受H0假設。
KS檢驗與t-檢驗之類的其他方法不同是KS檢驗不需要知道數據的分布情況,可以算是一種非參數檢驗方法。當然這樣方便的代價就是當檢驗的數據分布符合特定的分布時,KS檢驗的靈敏度沒有相應的檢驗來的高。在樣本量比較小的時候,KS檢驗最為非參數檢驗在分析兩組數據之間是否不同時相當常用。
Kolmogorov檢驗找出在每一個數據點上經驗累積概率與目標分布的累積概率之差的上界,列出公式是這樣的:
$$D_n = \underset{x}{sup}|F_n(x)-F(x)|$$
其中sup函數表示一組距離中的上確界,這是個數學概念,表示在原假設$F_n(x)=F(x)$的條件下,$F_n(x)-F(x)$的絕對值的最小上界。$F_n(x),F(x)$分別代表經驗的和理論的累積概率。其意圖在于如果原假設成立,則$D_n$應該很小,如果很大,則原假設不成立。但是,這個上確界怎么求出來呢?請看下面的公式:
$$D_n = \underset{x}{sup}|F_n(x)-F(x)|=\underset{1\leq k\leq n}{max}\{|F_n(x_k)-F_0(x_k)|,|F_0(x_{k+1}-F_n(x_k)|\}$$
其中k為樣本從小到大排列后的序數。從公式中看出$D_n$是經驗和目標累積概率之差和錯一位后再求出的差中最大的一個。Kolmogorov還給出了這個距離的分布函數,并給出了判斷的臨界值。當然現在的統計軟件都直接計算p值,很少有人查表了。
Kolmogorov-Smirnov檢驗(K-S檢驗)基于累積分布函數,用以檢驗一個經驗分布是否符合某種理論分布或比較兩個經驗分布是否有顯著性差異。
兩樣本K-S檢驗由于對兩樣本的經驗分布函數的位置和形狀參數的差異都敏感而成為比較兩樣本的最有用且常規的非參數方法之一。
優點:該檢驗不依賴于要測試的累積分布函數,相比于卡方擬合檢驗(卡方檢驗需要50個以上的樣本),不需要大量的樣本。
缺點:只適用于連續分布;在分布中間敏感,在兩端不夠敏感;最大的局限在于整個分布需要完全確定,如果位置,形狀等參數都是從數據中估計的,判定區間不再有效,因此這些參數一般只能通過模擬得到。
scipy.stats.kstest是一個很強大的檢驗模塊,除了正態性檢驗,還能檢驗 scipy.stats 中的其他數據分布類型。
scipy.stats.kstest(rvs, cdf, args=(), N=20, alternative=’two-sided’, mode=’approx’)
rvs:待檢驗的數據
cdf:檢驗方法,這里我們設置為‘norm’,即正態性檢驗
args:分布參數,可選
N:樣本數量
alternative:默認為雙尾檢驗,可以設置為‘less’或‘greater’作單尾檢驗
mode:定義計算p-value的方式
使用示例:
import numpy as np
from scipy import stats
np.random.seed(0)
x = np.random.randn(1, 100)
print(stats.kstest(x[0], 'norm'))
# KstestResult(statistic=0.0582486387238324, pvalue=0.8865884365301941)
輸出結果中第一個為統計量,第二個為P值(注:統計量越接近0就越表明數據和標準正態分布擬合的越好,如果P值大于顯著性水平,通常是0.05,接受原假設,則判斷樣本的總體服從正態分布)
參考鏈接:
Anderson-Darling test
這個方法是由T. W. Anderson和D. A. Darling于1954年提出的,與K-S檢驗相比,AD檢驗度量經驗累積概率和理論累積概率之差的方法顯得更加自然。下面的公式就是其方法:
$$Z = n\int_{-\infty}^{\infty}[F_n(x)-F(x)]^{2}w(x)f(x)dx$$
是不是感覺像是計算方差的公式,我的直觀感覺,就是把每個數據點的差求平方以后相加,得到總的分布偏差,這樣就考慮了所有的差異點,而不是像K-S檢驗那樣只考慮一個最大的。
公式中f(x)是理論分布密度函數,w(x)是某個權重函數。若w(x)≡1,則為Cramér-Von Mises統計量$W^2$。
用上面的積分公式計算統計量比較麻煩,因此兩位統計學家又推導出了簡單的計算方法,見下面的公式:
$$A^2=-n-\sum_{i}^{n}\frac{2i-1}{n}[\ln F(Y_i)+\ln (1-F(Y_{n+1-i})]$$
其中$Y_i=\frac{X_i-\hat{\mu}}{\hat{\sigma}}$
注意這個公式計算所采用的數據順序是從小到大排列的,不是原來的數據排列順序。
scipy.stats.anderson是由 scipy.stats.kstest 改進而來的,可以做正態分布、指數分布、Logistic 分布、Gumbel 分布等多種分布檢驗。默認參數為 norm,即正態性檢驗。
返回:statistic – 統計數;critical_values – 評判值;significance_level – 顯著性水平
import numpy as np
from scipy import stats
np.random.seed(0)
x = np.random.randn(1, 100)
print(stats.anderson(x[0], 'norm'))
# AndersonResult(statistic=0.18097695613924714, critical_values=array([0.555, 0.632, 0.759, 0.885, 1.053]), significance_level=array([15. , 10. , 5. , 2.5, 1. ]))
# 如果輸出的統計量值statistic < critical_values,則表示在相應的significance_level下,接受原假設,認為樣本數據來自給定的正態分布。
參考鏈接:
scipy.stats.normaltest
scipy.stats.normaltest運用了D’Agostino–Pearson綜合測試法,返回(得分值,p值),得分值=偏態平方+峰態平方
scipy.stats.normaltest(a, axis=0, nan_policy='propagate')
這里的三個參數都有必要看一下:
a:待檢驗的數據
axis:默認為0,表示在0軸上檢驗,即對數據的每一行做正態性檢驗,我們可以設置為axis=None來對整個數據做檢驗
nan_policy:當輸入的數據中有空值時的處理辦法。默認為 propagate,返回空值;設置為raise時,拋出錯誤;設置為omit時,在計算中忽略空值。
代碼示例:
import numpy as np
from scipy import stats
np.random.seed(0)
x = np.random.randn(1, 100)
print(stats.normaltest(x[0]))
# NormaltestResult(statistic=0.45430460563864783, pvalue=0.7967994182504964)
如果pvalue是>0.05,則代表是正態分布。
參考鏈接:
Lilliefors-test
檢驗樣本數據是否來自正態總體。采用方法是:當總體均值和方差未知時,用樣本的均值和方差代替后 再用K-S檢驗法。據說效果不如Anderson-Darling test。原假設 H0:樣本服從正態分布; 備擇假設 H1:樣本不服從正態分布
import numpy as np
from statsmodels.stats.diagnostic import lilliefors
np.random.seed(0)
x = np.random.randn(1, 100)
print(lilliefors(x[0]))
# 輸出(統計量的值,P值)=(0.06433451870420759, 0.40018452551214856),P值>指定水平0.05,接受原假設,可以認為樣本數據服從正態分布
參考鏈接:
總結
以上是生活随笔為你收集整理的python正态检验_Python检验数据是否正态分布的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: autocad完全应用指南_建筑绘图慢?
- 下一篇: mybatis collection用法