1.要解決的問題
給出的數據集爲人體的體溫數據,下載鏈接爲 https://pan.baidu.com/s/1t4SKF6U2yyjT365FaE692A*
包括三個數據字段:
- gender:性別,1爲男性,2爲女性
- Temperature:體溫
- HeartRate:心率
要解決的問題如下:
- 人體體溫的總體均值是否爲98.6華氏度?
- 人體的溫度是否服從正態分佈?
- 人體體溫中存在的異常數據是哪些?
- 男女體溫是否存在明顯差異?
- 體溫與心率間的相關性(強?弱?中等?)
首先導入數據集:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
data = pd.read_csv('test.csv')
temp = data['Temperature']
gender = data['Gender']
heartRate = data['HeartRate']
查看該數據集的各項數據
data.describe()
輸出:
Temperature | Gender | HeartRate | |
---|---|---|---|
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 |
輸入:
data.shape
輸出:
(130, 3)
問題一:人體體溫的總體均值是否爲98.6華氏度?
這是一個正態總體,方差未知,均值的假設檢驗問題,使用的是 t 分佈
原假設H0:=98.6
備擇假設H1:!=98.6
設置默認顯著性水平爲 0.05
def hypothesis_mean(data, total_mean, alpha=0.05):
sample_mean = np.mean(data)
sample_std = np.std(data, ddof=1)
sample_size = len(data)
# 檢驗統計量
t = (total_mean - sample_mean) * np.sqrt(sample_size) / sample_std
t_score = stats.t.isf(alpha / 2, df = (sample_size-1) )
if (t > t_score) or (t < -t_score):
return True
return False
if hypothesis_mean(temp, 98.6):
print('接受H0,人體體溫的總體均值爲98.6華氏度')
接受H0,人體體溫的總體均值爲98.6華氏度
問題二:人體的溫度是否服從正態分佈?
畫出熱度圖,肉眼觀察人體溫度看是否服從正態分佈。
根據中心極限定理,一般情況下,當數據量大於30的時候,可以近似看做服從正態分佈,該數據集一共有130條數據,可以近似看做服從正態分佈
sns.distplot(temp)
下面檢驗人體的溫度是否服從正態分佈
scipy.stats.normaltest
可以專門用作檢驗是否服從正態分佈
方法:scipy.stats.normaltest (a, axis=0)
參數:
- a - 待檢驗數據;
- axis - 默認爲0,表示在0軸上檢驗,即對數據的每一行做正態性檢驗,我們可以設置爲 axis=None 來對整個數據做檢驗
返回:
- statistic - 統計量
- pvalue - p值,p大於0.05時,接受原假設H0,即H0爲真,p小於0.05時,拒絕H0,即H0爲假,接受H1
scipy.stats.normaltest(temp)
輸出:
NormaltestResult(statistic=2.703801433319236, pvalue=0.2587479863488212)
根據輸出可以看出,p 值爲 0.26,大於 0.05,即接受 H0,原假設成立,人體體溫服從正態分佈
問題三:人體體溫中存在的異常數據是哪些?
異常數據,這裏採用兩種檢測方法
1.3σ 原則
3σ 原則又稱爲拉依達準則,該準則具體來說,就是先假設一組檢測數據只含有隨機誤差,對原始數據進行計算處理得到標準差,然後按一定的概率確定一個區間,認爲誤差超過這個區間的就屬於異常值。
正態分佈狀況下,數值分佈表:
數值分佈 在數據中的佔比
(μ-σ,μ+σ) 0.6827
(μ-2σ,μ+2σ) 0.9545
(μ-3σ,μ+3σ) 0.9973
注:在正態分佈中 σ 代表標準差, μ 代表均值,x=μ 爲圖形的對稱軸
def three_sigma(Ser):
'''
Ser:表示傳入DataFrame的某一列。
'''
low = Ser.mean()-3*Ser.std()
up = Ser.mean()+3*Ser.std()
drop_index = Ser.loc[(Ser < low) | (Ser > up)].index
for i in drop_index:
print(Ser[i])
return drop_index, len(drop_index)
three_sigma(temp)
100.8
輸出:
(Int64Index([129], dtype='int64'), 1)
根據輸出,可以看出,使用 3σ 原則檢測出來的人體體溫中的異常數據只有一個,爲 100.8
2.箱線圖
箱型圖提供了識別異常值的一個標準,即異常值通常被定義爲小於 QL-1.5IQR 或大於 QU+1.5IQR 的值。
其中,QL 稱爲下四分位數,表示全部觀察值中有四分之一的數據取值比它小;
QU 稱爲上四分位數,表示全部觀察值中有四分之一的數據取值比它大;
IQR 稱爲四分位數間距,是上四分位數 QU 與下四分位數 QL 之差,其間包含了全部觀察值的一半。
# 定義箱線圖識別異常值函數
def box_plot(Ser):
'''
Ser:進行異常值分析的DataFrame的某一列
'''
low = Ser.quantile(0.25)-1.5*(Ser.quantile(0.75)-Ser.quantile(0.25))
up = Ser.quantile(0.75)+1.5*(Ser.quantile(0.75)-Ser.quantile(0.25))
drop_index = Ser.loc[(Ser < low) | (Ser > up)].index
return drop_index, len(drop_index)
box_plot(temp)
輸出
(Int64Index([0, 65, 129], dtype='int64'), 3)
def view_boxplot(Ser):
plt.subplot(121)
plt.boxplot(Ser)
index, size = box_plot(Ser)
for i in index:
print(Ser[i])
view_boxplot(temp)
96.3
96.4
100.8
根據輸出可以看出,使用箱線圖檢測出來的人體體溫中的異常數據有三個,分別爲 96.3,96.4,100.8
問題四:男女體溫是否存在明顯差異?
這是兩個正態總體均值差的假設檢驗問題
由於不確定男女的體溫的方差是否相等,因此先用levene檢驗,檢驗兩總體是否具有方差齊性,若得到的p值大於0.05,認爲兩總體具有方差齊性。
# levene檢驗兩總體是否具有方差齊性
boy = data['Temperature'][data['Gender'] == 1]
girl = data['Temperature'][data['Gender'] == 2]
stats.levene(boy, girl)
輸出:
LeveneResult(statistic=0.06354951292025163, pvalue=0.8013756068102883)
第二個輸出爲 p 值,可以看出,p 值爲 0.80,遠大於 0.05,可以認爲兩總體具有方差齊性。
接下來使用 stats.ttest_ind
函數來檢驗男女的體溫是否存在明顯的差異
stats.ttest_ind(boy, girl)
Ttest_indResult(statistic=-2.2854345381654984, pvalue=0.02393188312240236)
得到的 p 值小於 0.05,可以認爲拒絕原假設,男女的體溫存在明顯的差異
問題五:體溫與心率間的相關性(強?弱?中等?)
首先可以使用 seaborn 庫中的 corr()
函數得到兩個變量之間的相關係數,並畫出散點圖來直觀表示
# 相關係數矩陣
temp.corr(heartRate)
0.2536564027207643
# 散點圖
plt.scatter(temp, heartRate)
相關係數是 0.25, 並且根據圖中也可以粗略判斷其相關性是不強的
下面介紹兩種判斷相關係數的方法
1. pearson(皮爾遜)相關係數
要求樣本滿足正態分佈
- 兩個變量之間的皮爾遜相關係數定義爲兩個變量之間的協方差和標準差的商,其值介於-1與1之間
先判斷兩變量是否服從正態分佈
stats.normaltest(temp, axis=0)
輸出:
NormaltestResult(statistic=2.703801433319236, pvalue=0.2587479863488212)
stats.normaltest(heartRate, axis=0)
輸出:
NormaltestResult(statistic=2.3488941072144778, pvalue=0.3089897872482146)
由於這兩個變量的 p 值都大於 0.05,可以認爲他們服從正態分佈,接下來進行皮爾遜相關係數檢驗
stats.pearsonr(temp, heartRate)
輸出:
(0.25365640272076423, 0.003591489250708233)
p值爲 0.03,基本無相關性
2. Sperman 秩相關係數
皮爾森相關係數主要用於服從正太分佈的連續變量
對於不服從正太分佈的變量,分類關聯性可採用 Sperman 秩相關係數,也稱等級相關係數
由於本用例給出的變量服從正態分佈,所以這裏就不再進行 Sperman 秩相關係數檢驗了