如何检验一个分布是否为正态分布
概率密度分布曲线表达式为:
f
(
x
)
=
1
2
π
σ
e
x
p
−
(
x
−
μ
)
2
2
σ
2
f(x)=\frac{1}{\sqrt{2π}σ}exp^{-\frac{(x-μ)^2}{2σ^2}}
f(x)=2πσ1exp−2σ2(x−μ)2
下面以房屋的评分系统数据作为说明,提取码:lyhx
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
读取数据:
d = pd.read_csv("~\KingCountryHomePrice\\train.csv")
设定分箱的数目:
bins_num = 20
画出频数图:
plt.hist(x = d['rating'], bins=bins_num, edgecolor='black')
plt.title('房屋评分系统对房屋的总体评分')
plt.show()
基本信息描述:
# 观察的describe
print('--------基本信息------')
print(d['rating'].describe())
理论散点和实际正态分布曲线图:
mean_rating = 7.664
sigma = np.std(d['rating'])
描绘正态分布曲线:
# 描绘正态分布曲线
def normfun(x, mu, sigma):
pdf = np.exp(-(x-mu)**2/(2*sigma**2))/(sigma*np.sqrt(2*np.pi))
return pdf
对打分的频数对应排布和进行排序
y_scatter = []
for i in d['rating'].unique():
y_scatter.append(list(d['rating']).count(i)/d['rating'].count())
x_scatter = list(d['rating'].unique())
x = np.arange(3, 13, 0.0001) # 步长越小,生成的数目就越大
y = normfun(x,mean_rating, sigma)
plt.plot(x, y)
plt.scatter(x_scatter, y_scatter)
plt.show()
从上图看,数据是不符合正态分布的,但为了更好地分析结果,我们还要用累计分布图和QQ图进行检验
画累计分布图:
churn_data = pd.DataFrame([x_scatter, y_scatter])
# 对数据进行转置
churn_data = churn_data.T
churn_data.columns = ['value', 'prob']
# 按照数值大小进行排序,然后求出累积图
churn_data = churn_data.sort_values(by = 'value')
cum_data = churn_data.cumsum()
plt.plot(cum_data['value'], cum_data['prob'])
plt.show()
观察累计分布曲线图,会发现数据也不严格的符合正态分布的累计分布图
QQ图
import statsmodels.api as sm
import pylab
sm.qqplot(churn_data['prob'], line='s')
pylab.show()
由图像可知,数据概率分布曲线和实际分布点偏离严重,接着进行[K-S][2]p值检验
from scipy import stats
import numpy as np
stats.kstest(churn_data['prob'], 'norm', (mean_rating, sigma))
# 最后得到检验p值小于,排除H1假设,样本数据不符合正态分布
KstestResult(statistic=0.9999999996682792, pvalue=1.0703583290996503e-104)
最后的p值远远小于0.05,我们可以拒绝原假设。