描述性統計指標含義
numpy/scipy包中求相應統計指標的方法:
利用Python進行描述統計分析時,用到numpy庫/scipy庫
1. 中心位置:均值、中位數(分位數)、衆數
- 均值(mean(data)):描述了樣本觀測數據取值相對集中程度
- 衆數(mode(data)):樣本中出現頻率最高的數
- 中位數(median(data)):描述了樣本觀測數據的中間位置
- 分位數:將一列數由小到大排序,如果有n個數,則四分之一分位數記爲第n0.25個數,四分之三分位數記爲第n0.75個數,p分位數就是第np個數.如果np不是整數則往最接近的較大的整數上歸,樣本的0.5分位數就是樣本的中位數。
2. 發散程度:最值、極差、方差、標準差、變異係數
-
最大最小值
-
極差(ptp(data)):最大值-最小值,作爲樣本觀測數據變異程度大小的一個簡單度量
-
方差(var(data))\標準差(std(data)):描述樣本觀測數據變異程度的大小(注意此處兩個方差,式1代表樣本的方差(即用樣本的方差估計總體方差時是除以n-1,pandas包中求std即默認除n-1),式2代表數據的方差(numpy中std即除n))
-
變異係數mean(data)/std(data):方差和平均值的比值,衡量數據變異程度。
3. 偏差程度:z-分數、偏度、峯度
- z-分數((data[]-mean(data))/std(data)):衡量偏差的統計值,測量值距均值相差的標準差數目(當絕對值大於3記爲異常)
- 偏度(skewness):反映總體分佈的對稱信息,偏度越接近0,說明分佈越對稱,否則越偏斜。
i. 若偏度爲負,說明樣本服從左偏分佈(概率密度的左尾巴長,頂點偏向右邊)
ii. 反之. - 峯度(kurtosis):反映總體分佈密度曲線在其峯值附近的陡峭程度(根據樣本2階和4階中心距計算)
i. 正態分佈的峯度爲3,如果樣本峯度大於3,說明總體分佈密度曲線在其峯值附近比正態分佈來得陡
ii. 小於 3,說明總體分佈密度曲線在其峯值附近比正態分佈平緩。
(當數據集偏度或峯度過大時,可能需要進行對數化處理)
4. 相關程度:相關係數、協方差
- 協方差(cov(data,bias=1)):描述變量間相互關係,兩隨機向量X,Y之間的協方差定義爲cov(X,Y)=E[(X-E(X))(Y-E(Y))],E表示數學期望
- 相關係數(corrcoef(data)):先對變量進行標準化變換,然後再計算協方差,把先標準化變換後做協方差運算定義爲變量間的相關係數。
i. 相關係數是一個無單位的量,絕對值不超過1,它描述了變量間的線性相關程度
ii. 當變量間相關係數爲0時,變量間不存在線性趨勢關係,但可能存在非線性趨勢關係
iii. 當變量間相關係數的絕對值爲1時,一個變量是另一變量的線性函數;當變量間相關係數越接近1時,變量間線性趨勢越明顯
iv. 在用協方差描述變量間的相關程度時會受到變量的量綱和數量級的影響,即使對於同樣的一組變量,當變量的量綱和數量級發生變化時,協方差也會隨之改變。
用python進行描述性統計
本案例探究BMI指數與身高、體重等因素的關係。(BMI通過體重公斤數除以身高米數平方得出的數值,用以衡量人體胖瘦程度以及是否健康的標準)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import brfss
%config InlineBackend.figure_format='retina' #設置圖像清晰度
df=brfss.ReadBrfss() #導入brfss數據
#選取bmi和income兩列數據,並捨棄缺失值
bmi_income=df[['bmi','income']].dropna()
bmi_income.head(3)
>>>
> bmi income
0 40.18 3.0
1 25.09 1.0
3 28.19 8.0
bmi_income.info() #查看數據基本信息
bmi_income['income'].value_counts()
bmi_rich=bmi_income[bmi_income.income==8]['bmi']
bmi_ord=bmi_income[bmi_income.income!=8]['bmi']
bmi_rich.describe()
>>>
>count 110259.000000
mean 27.450733
std 5.900353
min 12.050000
25% 23.690000
50% 26.570000
75% 30.040000
max 97.650000
Name: bmi, dtype: float64
bmi_ord.describe()
>count 232833.000000
mean 28.537320
std 6.971436
min 12.020000
25% 24.030000
50% 27.370000
75% 31.620000
max 97.650000
Name: bmi, dtype: float64
中心趨勢
- 均值:
mean_rich=bmi_rich.mean()
mean_ord=bmi_ord.mean()
print('BMI mean of rich people: %.2f' % mean_rich)
print('BMI mean of ordinary people: %.2f' % mean_ord)
>>>
>BMI mean of rich people: 27.45
BMI mean of ordinary people: 28.54
- 中位數:
median_rich=bmi_rich.median()
median_ord=bmi_ord.median()
print('BMI median of rich people: %.2f' % median_rich)
print('BMI median of ordinary people: %.2f' % median_ord)
>>>
>BMI median of rich people: 26.57
BMI median of ordinary people: 27.37
- 衆數:
mode_rich=bmi_rich.mode().iloc[0]
mode_count_rich=np.count_nonzero(bmi_rich==mode_rich)
mode_ord=bmi_ord.mode().iloc[0]
mode_count_ord=np.count_nonzero(bmi_ord==mode_ord)
print('BMI mode of rich people: %.2f(counts %d)' % (mode_rich,mode_count_rich))
print('BMI mode of ordinary people: %.2f(counts %d)' % (mode_ord,mode_count_ord))
>>>
>BMI mode of rich people: 26.63(counts 1246)
BMI mode of ordinary people: 26.63(counts 2766)
- 均值的差值:
print('mean difference(rich-ordinary): %.2f' % (mean_rich-mean_ord))
>>>
>mean difference(rich-ordinary): -1.09
- 直方圖:
fig=plt.figure(figsize=(12,8))
#繪製富人bmi數據直方圖
p1=fig.add_subplot(211)
plt.hist(bmi_rich,bins=50,rwidth=0.9)
plt.xlabel('BMI')
plt.xlim((0,80))
plt.ylabel('Counts')
plt.title('BMI histogram of rich people')
#繪製普通人bmi數據直方圖
p2=fig.add_subplot(212)
plt.hist(bmi_ord,bins=50,rwidth=0.9)
plt.xlabel('BMI')
plt.xlim((0,80))
plt.ylabel('Counts')
plt.title('BMI histogram of ordinary people')
plt.hist(bmi_rich,bins=50,range=(10,60),normed=True,label='rich',
alpha=0.4,color='r')
plt.hist(bmi_ord,bins=50,range=(10,60),normed=True,label='ord',
alpha=0.4,color='b')
plt.legend()
plt.xlabel('BMI')
plt.ylabel('probability density')
plt.title('BMI histogram')
偏度:
#計算衆數區間
bin_edge=np.arange(10,60,1)
counts,bins=np.histogram(bmi_rich,bin_edge)
mode_left=bins[np.argmax(counts)] #返回counts取最大值時的下標值
mode_right=bins[np.argmax(counts)+1]
mode_middle=(mode_left+mode_right)/2
print('mode range(%.2f,%.2f)'%(mode_left,mode_right))
print('median:%.2f'%(median_rich))
print('mean:%.2f'%(mean_rich))
#計算偏度
print('skewness:%.2f'%bmi_rich.skew())
#作圖
plt.axvline(x=mean_rich,linewidth=1,color='r',label='mean')
plt.axvline(x=median_rich,linewidth=1,color='g',label='median')
plt.axvline(x=mode_middle,linewidth=1,color='b',label='mode')
plt.legend(loc='best')
plt.hist(bmi_rich,bins=bin_edge,rwidth=0.9,alpha=0.5)
plt.xlabel('BMI')
plt.ylabel('Counts')
plt.title('BMI distribution of rich people')
#收入水平分佈
print('skewness:%.2f'%bmi_income.income.skew())
bins=np.arange(1,10)
plt.hist(bmi_income.income,bins=bins,rwidth=0.9,align='left',alpha=0.5,
label='skewness:%.2f'%bmi_income.income.skew())
plt.legend()
plt.xlabel('income level')
plt.ylabel('counts')
plt.title('income distribution')
相對位置
- ECDF圖:Emperical Cumulative Density Function,即累積概率密度圖
def ecdf(data): #計算數據的ECDF值
x=np.sort(data)
y=np.arange(1,len(x)+1)/len(x)
return (x,y)
def plot_ecdf(data,xlabel=None,ylabel='ECDF',label=None): #繪製數據的ECDF圖
x,y=ecdf(data)
_=plt.plot(x,y,marker='.',markersize=3,linestyle='none',label=label)
_=plt.legend(markerscale=4)
_=plt.xlabel(xlabel)
_=plt.ylabel(ylabel)
plt.margins(0.01)
plot_ecdf(bmi_rich,label='rich')
plot_ecdf(bmi_ord,xlabel='BMI',label='ord')
- 分位數:
q1=bmi_rich.quantile(0.25)
q2=bmi_rich.quantile(0.5)
q3=bmi_rich.quantile(0.75)
IQR=q3-q1 #四分位距(interquartile range, IQR)
print('min: ', bmi_rich.min())
print('25%: ',q1)
print('50%: ',q2)
print('75%: ',q3)
print('IQR: %.2f'%IQR)
print('max: ', bmi_rich.max())
>>>
>min: 12.05
25%: 23.69
50%: 26.57
75%: 30.04
IQR: 6.35
max: 97.65
- 箱圖:
bmi_income['income_level']=bmi_income['income'].map(lambda x: 'rich' if x==8 else 'ord')
sns.boxplot(x=bmi_income['income_level'],y=bmi_income['bmi'],palette='muted')
離散度
- 方差和標準差
var_rich=bmi_rich.var()
std_rich=bmi_rich.std()
print('For rich people: Variance=%.2f,Standard deviance=%.2f'%(var_rich,std_rich))
var_ord=bmi_ord.var()
std_ord=bmi_ord.std()
print('For ordinary people: Variance=%.2f,Standard deviance=%.2f'%(var_ord,std_ord))
>>>
>For rich people: Variance=34.81,Standard deviance=5.90
For ordinary people: Variance=48.60,Standard deviance=6.97
- Cohen’s d
def cohen_d(data1,data2):
n1=len(data1)
n2=len(data2)
x1=data1.mean()
x2=data2.mean()
var1=np.var(data1,ddof=1) #ddof=1代表無偏,ddof=0代表有偏
var2=np.var(data2,ddof=1)
sp=np.sqrt(((n1-1)*var1+(n2-1)*var2)/(n1+n2-2))
return (x1-x2)/sp
print("'Cohen's d:%.3f"%cohen_d(bmi_rich,bmi_ord))
>>>
'Cohen's d:-0.163
相關性
- 協方差
df2=df[['height','weight','bmi']].dropna()
height=.height
weight=df2.weight
bmi=df2.bmi
np.cov(height,weight) #計算協方差矩陣
>>>
>array([[1.12563400e-02, 1.08190764e+00],
[1.08190764e+00, 4.67153513e+02]])
- 相關係數
np.corrcoef(height,weight)[0][1] #計算相關係數
>>>0.4718041740847708
#繪製身高體重散點圖,一般通過散點圖查看兩個變量間的相關性
plt.plot(height,weight,marker='.',linestyle='none',alpha=0.05)
plt.xlabel('height(m)')
plt.ylabel('weight(kg)')
plt.title('correlation of weight and height')
plt.show()
#計算體重與BMI的相關係數
corr_weightBMI=np.corrcoef(weight,bmi)[0][1]
corr_weightBMI
#繪製BMI及體重散點圖,一般通過散點圖查看兩個變量間的相關性
plt.plot(weight,bmi,marker='.',linestyle='none',alpha=0.05)
plt.xlabel('weight(kg)')
plt.ylabel('bmi')
plt.title('correlation of weight and bmi')
plt.show()