確定數據分布正態性的11種基本方法
在數據科學和機器學習領域,許多模型都假設數據呈現正態分布,或者假設數據在正態分布下表現更好。例如,線性回歸假設殘差呈正態分布,線性判別分析(LDA)基于正態分布等假設進行推導。 因此,了解如何測試數據正態性的方法對于數據科學家和機器學習從業者至關重要。
本文將介紹測試數據正態性的11種基本方法,幫助讀者更好地理解數據分布的特征和如何應用合適的方法進行分析,以便在機器學習和數據建模過程中更好地處理數據分布對模型性能的影響。
繪圖法Plotting Methods
1.QQ Plot
QQ圖(Quantile-Quantile Plot)是一種用于檢驗數據分布是否符合正態分布的常用方法。在QQ圖中,將數據的分位數與標準正態分布的分位數進行比較,如果數據分布接近正態分布,QQ圖上的點將大致落在一條直線上。
如下示例代碼生成了一組服從正態分布的隨機數據來演示QQ Plot,運行代碼后,既可看到QQ Plot以及與之對應的正態分布曲線,通過觀察圖上的點的分布情況來初步判斷數據是否接近正態分布。
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
# 生成一組隨機數據,假設它們服從正態分布
data = np.random.normal(0, 1, 1000)
# 繪制QQ圖
stats.probplot(data, dist="norm", plot=plt)
plt.title('Q-Q Plot')
plt.show()
2.KDE Plot
KDE(Kernel Density Estimation)Plot是一種用于可視化數據分布的方法,它可以幫助我們檢測數據的正態性。在KDE Plot中,數據的密度被估計并繪制成一條平滑的曲線,這有助于我們觀察數據的分布形狀。
如下示例代碼生成了一組服從正態分布的隨機數據來演示KDE Plot,運行代碼后,既可看到KDE Plot以及與之對應的正態分布曲線,從而通過可視化來檢測數據分布的正態性。
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# 生成隨機數據
np.random.seed(0)
data = np.random.normal(loc=0, scale=1, size=1000)
# 創建KDE Plot
sns.kdeplot(data, shade=True, label='KDE Plot')
# 添加正態分布曲線
mu, sigma = np.mean(data), np.std(data)
x = np.linspace(min(data), max(data), 100)
y = (1/(sigma * np.sqrt(2 * np.pi))) * np.exp(-0.5 * ((x - mu) / sigma) ** 2)
plt.plot(x, y, 'r--', label='Normal Distribution')
# 顯示圖表
plt.legend()
plt.show()
3.Violin Plot
通過觀察Violin Plot可以發現數據的分布形狀,從而初步判斷數據是否接近正態分布。如果 Violin Plot 呈現出類似鐘形曲線的形狀,那么數據可能是近似正態分布的。如果 Violin Plot 偏斜嚴重或者有多個峰值,那么數據可能不是正態分布的。
如下示例代碼生成了一組服從正態分布的隨機數據來演示Violin Plot,運行代碼后,既可看到Violin Plot以及與之對應的正態分布曲線,通過可視化來檢測數據分布的形狀,從而初步判斷數據是否接近正態分布。
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# 生成隨機數據
np.random.seed(0)
data = np.random.normal(loc=0, scale=1, size=100)
# 創建 Violin Plot
sns.violinplot(data, inner="points")
# 添加正態分布曲線
mu, sigma = np.mean(data), np.std(data)
x = np.linspace(min(data), max(data), 100)
y = (1/(sigma * np.sqrt(2 * np.pi))) * np.exp(-0.5 * ((x - mu) / sigma) ** 2)
plt.plot(x, y, 'r--', label='Normal Distribution')
# 顯示圖表
plt.legend()
plt.show()
4.Histogram
使用直方圖(Histogram)來檢測數據分布的正態性也是一種常用的方法。直方圖可以幫助你直觀地了解數據的分布情況,并且可以初步判斷數據是否接近正態分布。
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
# 生成一組隨機數據,假設它們服從正態分布
data = np.random.normal(0, 1, 1000)
# 繪制直方圖
plt.hist(data, bins=30, density=True, alpha=0.6, color='g')
plt.title('Histogram of Data')
plt.xlabel('Value')
plt.ylabel('Frequency')
# 繪制正態分布的概率密度函數
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = stats.norm.pdf(x, np.mean(data), np.std(data))
plt.plot(x, p, 'k', linewidth=2)
plt.show()
如上圖所示,如果直方圖近似呈現鐘形曲線,并且與對應的正態分布曲線形狀相似,那么數據可能符合正態分布。當然,可視化只是一種初步的判斷,如果需要更精確的檢測,可以結合使用正態性檢驗等統計方法進行分析。
統計方法Statistical Methods
5.夏皮羅一威爾克(Shapiro-Wilk)檢驗
是一種用于檢驗數據是否滿足正態分布的統計方法,又稱之為W檢驗。在進行Shapiro-Wilk檢驗時,我們通常會關注兩個主要指標:
- 統計量W:基于觀測數據與在正態分布下的期望值之間的相關性來計算統計量W,W的取值范圍在0和1之間,當W接近1時,表示觀測數據與正態分布的擬合程度較好。
- P值:P值表示觀測到這種相關性的可能性,如果P值大于顯著水平(通常為0.05),則表明觀測數據很可能來自正態分布。
因此,當統計量W接近1且P值大于0.05時,我們可以得出結論:觀測數據滿足正態分布。
如下代碼中,首先生成一組服從正態分布的隨機數據,然后進行Shapiro-Wilk檢驗,得到檢驗統計量和P值。根據P值與顯著性水平的比較,即可判斷樣本數據是否來自正態分布。
from scipy import stats
import numpy as np
# 生成一組服從正態分布的隨機數據
data = np.random.normal(0, 1, 100)
# 執行Shapiro-Wilk檢驗
stat, p = stats.shapiro(data)
print('Shapiro-Wilk Statistic:', stat)
print('P-value:', p)
# 根據P值判斷正態性
alpha = 0.05
if p > alpha:
print('樣本數據可能來自正態分布')
else:
print('樣本數據不符合正態分布')
6.KS檢驗
KS檢驗(Kolmogorov-Smirnov test)是一種用于檢驗數據是否符合特定分布(比如正態分布)的統計方法。它通過測量觀測數據與特定理論分布的累積分布函數(CDF)之間的最大差異來評估二者是否來自同一分布?;静襟E如下:
- 對兩個樣本數據進行排序。
- 計算兩個樣本的經驗累積分布函數(ECDF),即計算每個值在樣本中的累積百分比。
- 計算兩個累積分布函數之間的差異,通常使用KS統計量衡量。
- 根據樣本的大小和顯著性水平,使用參考表活計算p值判斷兩個樣本是否來自同一分布。
Python中使用KS檢驗來檢驗數據是否符合正態分布時,可以使用Scipy庫中的kstest函數。下面是一個簡單的示例,演示了如何使用Python進行KS檢驗來檢驗數據是否符合正態分布。
from scipy import stats
import numpy as np
# 生成一組服從正態分布的隨機數據
data = np.random.normal(0, 1, 100)
# 執行KS檢驗
statistic, p_value = stats.kstest(data, 'norm')
print('KS Statistic:', statistic)
print('P-value:', p_value)
# 根據P值判斷正態性
alpha = 0.05
if p_value > alpha:
print('樣本數據可能來自正態分布')
else:
print('樣本數據不符合正態分布')
7.Anderson-Darling檢驗
Anderson-Darling檢驗是一種用于檢驗數據是否來自特定分布(例如正態分布)的統計方法。它特別強調觀察值在分布尾部的差異,因此在檢測極端值的偏差方面非常有效。
如下代碼使用stats.anderson函數執行Anderson-Darling檢驗,并獲得檢驗統計量、臨界值以及顯著性水平。然后根據統計量與臨界值的比較,即可判斷樣本數據是否來自正態分布。
from scipy import stats
import numpy as np
# 生成一組服從正態分布的隨機數據
data = np.random.normal(0, 1, 100)
# 執行Anderson-Darling檢驗
result = stats.anderson(data, dist='norm')
print('Anderson-Darling Statistic:', result.statistic)
print('Critical Values:', result.critical_values)
print('Significance Level:', result.significance_level)
# 判斷正態性
if result.statistic < result.critical_values[2]:
print('樣本數據可能來自正態分布')
else:
print('樣本數據不符合正態分布')
8.Lilliefors檢驗
Lilliefors檢驗(也稱為Kolmogorov-Smirnov-Lilliefors檢驗)是一種用于檢驗數據是否符合正態分布的統計檢驗方法,它是Kolmogorov-Smirnov檢驗的一種變體,專門用于小樣本情況。與K-S檢驗不同,Lilliefors檢驗不需要假定數據的分布類型,它基于觀測數據來評估是否來自正態分布。
如下示例中,使用lilliefors函數執行Lilliefors檢驗,并獲得檢驗統計量和P值。根據P值與顯著性水平的比較,即可以判斷樣本數據是否來自正態分布。
import numpy as np
from statsmodels.stats.diagnostic import lilliefors
# 生成一組服從正態分布的隨機數據
data = np.random.normal(0, 1, 100)
# 執行Lilliefors檢驗
statistic, p_value = lilliefors(data)
print('Lilliefors Statistic:', statistic)
print('P-value:', p_value)
# 根據P值判斷正態性
alpha = 0.05
if p_value > alpha:
print('樣本數據可能來自正態分布')
else:
print('樣本數據不符合正態分布')
9.距離測量Distance Measures
距離測量(Distance measures)是一種有效的測試數據正態性的方法,它提供了更直觀的方式來比較觀察數據分布與參考分布之間的差異。
下面是一些常見的距離測量方法及其在測試正態性時的應用:
(1) 「巴氏距離(Bhattacharyya distance)」:
- 測量兩個分布之間的重疊,通常被解釋為兩個分布之間的接近程度。
- 選擇與觀察到的分布具有最小Bhattacharyya距離的參考分布,作為最接近的分布。
(2) 「海林格距離(Hellinger distance)」:
- 用于衡量兩個分布之間的相似度,類似于Bhattacharyya距離。
- 與Bhattacharyya距離不同的是,Hellinger距離滿足三角不等式,這使得它在一些情況下更為實用。
(3) 「KL 散度(KL Divergence)」:
- 它本身并不是嚴格意義上的“距離度量”,但在測試正態性時可以用作衡量信息丟失的指標。
- 選擇與觀察到的分布具有最小KL散度的參考分布,作為最接近的分布。
這些距離測量方法可以幫助我們比較觀察到的分布與多個參考分布之間的差異,從而更好地評估數據的正態性。通過選擇與觀察到的分布距離最小的參考分布,我們可以更準確地判斷數據是否來自正態分布。