在这篇文章中,我们将研究假设检验。 我们会:
- 看看什么是假设检验。
- 对R’CO2’数据集执行假设检验。
- 对同一数据集执行更好的假设检验。
- 分析我们的假设检验的结果以了解其含义。
这篇文章将针对初学者(或寻求评论的初学者),我将在此处互换使用某些词汇来使概念更易于理解。
什么是假设检验?
假设检验是我们可以用来回答问题的工具。 这是我们的问题:我们想知道冷却设备是否影响(增加或减少)其CO2吸收。 在假设检验中,我们将两种可能的结果(对我们问题的答案)表述为“假设”。 假设检验如下:
假设1:低温植物 不会影响 其CO2吸收。
假设2:低温植物 确实会影响 其二氧化碳吸收。
我们将假说1称为“空假说”,因为这是什么都没有发生或“空”发生的结果。 我们将假说2称为“替代假说”,这是不同于原假设的结果。
我们将使用的数据集是R’CO2’数据集。 在此数据集中,测量了冷藏植物的CO2(二氧化碳)吸收和非冷藏植物的CO2吸收。 我已经通过删除索引清除了数据; 我建议您使用我的数据文件。 我们将使用这些数据,并使用假设检验来确定“冷藏”环境中植物的CO2吸收量是否不同于“非冷藏”环境中植物的二氧化碳吸收量。
# import some useful packages
%matplotlib inline
import pandas as pd
import numpy as np
from scipy import stats
from fitter import Fitter
import matplotlib.pyplot as plt
# silence warnings for beautification
import warnings
warnings.filterwarnings('ignore')
# create a dataframe df with our data
df = pd.read_csv('co2_data.csv')
df.head()

我们需要快速查看数据以确保其没有任何怪异的特征。 让我们检查冷藏和非冷藏植物的数量是否相同。 在下面我们可以看到它们是均匀的。 如果不是,这将使我们的假设检验更加困难。
# count how many chilled/unchilled plant measurements we have nonchill_plants = df[df['Treatment'] == 'nonchilled']
chill_plants = df[df['Treatment'] == 'chilled']
num_nonchilled = nonchill_plants.shape[0]
num_chilled = chill_plants.shape[0]
print('num chilled: {}, num normal: {}'.format(num_chilled, num_nonchilled))
num chilled: 42, num normal: 42
在许多情况下,最好有更多的数据(42个样本)以能够坚决拒绝或接受假设,通常至少要有100个样本才能回答假设。 虽然42不太低,但是我们可能可以使用这么多样本。
现在,让我们检查观察值的数量是否跨二氧化碳浓度均匀。 如果在更高或更低的CO2浓度下有更多的实验,这可能会影响我们的测试能力。 看起来每种浓度的实验次数确实是偶数。
# check to see if there is bias # in the concentrations of CO2 df.groupby('conc').size()
conc
95 12
175 12
250 12
350 12
500 12
675 12
1000 12
dtype: int64
让我们用曲线图绘制非冷藏植物的CO2吸收值。 我们将这种分布称为“非冷藏”分布。
plt.figure(figsize=(12.5,10))
plt.hist(nonchill_plants['uptake'], color='c3', label='non-chilled', alpha=0.7)
plt.xlabel('co2 absorbtion')
plt.ylabel('count')
plt.legend(loc='upper left')
plt.title('non-chilled plant data')
plt.show()

这样我们就有了数据:
我们的非冷藏植物分布有两个(或三个?)凸起,大多数数据点位于正确的凸起处。
我们有我们的假设:
零假设 :低温植物不会影响其二氧化碳吸收。
替代假设 :低温植物确实会影响其二氧化碳吸收。
现在,我们需要通过查看数据来找出发生了哪些假设。
一种发现的方法是用我们的眼睛比较数据的分布。 如果冷藏工厂的分布与非冷藏工厂的分布有显着差异,则备用假设可能是正确的。 如果两个分布相同,则零假设可能是正确的。 让我们绘制分布图并进行比较。
plt.figure(figsize=(12.5,10))
plt.hist(nonchill_plants['uptake'], label='non-chilled', color='c3', alpha=0.7)
plt.hist(chill_plants['uptake'], label='chilled', color='c0', alpha=0.7)
plt.xlabel('co2 absorbtion')
plt.ylabel('count')
plt.legend(loc='upper left')
plt.title('non-chilled plant data overlaid with chilled plant data')
plt.show()

蓝色的这种冷态植物分布明显向较低的CO2吸收值重新平衡。 这意味着植物变冷会影响其二氧化碳的吸收。 我们可以选择其他假设为正确的:
零假设:低温植物不会影响其二氧化碳吸收。
替代假设 :低温植物确实会影响其二氧化碳吸收。
用眼睛比较分布是在两种可能的假设之间进行选择的最简单方法。
统计检验
尽管先前的方法似乎可以很好地解决此处提出的问题,但它并不完全可靠。 有时两个分布很难区分。 我们如何客观地判断一个发行版何时与另一个发行版不同?
您可以使用一种称为统计检验的方法:它告诉您两个分布的相似程度,或更准确地说,它告诉您所测试的数据来自特定分布的概率(p值)。 下面,我们将进行统计测试,以查看我们的冷藏工厂数据是否与非冷藏工厂数据来自相同的分布。
在python中,您可以使用scipy.stats对任何定义明确的分布进行统计测试,但是我们对非冷藏植物的CO2吸收分布没有很好定义。 因此,我们将找到一个与非冷藏分布尽可能相似的众所周知的分布,我们可以使用fitter包,该包仅做了很多讨厌的工作,反复遍历可能的分布,以便我们找到分布最类似于我们的非冷藏配送。
让我们找出我们的非冷藏工厂数据来自哪个分布。
f = fitter(nonchill_plants['uptake'], bins=10)
f.verbose = false
f.fit()
best_shape_1 = f.get_best()
dst1 = list(best_shape_1.keys())[0]
print('non-chilled plant co2 absorbtion')
print('dstribution: {}'.format(dst1))
print('best distribution shape: {}'.format(best_shape_1[dst1]))
print('best 5 distributions, lowest 5 errors:')
f.df_errors.sort(columns=['sumsquare_error'], ascending=true).ix[:5]
non-chilled plant co2 absorbtion
dstribution: genhalflogistic
best distribution shape: (0.83770454292175289, 10.599999993744611, 29.353144088738148)
best 5 distributions, lowest 5 errors:

看起来genhalflogistic分布最适合我们的非冷藏数据,其误差值为0.001242。 我们将使用这种分布来检验我们的假设。 让我们目视检查genhalflogisitc分布,以确认该分布与我们的非冷藏植物数据相似。
rvf = stats.genhalflogistic.pdf(x=[x for x in range(11,46)],
c=best_shape_1[dst1][0],
loc=best_shape_1[dst1][1],
scale=best_shape_1[dst1][2])
plt.figure(figsize=(12.5,10))
plt.hist(nonchill_plants['uptake'], label='non-chilled', color='c3', alpha=0.7, normed=true, bins=10)
plt.plot([x for x in range(11,46)], rvf, label='genhalflogistic', color='c3')
plt.xlabel('co2 absorbtion')
plt.ylabel('count')
plt.legend(loc='upper left')
plt.title('non-chilled plant distribution and genhalflogistic distribution')
plt.show()

它不是完美的,但看起来半衰期分布确实确实在很大程度上匹配了我们的非冷藏植物数据。 两者都向右上方倾斜,并且都沿CO2 Absorbtion轴在15–25处略有倾斜。
我们可以说,如果冷藏植物的分布与代表我们非冷藏植物数据的genhalflogistic分布足够不同,则说明冷藏植物的CO2吸收受到影响。
为了衡量冷藏植物数据与总物流分布之间的差异,我们使用了一种称为p值的数据。 p值只是某个数据样本来自某个分布的概率。 如果在检查冷藏数据是否来自Genhalflogisitic分布时获得足够低的p值,则可以得出结论,冷藏植物数据遵循不同的分布,并且表现出与Genhalflogisitc /非冷藏分布不同的行为。
为了通过genhalflogisitc分布和冷藏工厂数据获得p值,我们将两者都输入到称为Kolmogorov-Smirnov检验或ks检验的数据中。 让我们计算一些p值。
_, nonchilled_pvalue = stats.kstest(nonchill_plants['uptake'], 'genhalflogistic', args=best_shape_1[dst1])
_, chilled_pvalue = stats.kstest(chill_plants['uptake'], 'genhalflogistic', args=best_shape_1[dst1])
print('p-value (probability) of non-chilled data being from our genhalflogistic: ', nonchilled_pvalue)
print('p-value (probability) of chilled data being from our genhalflogistic: ', chilled_pvalue)
p-value (probability) of non-chilled data being from our genhalflogistic: 0.639477797842
p-value (probability) of chilled data being from our genhalflogistic: 2.24809405358e-05
非冷藏数据来自此半统计分布的概率为63.94%(p值0.6394)。 这是有道理的,因为使用这种数据创建了这种准分布,并围绕该数据进行了整形。
来自我们的总物流分布的冷藏工厂数据的可能性很小:.00224% (p值0.0000224)。 通常,如果p值小于0.05,则可以说p值“足够小”。 当我们获得“足够小的” p值时,统计数据的术语是我们观察到的结果“具有统计意义”。 我们的冷藏数据与非冷藏数据来自相同分布的可能性很低,这表明在冷藏植物时,其二氧化碳吸收的分布会发生显着变化。 我们可以通过再次使用钳工器并查看冷藏工厂数据的分布情况来验证这一点。
f = fitter(chill_plants['uptake'], bins=10)
f.verbose = false
f.fit()
best_shape_2 = f.get_best()
dst2 = list(best_shape_2.keys())[0]
print('chilled plant co2 absorbtion')
print('dstribution: {}'.format(dst2))
print('best distribution shape: {}'.format(best_shape_2[dst2]))
print('best 5 distributions, lowest 5 errors:')
f.df_errors.sort(columns=['sumsquare_error'], ascending=true).ix[:5]
chilled plant co2 absorbtion
dstribution: dweibull
best distribution shape: (2.6804403695668575, 25.999783783267702, 11.415991122238617)
best 5 distributions, lowest 5 errors:

看起来最适合冷藏工厂数据的是事实上的双重威布尔分布,其误差值为0.000780。 这种分布看起来与我们的非半成品物流的Genhalflogistic完全不同。 我们将在下面绘制双重威布尔和冷藏植物数据。 您可以将其与上图进行比较以查看差异。
rvf_dwe = stats.dweibull.pdf(x=[x for x in range(8,43)], c=best_shape_2[dst2][0], loc=best_shape_2[dst2][1], scale=best_shape_2[dst2][2])
plt.figure(figsize=(12.5,10))
plt.hist(chill_plants['uptake'], label='chilled', color='C0', alpha=0.7, normed=True, bins=10)
plt.plot([x for x in range(8,43)], rvf_dwe, label='dweibull', color='C0')
plt.xlabel('CO2 Absorbtion')
plt.ylabel('Count')
plt.legend(loc='upper left')
plt.title('Chilled pland distribution and double weibull distribution')
plt.show()

关于p值的注释:
选择p值的阈值在很大程度上是任意的,通常人们接受0.05或更低。 如今,随着数据量的增加,获得0.05的p值变得越来越容易,并且有些人倾向于将阈值设置为0.01或更低。 这是一个笑话,但实际上为解释p值提供了一些见识的漫画。
结论
鉴于p值低,我们发现针对genhalflogistic分布对冷藏的植物数据进行了测试,我们可以拒绝原假设并接受替代假设:
零假设 :低温植物不会影响其二氧化碳吸收。
替代假设 :低温植物确实会影响其二氧化碳吸收。
我们还确认,冷藏工厂数据与非冷藏数据的分布非常不同。 进一步证实了我们的假设,即低温植物确实会影响其二氧化碳的吸收。
在这篇文章中,您应该学到了:
- 假设检验是什么以及我们如何使用它来回答问题。
- 通过视觉比较在假设之间进行选择的非正式方法。
- 如何使用两个分布进行统计检验以验证假设。