Python机器学习:假设检验

方差分析这部分内容还不是很理解,在这里先做一个笔记,以后有时间再回过头来改一改。
用到的数据集 → \rightarrow Iris

什么是假设检验?
假设检验就是利用样本数据对某个事先做出的统计假设,再按照某种方法去检验,最后判断此假设是否正确。

怎么去假设检验?
假设检验的目的是为了推断总体。首先对总体的未知参数或分布做出某种假设 H 0 H_{0} H0,然后在 H 0 H_0 H0成立的条件下,若通过抽样分析发现“小概率事件”竟然在一次实验中发生了(在这里我们是不希望小概率事件发生的),则表明 H 0 H_0 H0很可能不成立,从而拒绝 H 0 H_0 H0;相反,若这个“小概率事件”没有发生,则没有理由拒绝 H 0 H_0 H0,从而接收 H 0 H_0 H0

⭐️ 检验的显著性水平( α \alpha α):要求“小概率事件”发生的概率小于等于某一给定的临界概率。通常 α \alpha α的取值为较小的数0.05、0.01、0.001。
⭐️ P值:假定原假设 H 0 H_0 H0为真时,“拒绝原假设 H 0 H_0 H0”这件事犯错的可能性。当P值 < α <\alpha <α时,表示“拒绝原假设 H 0 H_0 H0”这件事犯错误的可能性很小,即可以认为原假设 H 0 H_0 H0是错误的,从而拒绝 H 0 H_0 H0;否则,应接收原假设 H 0 H_0 H0

🌕 数据分布检验

数据分布的假设检验是重要的非参数检验,它不是针对具体的参数,而是根据样本值来判断总体是否服从某种指定的分布

🌗 数据准备

# 导入相关的库
import numpy as np
from matplotlib import pyplot as plt
from scipy import stats
# 中文显示问题
import matplotlib
matplotlib.rcParams['axes.unicode_minus']=False
import seaborn as sns
sns.set(font="Kaiti",style="ticks",font_scale=1.4)

np.random.seed(123)			# 设置随机数种子
X1 = stats.norm.rvs(loc = 0,scale = 1,size = 500)		# X1为服从均值为0方差为1的标准正态分布数据
X2 = stats.norm.rvs(loc = 0,scale = 5,size = 500)		# X2为服从均值为0方差为5的正态分布数据
X3 = stats.f.rvs(15,30,size = 500)						# X3为服从均值为15方差为30的非正态分布数据
plt.figure(figsize = (15,6))
plt.subplot(1,3,1)							# 将画布分为一行三列(三部分),现在对从左至右从上至下第一个子图操作
plt.hist(X1,bins = 50,density = True)		# X1的频率直方图(density=True表示频率,False表示频数。默认为频数)
plt.grid()
plt.ylabel("频率")
plt.title("标准正态分布")
plt.subplot(1,3,2)							# 对第二个子图操作
plt.hist(X2,bins = 50,density = True)
plt.grid()
plt.ylabel("频率")
plt.title("正态分布")
plt.subplot(1,3,3)							# 对第三个子图操作
plt.hist(X3,bins = 50,density = True)
plt.grid()
plt.ylabel("频率")
plt.title("F分布")
plt.tight_layout()							# 防止子图间轴域的标签叠在一起
plt.show()

在这里插入图片描述

🌗 利用Q-Q图检验数据是否符合正态分布

什么是Q-Q图?
Q-Q中的两个Q都是quantile(分位数)的缩写,也就是说Q-Q是横纵坐标都关于分位数的一个图。那么说到这里,

什么又是分位数?
分位数也称分位点,是指将一个随机变量的概率分布范围分为几个等份的点,常用的有中位数(二分位数)、四分位数、百分位数等。

Q-Q图的作用即标题,是用来检验数据是否符合正态分布的,它就是先将两列数据的分位点画成散点图,然后比较两列数据的分位点是否分布在y=x的直线上,若是,则接收数据来自正态总体的假设,否则就拒绝原假设。

在这里我们可以使用statsmodels.api模块中的qqplot()函数来绘制Q-Q图。

import numpy as np
from matplotlib import pyplot as plt
from scipy import stats
import statsmodels.api as sm		# 导入Q-Q图要用的模块

import matplotlib
matplotlib.rcParams['axes.unicode_minus']=False
import seaborn as sns
sns.set(font="Kaiti",style="ticks",font_scale=1.4)

np.random.seed(123)
X1 = stats.norm.rvs(loc = 0,scale = 1,size = 500)
X2 = stats.norm.rvs(loc = 0,scale = 5,size = 500)
X3 = stats.f.rvs(15,30,size = 500)

fig = plt.figure(figsize = (15,5))
ax = fig.add_subplot(1,3,1)			# add_subplt与subplot是一个东西,没有太大的区别,只是调用的方式不一样
sm.qqplot(X1,line = "45",ax = ax)	# 绘制X1的Q-Q图,line=45是绘制45°斜直线
plt.grid()
plt.title("X1正态检验Q-Q图")
ax = fig.add_subplot(1,3,2)
sm.qqplot(X2,loc = 0,scale = 5,line = "45",ax = ax)	# 绘制X2的Q-Q图
plt.grid()
plt.title("X2正态检验Q-Q图")
ax = fig.add_subplot(1,3,3)
sm.qqplot(X3,line = "45",ax = ax)	# 绘制X3的Q-Q图
plt.grid()
plt.title("X3正态检验Q-Q图")
fig.tight_layout()
plt.show()

在这里插入图片描述
可以发现,前两个图的散点图都能很好地拟合参考线,表示X1和X2是正态分布,而第三个图的散点图没有在参考线上,表示X3不是正态分布。

🌗 利用K-S拟合优度检验来检验数据是否符合正态分布

K-S检验可以使用stats.kstest()函数完成,默认情况下会验证数据是否符合标准正态分布,同时可以指定cdf参数所要验证的分布类型,还可以利用args参数指定符合参数的特定分布。

# 这里还是用随机数种子“123”
print(stats.kstest(X1,cdf = "norm"))				# X1的标准正态分布检验
print(stats.kstest(X2,cdf = "norm"))				# X2的标准正态分布检验
print(stats.kstest(X2,cdf = "norm",args = (0,5)))	# X2的正态分布检验
print(stats.kstest(X3,cdf = "norm"))				# X3的标准正态分布检验
print(stats.kstest(X3,cdf = "f",args = (15,30)))	# X3的非正态分布检验

在这里插入图片描述
从结果中我们可以看到,在对X1的标准正态分布检验中,P值大于0.05(在前面回顾一下P值的概念),就说明了“拒绝原假设”这件事犯错误的可能性比较大了,也就是说拒绝原假设会犯错误,那么我们就应该接收原假设,即X1是服从标准正态分布的。(0.05是检验的显著性水平,是人为取值的)

又如在X2的标准正态分布检验中,它的P值为0,但本质上是不为0的,因为这个P值很小很小(5.2306133517677304 × 1 0 − 48 \times10^{-48} ×1048),所以程序就直接省略了。那就是这个P值它是小于0.05,说明“拒绝原假设”这件事犯错误的可能性比较小,那么我们就应该拒绝原假设,即X2不服从标准正态分布。

后面几个结果也是同样的分析。

K-S检验还可以用stats.ks_2samp()函数检验两个随机变量的分布是否相同

print(stats.ks_2samp(X1,X2))
print(stats.ks_2samp(X2,X3))
print(stats.ks_2samp(X3,X1))

在这里插入图片描述
同样,也是根据P值来判断它们是否具有相同的分布。

🌕 t检验

t检验分为单样本t检验两独立样本t检验

⭐️ 单样本t检验:检验来自正态分布的样本的期望值(均值)是否为某一实数。
⭐️ 两独立样本t检验:判断两个来自正态分布(方差相同)的独立样本的期望值之差是否为某一实数。

两种检验的原假设都是差等于指定值

🌗 单样本t检验

import numpy as np
from scipy import stats

np.random.seed(123)
X1 = stats.norm.rvs(loc = 0,scale = 1,size = 500)	# 标准正态分布随机数X1
X2 = stats.norm.rvs(loc = 0,scale = 5,size = 500)	# 正态分布随机数X2
X3 = stats.norm.rvs(loc = 5,scale = 5,size = 500)	# 正态分布随机数X3
print(stats.ttest_1samp(X1,0))		# 检验X1的均值是否为0
print(stats.ttest_1samp(X2,5))		# 检验X2的均值是否为5
print(stats.ttest_1samp(X3,5))		# 检验X3的均值是否为5

在这里插入图片描述
从第一组的检验结果可以发现,它的P值大于0.05,也就是说“拒绝原假设”这件事犯错误的可能性比较大,所以应该接受原假设,即X1的均值为0,剩下两组的判断也是如此。

🌗 两独立样本的检验

print(stats.ttest_ind(X1,X2))	# 检验X1和X2的均值之差是否等于0
print(stats.ttest_ind(X2,X3))	# 检验X2和X3的均值是否相等
print(stats.ttest_ind(X3,X1))	# 检验X3和X1的均值是否相等

在这里插入图片描述
从结果分析,我们可以知道X1和X2的均值相等,X2和X3的均值不相等,X3和X1的均值也不相等。

🌕 方差分析

方差分析是分析实验数据的一种方法。

对于抽样测得的实验数据,由于观测条件不同随机因素的干扰造成的差异使得实验结果不同,将前者造成的差异称为系统差异偶然差异

方差分析的目的:从实验数据中分析出各个因素及它们之间产生的影响,确定各个因素作用的大小,进而把两种差异区分开来,以确定在实验中有没有系统的因素在起作用。

方差分析根据因素数量,可分为单因素方差分析双因素方差分析等。

🌗 单因素方差分析

使用sm.stats.anova_lm()函数完成方差分析(l是小写L),使用pairwise_tukeyhsd()函数对数据方差分析结果进行多重检验。

import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf

a = pd.read_csv("D:/Pycharm/机器学习数据/program/data/chap2/Iris.csv")	# 读取数据
model = smf.ols("SepalLengthCm~Species",data = a).fit() 
b = sm.stats.anova_lm(model,typ = 2)	# 方差分析
print(b)

在这里插入图片描述最后一个PR是P值,远小于0.05,则应该拒绝原假设,说明不用类别的SepalLengthCm特征均值不完全相同。那么我们可以使用多重比较对比哪些类别之间的均值不同。

import pandas as pd
from statsmodels.stats.multicomp import pairwise_tukeyhsd

a = pd.read_csv("D:/Pycharm/机器学习数据/program/data/chap2/Iris.csv")
b = pairwise_tukeyhsd(endog = a.SepalLengthCm,groups = a.Species,alpha = 0.05)
print(b)

在这里插入图片描述
针对于获得的多重比较的结果,可以使用plot_simultaneous()函数可视化出多重比较的图像。

b.plot_simultaneous()
plt.grid()
plt.show()

在这里插入图片描述
可以直观的看出,三个类别的均值都不相同或,且setosa的均值最小,virginica的均值最大。

🌗 双因素方差分析

双因素方差分析分为两种情况,分别是不考虑交互作用和考虑交互作用的情况。

import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf

a = pd.read_csv("D:/Pycharm/机器学习数据/program/data/chap2/Iris.csv")

np.random.seed(123)
a["Group"] = np.random.choice(["A","B"],size = 150)		# 生成新的分类因素Group
model = smf.ols("SepalLengthCm~Species * Group",data = a).fit()
b = sm.stats.anova_lm(model,typ = 2)
print(b)

在这里插入图片描述
从结果可以看出,Species因素下差异是显著的。Group因素和Species:Group(Species和Group的交互作用)因素下差异是不显著的。

针对双因素影响的数据,可以使用sns.catplot()函数将其可视化。

import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
from matplotlib import pyplot as plt
import seaborn as sns

import matplotlib
matplotlib.rcParams['axes.unicode_minus']=False
sns.set(font="Kaiti",style="ticks",font_scale=1.4)

a = pd.read_csv("D:/Pycharm/机器学习数据/program/data/chap2/Iris.csv")
np.random.seed(123)
a["Group"] = np.random.choice(["A","B"],size = 150)
model = smf.ols("SepalLengthCm~Species * Group",data = a).fit()
b = sm.stats.anova_lm(model,typ = 2)
sns.catplot(x = "Species",y = "SepalLengthCm",hue = "Group",markers = ["s","o"],linestyles = ["-","--"],data = a,kind = "point",aspect = 1.4)
plt.grid()
plt.title("多因素方差分析")
plt.show()

在这里插入图片描述

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值