
實時航班追蹤背后的技術:在線飛機追蹤器的工作原理
其中, 為均值, 是方差
正態性檢驗是數據分析和機器學習中的重要步驟,判斷數據是否呈正態分布不僅可以幫助選擇合適的算法和方法,還能提升模型的性能和可解釋性,如果數據不符合正態分布,可以考慮通過數據變換(如對數變換、Box-Cox變換)來改善分布特征,參考文章——特征工程——數據轉換
正態分布檢驗用于判斷給定的數據是否來自正態分布。常見的正態性檢驗方法包括:
圖形法
統計檢驗法
不同檢驗方法對數據的敏感度不同,選擇時可以根據樣本量和對正態性的嚴格要求程度來確定
代碼實現
數據生成
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
np.random.seed(42)
# 生成一列正態分布數據,均值為0,標準差為1,數據量為1000
normal_data = np.random.normal(loc=0, scale=1, size=1000)
# 生成一列非正態分布數據(例如從均勻分布生成)
non_normal_data = np.random.uniform(low=-2, high=2, size=1000)
data = pd.DataFrame({
'Normal_Distribution': normal_data,
'Non_Normal_Distribution': non_normal_data
})
data
生成兩列數據,一列為正態分布,另一列為非正態分布,接下來根據這些數據進行數據正態分布檢驗實現
Q-Q圖
import scipy.stats as stats
# 創建Q-Q圖函數
def plot_qq(data, title):
stats.probplot(data, dist="norm", plot=plt)
plt.title(title)
plt.grid(True)
# 繪制兩列數據的Q-Q圖
plt.figure(figsize=(12, 6),dpi=1200)
plt.subplot(1, 2, 1)
plot_qq(data['Normal_Distribution'], 'Q-Q Plot of Normal Distribution')
plt.subplot(1, 2, 2)
plot_qq(data['Non_Normal_Distribution'], 'Q-Q Plot of Non-Normal Distribution')
plt.tight_layout()
plt.savefig("Q-Q.pdf", format='pdf',bbox_inches='tight')
plt.show()
左側圖是正態分布數據的Q-Q圖,點大致沿著一條直線分布,說明這列數據接近正態分布,右側圖是非正態分布數據的Q-Q圖,點偏離直線較明顯,說明這列數據不符合正態分布
P-P圖
# 創建P-P圖函數
def plot_pp(data, title):
sorted_data = np.sort(data)
cdf = stats.norm.cdf(sorted_data, np.mean(sorted_data), np.std(sorted_data))
plt.plot(cdf, np.linspace(0, 1, len(data)), marker='o', linestyle='', markersize=3)
plt.plot([0, 1], [0, 1], 'r--')
plt.title(title)
plt.xlabel('Theoretical CDF')
plt.ylabel('Empirical CDF')
plt.grid(True)
# 繪制兩列數據的P-P圖
plt.figure(figsize=(12, 6),dpi=1200)
plt.subplot(1, 2, 1)
plot_pp(data['Normal_Distribution'], 'P-P Plot of Normal Distribution')
plt.subplot(1, 2, 2)
plot_pp(data['Non_Normal_Distribution'], 'P-P Plot of Non-Normal Distribution')
plt.tight_layout()
plt.savefig("P-P.pdf", format='pdf',bbox_inches='tight')
plt.show()
左側是正態分布數據的P-P圖,數據點與理論的CDF曲線大致符合,說明這列數據接近正態分布,右側是非正態分布數據的P-P圖,數據點明顯偏離理論的CDF曲線,說明這列數據不符合正態分布
直方圖
# 繪制直方圖函數
def plot_hist(data, title):
plt.hist(data, bins=30, density=True, alpha=0.6, color='g')
# 繪制正態分布曲線
mu, std = np.mean(data), np.std(data)
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = stats.norm.pdf(x, mu, std)
plt.plot(x, p, 'k', linewidth=2)
plt.title(title)
plt.grid(True)
# 繪制兩列數據的直方圖
plt.figure(figsize=(12, 6), dpi=1200)
plt.subplot(1, 2, 1)
plot_hist(data['Normal_Distribution'], 'Histogram of Normal Distribution')
plt.subplot(1, 2, 2)
plot_hist(data['Non_Normal_Distribution'], 'Histogram of Non-Normal Distribution')
plt.tight_layout()
plt.savefig("Histogram.pdf", format='pdf',bbox_inches='tight')
plt.show()
左側是正態分布數據的直方圖,其形狀接近對稱的鐘形,并且與疊加的正態分布曲線高度吻合,說明數據符合正態分布,右側是非正態分布數據的直方圖,其形狀較為平坦,未呈現正態分布的鐘形曲線,說明數據不符合正態分布
Shapiro-Wilk檢驗
# 進行Shapiro-Wilk檢驗
shapiro_normal = stats.shapiro(data['Normal_Distribution'])
shapiro_non_normal = stats.shapiro(data['Non_Normal_Distribution'])
shapiro_results = {
'Normal_Distribution': {
'Statistic': shapiro_normal.statistic,
'p-value': shapiro_normal.pvalue
},
'Non_Normal_Distribution': {
'Statistic': shapiro_non_normal.statistic,
'p-value': shapiro_non_normal.pvalue
}
}
shapiro_results
正態分布數據:統計量為 0.9986,p 值為 0.6265,p 值大于 0.05,因此不能拒絕數據符合正態分布的假設,非正態分布數據:統計量為 0.9543,p 值非常小,p 值遠小于 0.05,因此可以拒絕數據符合正態分布的假設
Kolmogorov-Smirnov檢驗
# 進行Kolmogorov-Smirnov檢驗
ks_normal = stats.kstest(data['Normal_Distribution'], 'norm', args=(np.mean(data['Normal_Distribution']), np.std(data['Normal_Distribution'])))
ks_non_normal = stats.kstest(data['Non_Normal_Distribution'], 'norm', args=(np.mean(data['Non_Normal_Distribution']), np.std(data['Non_Normal_Distribution'])))
ks_results = {
'Normal_Distribution': {
'Statistic': ks_normal.statistic,
'p-value': ks_normal.pvalue
},
'Non_Normal_Distribution': {
'Statistic': ks_non_normal.statistic,
'p-value': ks_non_normal.pvalue
}
}
ks_results
正態分布數據:統計量為 0.0215,p 值為 0.7370,p 值大于 0.05,無法拒絕數據符合正態分布的假設,非正態分布數據:統計量為 0.0678,p 值為 0.00019,p 值遠小于 0.05,因此可以拒絕數據符合正態分布的假設
Anderson-Darling檢驗
# 進行Anderson-Darling檢驗
ad_normal = stats.anderson(data['Normal_Distribution'], dist='norm')
ad_non_normal = stats.anderson(data['Non_Normal_Distribution'], dist='norm')
ad_results = {
'Normal_Distribution': {
'Statistic': ad_normal.statistic,
'Critical_Values': ad_normal.critical_values,
'Significance_Level': ad_normal.significance_level
},
'Non_Normal_Distribution': {
'Statistic': ad_non_normal.statistic,
'Critical_Values': ad_non_normal.critical_values,
'Significance_Level': ad_non_normal.significance_level
}
}
ad_results
正態分布數據:統計量為 0.347,低于所有的臨界值(0.574, 0.653, 0.784, 0.914, 1.088),因此我們不能拒絕數據符合正態分布的假設,非正態分布數據:統計量為 11.326,遠高于所有的臨界值,因此可以拒絕數據符合正態分布的假設
Jarque-Bera檢驗
# 進行Jarque-Bera檢驗
jb_normal = stats.jarque_bera(data['Normal_Distribution'])
jb_non_normal = stats.jarque_bera(data['Non_Normal_Distribution'])
jb_results = {
'Normal_Distribution': {
'Statistic': jb_normal.statistic,
'p-value': jb_normal.pvalue
},
'Non_Normal_Distribution': {
'Statistic': jb_non_normal.statistic,
'p-value': jb_non_normal.pvalue
}
}
jb_results
正態分布數據:統計量為 2.456,p 值為 0.2928,p 值大于 0.05,無法拒絕數據符合正態分布的假設,非正態分布數據:統計量為 59.919,p 值非常小,可以拒絕數據符合正態分布的假設
D’Agostino’s K-squared檢驗
# 進行D'Agostino's K-squared檢驗
dagostino_normal = stats.normaltest(data['Normal_Distribution'])
dagostino_non_normal = stats.normaltest(data['Non_Normal_Distribution'])
dagostino_results = {
'Normal_Distribution': {
'Statistic': dagostino_normal.statistic,
'p-value': dagostino_normal.pvalue
},
'Non_Normal_Distribution': {
'Statistic': dagostino_non_normal.statistic,
'p-value': dagostino_non_normal.pvalue
}
}
dagostino_results
正態分布數據:統計量為 2.576,p 值為 0.2759,p 值大于 0.05,無法拒絕數據符合正態分布的假設,非正態分布數據:統計量為 710.37,p 值極小,可以拒絕數據符合正態分布的假設
本文章轉載微信公眾號@Python機器學習AI