数据分布python实战
使用 Python 验证数据集中的体温是否符合正态分布。
正态分布 正态分布可视化之后就像是一个小山包,中间高两头低,大部分数据集中在平均值小部分在两端,
密度函数如下:
那正态分布是用来做什么的?为什么我们需要对数据进行正态性检验?
因为在数据建模前,我们需要通过数据分正态性检验结果来确定下一步的分析方案。
在本文中我们将针对拥有人体体温、性别、心率的数据集展开正态性检验。
总所周知人体在正常情况下是一个稳定的系统,体温是在36.7~37.7摄氏度之间,即98.1~99.9华氏度之间,这是稳定的,但当这个系统遭受病毒入侵等外界偶然因素时,会出现一些偏离在这些范围外的体温,换而言之我们可以将之理解为是呈现正态分布的数据,但是我们应该怎么证明呢?先不着急,我们先来观察一下这个数据集。拥有体温、心率、心率,这里我们只对心率做正态性检验。 观察体温数据,最小值96.3,最大值100.8,均值为98.2位于正常体温之内,这里我们使用kstest对数据的正态性进行KS检验,注意kstest不仅仅可以用来做正态性检验,同时也可以用来检验其他数据分布类型。注意:KS检验样本量需要大于50个。 函数使用方法如下:
kstest(rvs, cdf, args=(), N=20, alternative='two_sided', mode='approx',** kwds)
rvs:待检验的数据
cdf:检验方法,这里我们设置为‘norm’,即正态性检验
alternative:默认为双尾检验,可以设置为‘less’或‘greater’作单尾检验
#在文章开头统一调包
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import kstest
from scipy import stats
#读入数据
data=pd.read_csv('http://jse.amstat.org/datasets/normtemp.dat.txt',header=None,sep='\s+',names=['Temperature','sex','heart'])
#观察数据集
print(data.describe(percentiles=[.05, .25, .75, .95]))
#计算均值、标准差
u = data['Temperature'].mean()
std = data['Temperature'].std()
#使用KS检验检验正态性(样本量大于50)
kstest(data['Temperature'], 'norm',(u,std))
Temperature sex heart
count 130.000000 130.000000 130.000000
mean 98.249231 1.500000 73.761538
std 0.733183 0.501934 7.062077
min 96.300000 1.000000 57.000000
5% 97.045000 1.000000 62.000000
25% 97.800000 1.000000 69.000000
50% 98.300000 1.500000 74.000000
75% 98.700000 2.000000 79.000000
95% 99.300000 2.000000 84.000000
max 100.800000 2.000000 89.000000
# KstestResult(statistic=0.06472685044046644, pvalue=0.6450307317439967)
statistic为D值,pvalue为p值
一般来说我们认为 p值大于0.05时,为正态分布,小于则为非正态性。故而这里为正态分布。下面我们使用W检验,检验正态性。
#使用W检验
stats.shapiro(data['Temperature'])
# (0.9865769743919373, 0.2331680953502655)
(统计数,p值) 与KS检验基本相同,也认为 p值大于0.05时,为正态分布,小于则为非正态性。这里为正态分布。
接下来我们作图对正态性进行检验。一般来说从视觉上认定为正态性即可。从图上来看本数据集中体温也为正态分布。
#无拟合曲线的正态分布直方图
plt.hist(data['Temperature'], bins=120, color='blue',alpha=0.5)
plt.xlabel('Temperature')
plt.ylabel('frequency')
plt.title(r'Histogram of normal distribution of body temperature')
plt.show()
#拥有拟合曲线正态分布直方图
sns.set_palette("hls")
sns.distplot(data['Temperature'], bins=130, kde=True,color='blue')
plt.xlabel('Temperature')
plt.ylabel('frequency')
plt.title(r'Histogram of normal distribution of body temperature')
plt.show()
所以综上所诉,本数据集中的体温符合正态分布规律。