6.6 分析:统计假设检验
R设计用于为统计分析人员提供各种数据检查工具。本章迄今为止所讨论的编程功能都是达到该目的的手段。我们希望使用的R主要功能是通过识别统计显著特征,支持警报的构建(更多关于警报构建的讨论参见第7章)。
识别对警报有用的属性,需要识别“重要”的行为,对“重要”有各种不同的定义。R提供了许多用于研究数据并对数据进行统计检验的工具套件。学习这些工具的使用,需要理解R工具提供的常见测试统计数字。本章余下的部分重点关注这些任务。
6.6.1 假设检验
统计假设检验是根据特定数据集中的证据,评估有关外界行为的某个断言的过程。断言可能是数据呈正态分布,或者早晨网络上发生了攻击。假设检验从可与某个模型相比较的一个假设开始,假设可能无效。假设检验的语言常常不直观,因为它依赖于科学的一个关键属性——科学无法证明某个断言,但是可以证明断言错误,或者无法证明断言正确。所以,假设检验专注于“拒绝零假设”。
统计假设从所谓的“零假设”(null hypothesis,H0)开始。最基本的零假设是数据集中的变量之间没有关系。备择假设(H1)是零假设的反面——有证据说明某种关系。零假设的检验是这样进行的:用一个过程建立零假设模型,然后比较该过程生成的数据符合零假设推断的可能性。
例如,考虑确定硬币重量均匀还是一面比另一面重的测试过程。我们通过重复抛硬币来进行测试。零假设声明正面和反面的概率相等:P=0.5。备择假设声明重量偏向某一面。
为了确定硬币的重量是否均匀,我们必须多次抛掷它。构造检验的问题是,我们必须抛掷硬币多少次,才能做出决定。图6-3显示了1~4次抛掷中,结果组合的概率分解1。
https://yqfile.alicdn.com/948fb2012019811c57c11445fb738641b70fe506.png" >
结果遵循二项分布,我们可以用R的dbinom函数计算。2
> # 使用dbinom求得4次抛掷硬币且单次抛掷正面向上概率为0.5时,
> # 出现0-4次正面朝上的概率
> dbinom((0:4),4,p=0.5)
[1] 0.0625 0.2500 0.3750 0.2500 0.0625
> #结果按照顺序显示——0次、1次、2次、3次、4次正面朝上
为了确定结果是否显著,我们必须确定偶然发生结果的概率。在统计检验中,这通过使用P值来实现。P值是“零假设为真”的概率,你所得到的结果至少和观测结果一样极端。P值越低,观测结果在零假设下发生的概率就越低。按照惯例,在P值小于0.05时拒绝零假设。
为了理解“极端性”的概念,考虑4次抛掷硬币无一成功的二项检验。R中的命令如下:
> binom.test(0,4,p=0.5)
Exact binomial test
data: 0 and 4
number of successes = 0, number of trials = 4, p-value = 0.125
alternative hypothesis: true probability of success is not equal to 0.5
95 percent confidence interval:
0.0000000 0.6023646
sample estimates:
probability of success
0
P值为0.125,是4次都掷出正面(0.0625)和4次都掷出反面(0.0625)的概率之和。在“2次反面”的语境下,这个P值考虑的是两个极端状况。类似的,如果我们考虑1次正面的情况:
> binom.test(1,4,p=0.5)
Exact binomial test
data: 1 and 4
number of successes = 1, number of trials = 4, p-value = 0.625
alternative hypothesis: true probability of success is not equal to 0.5
95 percent confidence interval:
0.006309463 0.805879550
sample estimates:
probability of success
0.25
得出的P值为0.625,即0.0625+0.25+0.25+0.0625(除了2次正面和2次反面的情况之外,其他各种组合的概率)。
6.6.2 检验数据
用R进行的最常见检验是检验特定的数据集是否符合某种分布。对于信息安全和异常检测,数据符合某种分布使我们可以估计警报阈值。话虽如此,我们很少真正碰到数据符合某种分布模型的情况(正如第10章中所讨论的)。确定一种现象符合某种分布模型,你就可以使用该分布的特征函数预测数值。
这种估算过程的经典例子,是使用均值和标准差预测正态分布值。正态分布有如下形式的概率密度函数:
\frac{1}{{\sigma \sqrt {2\pi } }}{\text{e}} - \frac{{(x - \mu )^2 }}{{2\sigma ^2 }}$
其中,μ是均值,σ是模型的标准差。
如果流量符合分布模型,就为我们提供了一个估计某种现象发生概率的数学工具。正如第10章中所述,真正遇到满意模型的机会很少——当你遇到这些模型时,通常已经进行了繁重的数据过滤工作,并进行多次探索,提取出合适的信息。
这一点很重要,因为如果你在不知道模型是否有效的情况下就采用相应的数学方法,就可能有建立错误传感器的危险。R提供许多现存的不同统计检验,以确定你是否可以使用某种模型。为了简洁起见,本文主要关注两种提供基本工具的测试。
Shapiro-Wilk (shapiro.test)
Shapiro-Wilk检验很适合于正态分布的检验,使用它可以检验样本集是否符合正态分布。
Kolmogorov-Smirnov (ks.test)
适合于检验连续分布(如正态或者均匀分布)。
这些检验的操作方式类似:对一个样本集和另一个样本集(明确提供或者通过函数调用)运行检验函数。检验的统计数字描述了符合程度,并生成一个p值。
Shapiro-Wilk检验(shapiro.test)是正态性检验,零假设是提供的数据是正态分布的。例6-4是运行这种检验的一个例子。
例6-4 运行Shapiro-Wilk检验
># 检验随机正态分布函数是否通过shapiro检验
> shapiro.test(rnorm(100,100,120))
> Shapiro-Wilk normality test
data: rnorm(100, 100, 120)
W = 0.9863, p-value = 0.3892
> #我们很快将解释这些数字
> #检验均匀分布函数是否通过shapiro检验
> shapiro.test(runif(100,100,120))
Shapiro-Wilk normality test
data: runif(100, 100, 120)
W = 0.9682, p-value = 0.01605
所有统计检验都会生成一个检验统计数字(在Shapiro-Wilk检验中是W),这是与零假设下分布的比较。统计数字的准确取值和解读是特定于检验的,应该使用p值作为该值的规范化解读。
Kolmogorov-Smirnov检验(ks.test)是一种简单的适合度检验,用于确定某个数据集是否符合特定的连续分布(例如正态或者均匀分布)。它可以与一个函数(在这种情况下,它将提供的数据集与函数进行比较)或者两个数据集(在这种情况下,对照这两个数据集)一起使用。实际的检验参见例6-5。
例6-5 使用ks检验
> # KS检验实例;我们创建两个随机的均匀分布
> a.set <- runif(n=100, min=10, max=20)
> b.set <- runif(n=100, min=10, max=20)
> ks.test(a.set, b.set)
Two-sample Kolmogorov-Smirnov test
data: a.set and b.set
D = 0.07, p-value = 0.9671
alternative hypothesis: two-sided
> #现在,我们使用函数比较一个数据集和分布模型
> #注意,我使用punif来得到分布,传递的参数和单独调用punif时一样
> ks.test(a.set, punif, min=10, max=20)
One-sample Kolmogorov-Smirnov test
data: a.set
D = 0.0862, p-value = 0.447
alternative hypothesis: two-sided
> #在使用该检验之前,我需要一次估算。
> #对于均匀分布,可以使用最小和最大值,就像在正态分布中使用均值和标准差一样
> ks.test(a.set,punif,min=min(a.set),max=max(a.set))
One-sample Kolmogorov-Smirnov test
data: a.set
D = 0.0829, p-value = 0.4984
alternative hypothesis: two-sided
> #现在,我拒绝这个零假设;我将把这些数据当成正态分布,再次估算
> ks.test(a.set,pnorm,mean=mean(a.set),sd=sd(a.set))
One-sample Kolmogorov-Smirnov test
data: a.set
D = 0.0909, p-value = 0.3806
alternative hypothesis: two-sided
> #嗯,p值也不高啊…因为我没有使用足够的样本,我们用400个样本再次检验
> a.set<-runif(400,min=10,max=20)
> b.set<-runif(400,min=10,max=20)
> #相互比较
> ks.test(a.set,b.set)$p.value
[1] 0.6993742
> #比较均匀分布
> ks.test(a.set,punif,min=min(a.set),max=max(a.set))$p.value
[1] 0.5499412
> #比较不同的分布
> ks.test(a.set,pnorm, mean = mean(a.set),sd=sd(a.set))$p.value
[1] 0.001640407
KS的统计效能(Power)较弱。试验的效能指的是正确拒绝零假设的能力。效能较弱的检验需要比效能较强的检验更大的样本数量。样本大小是复杂的问题,特别是在处理安全数据的时候。大部分统计检验来自于“海底实验室”,在实验室中获得60个样本就已经是很了不起的成就了。但是对于网络流量分析,可以采集海量的样本,检验可能因为太多数据而变得不可靠,和常态的小偏差可能造成某些检验拒绝数据,你总是可以投入更多数据,有效地制作出符合目标的检验。
在我的经验中,对于好的可视化工作,分布检验通常是糟糕的第二选择。第10章将更深入地讨论这一点。