Python 全栈 60 天精通之路

Day 46:必备统计学知识:概率、期望、方差、标准差、协方差、相关系数、t 检验、F 检验、卡方检验

发布日期:2022年3月14日 14:53 阅读: 304 访问: 305

大家好,今天与大家一起学习统计学相关的核心概念和重要知识点。 统计学是一门收集、分析、展示和解释数据的学问。一般使用图表、统计变量总结分析数据。展示数据常用的图形类型有柱状图、折线图、饼图、箱型图、散点图等等,相关的统计变量和概念主要有: 事件 事件发生的概率 离散型变量 连续型变量 <l

大家好,今天与大家一起学习统计学相关的核心概念和重要知识点。

统计学是一门收集、分析、展示和解释数据的学问。一般使用图表、统计变量总结分析数据。展示数据常用的图形类型有柱状图、折线图、饼图、箱型图、散点图等等,相关的统计变量和概念主要有:

  • 事件
  • 事件发生的概率
  • 离散型变量
  • 连续型变量
  • 概率分布
  • 平均值、众数、中位数、分位数
  • 方差、标准差、协方差
  • 相关系数
  • 零假设(虚无假设)、备择假设
  • t 检验 、F 检验、卡方检验

理顺这些基本概念和相关理论,相当于把基本的统计学知识能重温一遍。

事件

抛硬币出现正面就可以定义为一个事件 X;抛硬币出现反面也能被定义为一个事件 Y;抛硬币 10 次,正面朝上次数也可定义为一个事件 Z;在 101 班测量了 40 名学生的身高,学生的平均身高也可以被定义为一个事件 H。

概率

概率描述某个事件发生的概率,比如上面事件 X 发生的概率为 0.4,则对应的事件 Y 发生的概率就为 0.6,事件 X 和 事件 Y 为一对对立事件。抛硬币 10 次,正面朝上次数为事件 Z,可能的取值为 0 到 10,发生 0 次的概率一般记做 P(X=0),它等于 0.6^10;出现 1 次的概率 P(X=1),等于 0.4*0.6^9,后面依次类推。

离散型随机变量

比如上面的事件 Z,可能取值为 0 到 10,这是一个离散型随机变量,因为事件 Z 可能的取值个数是有限的。

连续型随机变量

101 班 40 名学生的平均身高对应的事件 H 取值就有各种可能性,因此事件 H 取值为连续型随机变量

概率分布

概率分布表示某个事件的所有可能取值对应的概率情况。求出每个可能的取值对应的概率,就相当于得到事件 Z 的概率分布。此处事件 Z 的概率分布实际上就是我们常见的 二项分布,下面绘制出事件 Z 在正面发生概率为 0.4 情况下的概率分布图:

ph = 0.4
pt = 1 - ph 
sumn = 10 

zi = range(0,sumn+1)

def combine_number(sumn, headn):
    return math.factorial(sumn) / math.factorial(headn) / math.factorial(sumn - headn)

pi = [combine_number(10,headn)* math.pow(ph,headn) * math.pow(pt,sumn - headn) for headn in zi]

plt.plot(zi,pi,color='r')
plt.scatter(zi,pi,color='', marker='o',edgecolor='b')
plt.grid()
plt.xlabel('count of head')
plt.ylabel('p distribute')
plt.show()

看到正面出现 4 次的概率最大为 0.25。

累积分布函数

如上事件 Z 出现次数不大于 4 次的概率累加和,记做 F(4),等于 P(Z<=4) 的概率,逐个计算出 F(n),n 等于 0 到 10,这样就得到一个累积分布函数,离散型变量的累积分布函数被称作概率质量函数。

代码接着第 6 节,下面绘制出事件 Z 的概率质量函数:

cfd = np.cumsum(pi)
plt.step(zi,cfd,color='g')
for i,j in zip(zi,cfd):
    plt.text(x=i-0.75,y=j,s=round(j,2))

plt.xlabel('count of head')
plt.ylabel('cumulation p')
plt.grid()
plt.show()

平均值、中位数、标准差、方差

描述性变量是对已有数据的基本情况统计量,比如测量出 101 班 40 名学生的身高,我们就能基于这些数据,计算出以下描述性统计量:

  • 平均值
  • 中位数
  • 标准差
  • 方差

假定下面为 101 班级 40 名学生测量身高值:

hs = array([189., 158., 178., 169., 146., 169., 168., 169., 160., 177., 161.,
       191., 155., 177., 171., 183., 168., 181., 189., 180., 170., 168.,
       170., 169., 176., 163., 136., 165., 179., 150., 186., 160., 177.,
       154., 165., 186., 168., 182., 167., 162.])

使用 NumPy 很容易计算出 40 名学生的平均身高值:169.8。

np.mean(hs)

中位数:169.0,按照身高从低到高排序后,位于中间的数值。

np.median(hs)

它与均值不同,某些场景选用中位数会更加合适,尤其数据分布不均匀时。比如中等收入家庭占多,富豪还是少数但是财富值远多于中等收入家庭。如果取所有样本的均值就会高于大多数中等家庭收入均值,此时选用样本中位数更能贴近家庭实际收入情况。

方差:144.16。

np.var(hs)

标准差:12.0。

np.std(hs)

方差取根号得到标准差,它们表示数据偏离平均值的程度,标准差越小表示数据整体更靠近均值,反之越偏离均值,也就更加分散。

展示 40 位学生身高数据偏离平均值的柱状图:

import matplotlib.pyplot as plt
import numpy as np
import math

plt.figure(figsize=(12,8))
plt.bar(np.arange(40),hs-np.mean(hs),color='blue')
plt.plot(np.arange(40),np.repeat(0,40),color='r')
plt.xlabel('student id')
plt.ylabel('subtract mean height')

从上图看出偏离平均值(红线水平线)最大的样本 id 位于 25 到 30 间,偏离值为 30 多。

分位数

快速了解数据的分布最便捷的方法之一就是通过分位数,绘制箱型图。

常用的分位数有上、下分位数和中位数,分别对应数据 75%、25%、50% 比例处。

使用 NumPy 分别求出 40 位学生身高的上、下分位数和中位数,依次为:178.25、169.0、169.0。

p3 = np.percentile(hs,75)
p1 = np.percentile(hs,25)
p2 = np.percentile(hs,50)

接下来绘制箱型图,进一步获取到更多数据分布的信息:

plt.figure(figsize=(12,8))
plt.grid()
d = plt.boxplot(hs)

从箱型图中看出如上标注的信息,位于上、下限之外的样本点是异常值,用圆圈表示,如上图所示。

期望

101 班 40 名学生的身高值是连续性随机变量,很显然研究具体某个身高值的概率没有意义。一般的,将样本集合的最小值、最大值对应的区间均分为若干等分,求出某个样本落在对应区间的概率值,记做此身高值的概率。

使用 Matplotlib 绘制频率分布直方图,得到 10 个区间,以及落入每个区间的样本个数:

plt.figure(figsize=(8,6))
hsh = plt.hist(hs,color='b')
hsh 

注意 hist 方法返回的结果为一个元组,第一个元素为区间内样本的个数,第二个元素表示划分的 10 个区间,例如落在区间[136.,141.5] 的样本个数为 1,落在区间 [152.5, 158] 内元素个数为 2。

(array([1., 1., 1., 2., 6., 7., 7., 6., 4., 5.]),
 array([136. , 141.5, 147. , 152.5, 158. , 163.5, 169. , 174.5, 180. ,
        185.5, 191. ]),
 <a list of 10 Patch objects>)

频率分布直方图就是绘制区间与落在区间内样本个数的直方图,如下所示:

基于频率分布直方图理解期望更容易,从划分的 10 个子区间内分别选取一个代表性数值,然后求出每个子区间的概率,取两者的乘积求和便是身高的期望值,计算过程如下:

hsp  = hsh[0] / sum(hsh[0]) # 计算每个子区间的概率
hsv = [ (hsh[1][i] + hsh[1][i+1])/2.  for i in range(len(hsh[1])-1)] #选取子区间的中位数作为此区间的代表值
ex = sum(hsp * np.array(hsv))
ex

得到期望值为:170.2375,也就是基于 40 个学生身高样本,我们对学生身高的期望值大约为 170。

协方差

上面介绍的都是对单变量的统计分析,而协方差和相关系数分析的是两个随机变量间的相关程度,是对两个随机变量的联合分布的概率度量,给出两个随机变量怎样一起变化。

如下为 101 班 40 名学生某次期末考试的数学和物理分数:

(array([74, 84, 93, 60, 66, 78, 98, 65, 73, 89, 67, 93, 55, 77, 77, 77, 53,
        73, 65, 68, 82, 61, 68, 85, 66, 89, 78, 81, 85, 59, 73, 91, 68, 69,
        74, 74, 90, 73, 94, 91]),
 array([66, 72, 81, 52, 54, 69, 92, 55, 64, 80, 54, 82, 44, 65, 67, 69, 43,
        61, 58, 62, 71, 55, 61, 73, 57, 80, 70, 70, 75, 52, 63, 82, 57, 58,
        64, 63, 78, 63, 82, 79]))

图形展示学生的数学成绩和物理成绩:

plt.figure(figsize=(12,8))
plt.plot(maths,color='b',label='math')
plt.scatter(np.arange(40),maths, color='', marker='o',edgecolor='b')
plt.plot(phys,color='orange',label='phy')
plt.scatter(np.arange(40),phys, color='', marker='o',edgecolor='orange')
plt.xlabel('student id')
plt.ylabel('score')
plt.legend()

求两个变量的协方差:

np.cov(maths,phys)

结果如下,分别表示自身与自身,自身与对方的相关程度,不过估计看完没啥感觉,我们再来一组对比分析。

array([[153.01609195, 156.49195402],
       [156.49195402, 164.59885057]])

再拿 40 位学生的英语成绩与数学成绩做对比:

array([74, 73, 58, 90, 86, 73, 51, 85, 78, 62, 91, 59, 94, 74, 69, 74, 97,
       76, 84, 79, 68, 88, 83, 67, 86, 62, 71, 70, 67, 91, 75, 60, 83, 85,
       76, 75, 60, 74, 54, 54])

绘制图形:

plt.figure(figsize=(12,8))
plt.plot(maths,color='b',label='math')
plt.scatter(np.arange(40),maths, color='', marker='o',edgecolor='b')
plt.plot(engs,color='orange',label='eng')
plt.scatter(np.arange(40),engs, color='', marker='o',edgecolor='orange')
plt.xlabel('student id')
plt.ylabel('score')
plt.legend()

有些杂乱,按照数学成绩升序排序后,重新绘制图形:

### 按照分数升序排序后;
maths_ = np.sort(maths)
engs_arg = np.argsort(maths)
engs_ = engs[engs_arg]
plt.figure(figsize=(12,8))
plt.plot(maths_,color='b',label='math')
plt.scatter(np.arange(40),maths_, color='', marker='o',edgecolor='b')
plt.plot(engs_,color='orange',label='eng')
plt.scatter(np.arange(40),engs_, color='', marker='o',edgecolor='orange')
plt.xlabel('student id')
plt.ylabel('score')
plt.legend()

再求出数学和英语的协方差:

np.cov(maths,engs)

结果为:

array([[ 133.83589744, -134.06153846],
       [-134.06153846,  140.2974359 ]])

两个协方差对比,可以看出学生的数学成绩和物理成绩正相关,数学成绩和英语成绩负相关。

相关系数

协方差除以两个变量的方差乘积,得到相关系数。

np.corrcoef(maths,phys)

数学和物理高度正相关,也就是说数学分数高,物理分数就高。

array([[1.        , 0.98582444],
       [0.98582444, 1.        ]])
np.corrcoef(maths,engs)

数学和英语高度负相关,数学分数高,英语分数一般不高。

array([[ 1.        , -0.97834724],
       [-0.97834724,  1.        ]])

相关系数的取值范围为 [-1,1],大于 0 表示正相关,小于 0 表示负相关,等于 0 表示两个事件相关独立,无任何关系。

t 检验

假定本次期末考试高三年级的数学和物理成绩都服从正态分布,且方差相等。如上已经知道 101 班数学考试的平均成绩和标准差分别为 X=75.9Sx=11.4,40 名学生的物理平均成绩为 Y=66.1Sy=11.1

试问本次期末考试全校的数学和物理成绩的平均分有无显著差异?

这是一个典型的双样本,满足正态分布且方差相等的假设检验,判断两个正态分布的期望是否相同,这就是一个 t 检验问题。

使用 SciPy 求解双样本同方差的 t 检验问题,原假设 H0——数学和物理成绩的平均分无显著差异,H1——有显著差异。

import numpy as np
from scipy import stats

mean1 = 75.9
mean2 = 66.1

std1 = 11.4
std2 = 11.1

nobs1 = 40
nobs2 = 40

modified_std1 = np.sqrt(np.float32(nobs1)/np.float32(nobs1-1)) * std1
modified_std2 = np.sqrt(np.float32(nobs2)/np.float32(nobs2-1)) * std2

(statistic, pvalue) = stats.ttest_ind_from_stats(mean1=mean1, std1=modified_std1, nobs1=nobs1, mean2=mean2, std2=modified_std2, nobs2=nobs2)
(statistic, pvalue) 

得到结果为:

(3.8463804246241637, 0.00024347752844308177)

假设我们显著性水平 α=0.05,pvalue 显著的小于 0.05,所以我们拒绝原假设 H0,也就是认为数学和物理成绩的期望存在显著性差异。

解释下 p 值,p 值表示原假设发生概率大小。p 值越小说明原假设情况发生的概率就越小。

F 检验

t 检验是为检验均值是否有显著性差异,F 检验是为检验方差是否有显著性差异。

如下为两种车型近 10 天的销量情况,检验两种车型的销量方差是否存在显著差异,原假设 H0 为两种车型的销量方差无显著差异,H1 为方差有显著差异。

car_a = array([28, 72, 73, 62, 27, 91, 76, 63, 95, 20])
car_b = array([86, 40, 60, 37, 64, 51, 39, 53, 26, 81])

使用 F 检验过程如下:

def varf(a):
    return sum(np.power(a - np.mean(a),2)) / (len(a)-1)

f = varf(car_a) / varf(car_b)
f

统计值 f 为:1.91。

参考 F 检验表(https://wenku.baidu.com/view/fafb62536fdb6f1aff00bed5b9f3f90f77c64d5b.html),在显著性上水平等于 0.05,样本个数都为 9 的情况下关键值为 3.18,统计值 f 小于 3.18,所以接收原假设 H0,即认为两种车型的方差无显著性差异。

卡方检验

卡方检验用于检测分类型变量是否符合期望频数。例如,投掷一个 6 面筛子共 60 次,期望每一面出现的频次都为 10。但是不确定这个筛子是否动过手脚,于是投掷 60 次,得到实验数据如下:

array([11,  8,  9,  8, 10, 14])

使用卡方检验判断原假设 H0——未动过手脚,H1——动过手脚:

import scipy.stats as ss
obs= np.array([11,  8,  9,  8, 10, 14])
exp=np.repeat(10,6)
#拒绝域 5% 的显著水平,自由度 5
jjy=ss.chi2.isf(0.05,5)

#卡方
kf=ss.chisquare(obs,f_exp=exp).statistic

jjy, kf

结果:

jjy, kf = (11.1, 2.6)

5% 的显著水平,自由度 5 的拒绝域为大于 11.1,卡方检验计算的卡方值为 2.6,不在拒绝域内,所以接收原假设,即筛子未动过手脚。

小结

今天一口气我们一起总结了统计学的一些主要概念,顺着这些概念主线,我们便能快速重拾统计学的基本知识,为后面的机器学习和深度学习打下坚实的基础,今天主要总结:

  • 什么是事件,事件的概率
  • 事件对应的随机变量,分为离散型和连续型
  • 求出变量的所有可能取值的概率,变得到变量的概率分布和累积分布函数
  • 常见的 6 个描述性统计变量
  • 描述数据分布的分位数,从中还能找出异常值
  • 双变量间的相关性分析
  • 双样本的 t 检验 和 F 检验,分别检验不同样本间的均值、方差是否有显著性差异
  • 卡方检验常用于分类型变量,检验频次是否符合期望频次