import pandas as pd
import pylab
import math
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from scipy.stats import norm
import scipy.stats
import warnings
warnings.filterwarnings("ignore")
df=pd.read_csv("http://ww2.amstat.org/publications/jse/datasets/normtemp.dat.txt",sep=" ",names=['Temperature','Gender','Heart Rate'])
df.head()
| Temperature | Gender | Heart Rate |
---|
0 | 96.3 | 1 | 70 |
---|
1 | 96.7 | 1 | 71 |
---|
2 | 96.9 | 1 | 74 |
---|
3 | 97.0 | 1 | 80 |
---|
4 | 97.1 | 1 | 73 |
---|
df.describe()
| Temperature | Gender | Heart Rate |
---|
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 |
---|
25% | 97.800000 | 1.000000 | 69.000000 |
---|
50% | 98.300000 | 1.500000 | 74.000000 |
---|
75% | 98.700000 | 2.000000 | 79.000000 |
---|
max | 100.800000 | 2.000000 | 89.000000 |
---|
#假设检验
#前提检验正态分布
observed_temperatures = df['Temperature'].sort_values()
bin_val = np.arange(start = observed_temperatures.min(),stop=observed_temperatures.max(),step=50)
mu,std = np.mean(observed_temperatures),np.std(observed_temperatures)
p = norm.pdf(observed_temperatures, mu,std)
plt.hist(observed_temperatures,bins=bin_val,normed=True,stacked=True)
plt.plot(observed_temperatures,p,color='r')
plt.xticks(np.arange(95.75,101.25,0.25),rotation=90)
plt.xlabel('Human Body Temperature Distributions')
plt.ylabel('human body temperature')
plt.show()
print("Average (Mu):"+str(mu)+"/ Standard Deviation:" + str(std))
![](https://img-blog.csdn.net/2018092611505536?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h6eTUzNzE5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
Average (Mu):98.24923076923076/ Standard Deviation:0.7303577789050376
#确定指标进行正态检验
x = observed_temperatures
shapiro_test,shapiro_p = scipy.stats.shapiro(x)
print("Shapiro-Wilk Stat:",shapiro_test,"Shapiro-Wilk p-Value:",shapiro_p)
k2,p = scipy.stats.normaltest(observed_temperatures)
print("k2:",k2,"p:",p)
#以上两种方法,p值大于0.05,认为正态分布
#Another method to determining normality is through Quantile-Quantile Plots
#QQ图检查正态分布
scipy.stats.probplot(observed_temperatures,dist='norm',plot=pylab)
pylab.show()
Shapiro-Wilk Stat: 0.9865769743919373 Shapiro-Wilk p-Value: 0.2331680953502655
k2: 2.703801433319236 p: 0.2587479863488212
![](https://img-blog.csdn.net/20180926115120555?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h6eTUzNzE5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
#另一种检测正态分布的方法
def ecdf(data):
#Compute ECDF
n = len(data)
x = np.sort(data)
y = np.arange(1,n+1) / n
return x,y
# Compute empirical mean and standard deviation
#Number of samples
n = len(df['Temperature'])
#Sample mean
mu = np.mean(df['Temperature'])
#Sample standard deviation
std = np.std(df['Temperature'])
print("Mean Temperature:",mu,"Standard deviation:",std)
#基于当前的均值和标准差,随机生成一个正态分布
normalized_sample = np.random.normal(mu,std,size=10000)
normalized_x,normalized_y = ecdf(normalized_sample)
x_temperature,y_temperature = ecdf(df['Temperature'])
#Plot the ECDFs
fig = plt.figure(figsize=(8,6))
plt.plot(normalized_x,normalized_y)
plt.plot(x_temperature,y_temperature,marker='.',linestyle='none')
plt.xlabel('ECDF')
plt.ylabel("Temperature")
plt.legend(("Normal Distribution","Sample data"))
Mean Temperature: 98.24923076923076 Standard deviation: 0.730357778905038
Out[73]:
<matplotlib.legend.Legend at 0xb3437b8>
![](https://img-blog.csdn.net/2018092611515132?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h6eTUzNzE5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
#验证98.6为平均温度
from scipy import stats
CW_mu = 98.6
stats.ttest_1samp(df['Temperature'],CW_mu,axis=0)
#T-Stat -5.454 p-value 近乎0,拒绝原假设
Ttest_1sampResult(statistic=-5.454823292364077, pvalue=2.410632041561008e-07)
#检验男女体温是否明显区别
#两独立样本t检验
#H0:两样本没有明显差异,H1:有明显差异
female_temperature = df.Temperature[df.Gender==2]
male_temperature = df.Temperature[df.Gender==1]
mean_female_temperature = female_temperature.mean()
mean_male_temperature = male_temperature.mean()
print("男体温均值:",mean_male_temperature,"女体温均值:",mean_female_temperature)
#两独立样本t检验
stats.ttest_ind(female_temperature,male_temperature,axis=0)
#由于p值0.024 < 0.05 ,拒绝原假设,我们有95%的自信度认为是有差异的
男体温均值: 98.1046153846154 女体温均值: 98.39384615384616
Ttest_indResult(statistic=2.2854345381654984, pvalue=0.02393188312240236)