精华内容
下载资源
问答
  • 题目 评估Auto数据集上拟合多个线性模型所产生的测试错误率。...交叉验证,顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测...

    题目

          评估Auto数据集上拟合多个线性模型所产生的测试错误率。Auto数据集是存在与ISLR程序包中的一个摩托车相关数据的数据集,读者可自行下载ISLR程序包,并将Auto数据集加载。

    相关资料

          交叉验证是在机器学习建立模型和验证模型参数时常用的办法。交叉验证,顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏。在此基础上可以得到多组不同的训练集和测试集,某次训练集中的某样本在下次可能成为测试集中的样本,即所谓“交叉”。

    那么什么时候才需要交叉验证呢?交叉验证用在数据不是很充足的时候。比如在我日常项目里面,对于普通适中问题,如果数据样本量小于一万条,我们就会采用交叉验证来训练优化选择模型。如果样本大于一万条的话,我们一般随机的把数据分成三份,一份为训练集(Training Set),一份为验证集(Validation Set),最后一份为测试集(Test Set)。用训练集来训练模型,用验证集来评估模型预测的好坏和选择模型及其对应的参数。把最终得到的模型再用于测试集,最终决定使用哪个模型以及对应参数。

    回到交叉验证,根据切分的方法不同,交叉验证分为下面三种:

    第一种是简单交叉验证,所谓的简单,是和其他交叉验证方法相对而言的。首先,我们随机的将样本数据分为两部分(比如: 70%的训练集,30%的测试集),然后用训练集来训练模型,在测试集上验证模型及参数。接着,我们再把样本打乱,重新选择训练集和测试集,继续训练数据和检验模型。最后我们选择损失函数评估最优的模型和参数。

    第二种是S折交叉验证(S-Folder Cross Validation)。和第一种方法不同,S折交叉验证会把样本数据随机的分成S份,每次随机的选择S-1份作为训练集,剩下的1份做测试集。当这一轮完成后,重新随机选择S-1份来训练数据。若干轮(小于S)之后,选择损失函数评估最优的模型和参数。

    第三种是留一交叉验证(Leave-one-out Cross Validation),它是第二种情况的特例,此时S等于样本数N,这样对于N个样本,每次选择N-1个样本来训练数据,留一个样本来验证模型预测的好坏。此方法主要用于样本量非常少的情况,比如对于普通适中问题,N小于50时,我一般采用留一交叉验证。

    通过反复的交叉验证,用损失函数来度量得到的模型的好坏,最终我们可以得到一个较好的模型。那这三种情况,到底我们应该选择哪一种方法呢?一句话总结,如果我们只是对数据做一个初步的模型建立,不是要做深入分析的话,简单交叉验证就可以了。否则就用S折交叉验证。在样本量少的时候,使用S折交叉验证的特例留一交叉验证。

    此外还有一种比较特殊的交叉验证方式,也是用于样本量少的时候。叫做自助法(bootstrapping)。比如我们有m个样本(m较小),每次在这m个样本中随机采集一个样本,放入训练集,采样完后把样本放回。这样重复采集m次,我们得到m个样本组成的训练集。当然,这m个样本中很有可能有重复的样本数据。同时,用没有被采样到的样本做测试集。这样接着进行交叉验证。由于我们的训练集有重复数据,这会改变数据的分布,因而训练结果会有估计偏差,因此,此种方法不是很常用,除非数据量真的很少,比如小于20个。

            随机抽样函数sample介绍:

     

    > x=1:10
    
    > sample(x=x)
    [1]  3  5  9  6 10  7  2  1  8  4

            第一行代码表示给x向量x赋值,第二行代码表示对x向量进行随机抽样。结果输出为每次抽样抽得的结果,可以看出该抽样为无放回抽样-最多抽n次,n为向量中元素的个数。

           如果想指定在该向量中抽取元素的个数,需要加一个参数size:

    > x=1:1000
    
    > sample(x=x,size=20)
    
    [1]  66 891 606 924 871 374 879 573 284 305 914 792 398 497 721 897 324 437
    
    [19] 901  33

           这是在1~1000的正整数中抽样,其中size指定抽样的次数,抽了20次,结果如上所示。

           这些都是无放回抽样。所谓无放回抽样,也就是说某个元素一旦被选择,该总体中就不会再有该元素。如果是有放回抽样,则需添加一个参数repalce=T:

    > x=1:10
    
    > sample(x=x,size=5,replace=T)
    
    [1] 4 7 2 4 8

           “replace”就是重复的意思。即可以重复对元素进行抽样,也就是所谓的有放回抽样。我们看上面的结果,元素4在5次随机抽样的过程中被抽取了两次。

           如果我们输入代码的位置与某个函数中参数的位置一一对应的话,我们可以不写该函数的参数,如:

    > x=1:10
    
    > sample(x,20,T)
    
    [1] 1 2 2 1 5 5 5 9 9 5 2 9 8 3 4 8 8 8 1 1

          简单运用:对于掷骰子,投硬币(这可能是介绍抽样必介绍的内容),都属于有放回抽样。

           这里要说明,对于sample函数,参数x可以是数值,也可以是字符,实际上参数x代表任意一个向量:

    > a=c("A","B")
    
    > sample(x=a,size=10,replace=T)
    
    [1] "B" "A" "A" "A" "B" "A" "A" "B" "A" "A"

          上述代码可以理解为掷硬币,抛了10次,其中正面(A)与反面(B)出现的次数是可以重复的。

         上述抽样过程,每一个元素被抽取的概率相等,称为随机抽样。

         有时候我们的抽取元素的概率未必相等(如常见的二项分布概率问题),此时我们需要添加一个参数prob,即:“probability”(概率)的缩写。假设一名医生给患者做某手术成功的概率是80%,那么现在他给20例病人做手术,可能有哪几次是成功的呢?代码如下:

    > x=c("S","F")
    
    > sample(x,size=20,replace=T,prob=c(0.8,0.2))
    
    [1] "F" "S" "S" "S" "S" "S" "S" "S" "S" "S" "S" "S" "F" "S" "S" "F" "S" "S"
    
    [19] "F" "S"

         其中“S”代表成功,“F”代表失败。

    > x=c(1,3,5,7)
    
    > sample(x,size=20,replace=T,prob=c(0.1,0.2,0.3,0.9))
    
    [1] 3 5 7 3 7 3 7 5 3 7 7 7 1 5 7 5 7 7 3 7

          这些代码告诉我们,对每一个元素都可以给定一个概率,且每个概率是独立的,即在参数prob中,不一定所有元素的概率加起来等于1,它只代表某元素被抽取的概率而已。

         对于sample函数,其参数x可以是R中任意一个对象(如上述对字符的抽样)。其中还有一个功能相同的函数sample.int,“int”即“intger”的缩写,也就是“整数”。它的参数n必须是正整数:

    > x=-10.5:7.5
    
    > sample(x=x,size=3)
    
    > sample.int(n=x,size=3)
    
    [1] -5.5 -7.5  0.5
    
    Error in sample.int(x, size = 3) : invalid first argument

            第一行代码生成了-10.5到7.5的等差数列,结果输出的第一行是sample的结果;第二行是sample.int的结果,提示错误:“第一个自变量无效”,因为它不是正整数。其余的用法与ample是一样的。

     

    实验

          在开始之前,用 set. seed ()函数来为 R 的随机数生成器设定一个种子 (seed) .这样就就可以得到与下面展示的完全相同的结果。通常来说,使用一种如同交叉验证法这样包含随机性的分析方法时,可以设定一个随机种子,这样下次就可以得到完全相同的结果。

           首先用 sample()函数把观测集分为两半,从原始的 392 个观测中随机地选取一个有 196 个观测的子集,作为训练集。

    > library(ISLR)
    > set.seed(1)
    #产生从1-392中抽样出196个数。
    > train=sample(392,196)
    [1] 324 167 129 299 270 187 307  85 277 362 330 263 329  79 213  37 105
    [18] 217 366 165 290 383  89 289 340 326 382  42 111  20  44 343  70 121
    [35]  40 172  25 248 198  39 298 280 160  14 130  45  22 206 230 193 104
    [52] 367 255 341 342 103 331  13 296 375 176 279 110  84  29 141 252 221
    [69] 108 304  33 347 149 287 102 145 118 323 107  64 224 337  51 325 372
    [86] 138 390 389 282 143 285 170  48 204 295  24 181 214 225 163  43   1
    [103] 328  78 284 116 233  61  86 374  49 242 246 247 239 219 135 364 363
    [120] 310  53 348  65 376 124  77 218  98 194  19  31 174 237  75  16 358
    [137]   9  50  92 122 152 386 207 244 229 350 355 391 223 373 309 140 126
    [154] 349 344 319 258  15 271 388 195 201 318  17 212 127 133  41 384 392
    [171] 159 117  72  36 315 294 157 378 313 306 272 106 185  88 281 228 238
    [188] 368  80  30  93 234 220 240 369 164

             用 lm() 函数中的 subset 选项,只用训练集中的观测来拟合一个线性回归模型。

    > lm.fit=lm(mpg~horsepower,data=Auto,subset=train)

           现在用 predict ()函数来估计全部 392 个观测的响应变量,再用 mean() 函数来计算验证集中 196 个观测的均方误差。注意一下,下面的 -train 指标意味着只选取不在训练集中的观测。(说明:‘-’就是subset)

    > attach(Auto)
    > mean((mpg-predict(lm.fit,Auto))[-train]^2)
    [1] 23.26601

         从以上数据可以看出用线性回归拟合模型所产生的测试的均方误差估计为 23.26601。下面用 poly ()函数来估计用二次和三次多项式回归所产生的测试误差。

    > lm.fit2=lm(mpg~poly(horsepower,2),data=Auto,subset=train)#poly函数估计二次
    > mean((mpg-predict(lm.fit2,Auto))[-train]^2)
    [1] 18.71646
    > lm.fit3=lm(mpg~poly(horsepower,3),data=Auto,subset=train)#和三次
    > mean((mpg-predict(lm.fit3,Auto))[-train]^2)
    [1] 18.79401

           这两个错误率分别为 18.71646 和 18.79401。如果选择了一个不同的训练集的话,那就会在验证集上 得到一个不同的误差。

    > set.seed(2)
    > train=sample(392,196)
    > lm.fit=lm(mpg~horsepower,subset=train)
    > mean((mpg-predict(lm.fit,Auto))[-train]^2)
    [1] 25.72651
    > lm.fit2=lm(mpg~poly(horsepower,2),data=Auto,subset=train)
    > mean((mpg-predict(lm.fit2,Auto))[-train]^2)
    [1] 20.43036
    > lm.fit3=lm(mpg~poly(horsepower,3),data=Auto,subset=train)
    > mean((mpg-predict(lm.fit3,Auto))[-train]^2)
    [1] 20.38533

            案例分析完毕,小伙伴们学到了没有(*^_^*)
     

    展开全文
  • 交叉验证

    千次阅读 2018-07-10 17:11:33
    交叉验证(Cross Validation)是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据进行分组,一部分做为训练集(training set),另一部分做为验证集(validation set),首先用训练集对...
      交叉验证(Cross Validation)是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据进行分组,一部分做为训练集(training set),另一部分做为验证集(validation set),首先用训练集对分类器进行训练,在利用验证集来测试训练得到的模型(model),以此来做为评价分类器的性能指标。常见的交叉验证方法如下:

    留出法 Hold-Out Method

      将原始数据随机分为两组,一组做为训练集,一组做为验证集,利用训练集训练分类器,然后利用验证集验证模型,记录最后的分类准确率为此分类器的性能指标。此种方法的好处的处理简单,只需随机把原始数据分为两组即可,其实严格意义来说Hold-Out Method并不能算是CV,因为这种方法没有达到交叉的思想,由于是随机的将原始数据分组,所以最后验证集分类准确率的高低与原始数据的分组有很大的关系,所以这种方法得到的结果其实并不具有说服性。


    2-折交叉验证 (2-fold Cross Validation,记为2-CV)

      做法是将数据集分成两个相等大小的子集,进行两回合的分类器训练。在第一回合中,一个子集作为training set,另一个便作为testing set;在第二回合中,则将training set与testing set对换后,再次训练分类器,而其中我们比较关心的是两次testing sets的辨识率。不过在实务上2-CV并不常用,主要原因是training set样本数太少,通常不足以代表母体样本的分布,导致testing阶段辨识率容易出现明显落差。此外,2-CV中分子集的变异度大,往往无法达到“实验过程必须可以被复制”的要求。

    K-折交叉验证(K-fold Cross Validation,记为K-CV)

        将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型,用这K个模型最终的验证集的分类准确率的平均数作为此K-CV下分类器的性能指标。K一般大于等于2,实际操作时一般从3开始取,只有在原始数据集合数据量小的时候才会尝试取2。K-CV可以有效的避免过学习以及欠学习状态的发生,最后得到的结果也比较具有说服性。

    留一法(Leave-One-Out Cross Validation,记为LOO-CV)

    如果设原始数据有N个样本,那么LOO-CV就是N-CV,即每个样本单独作为验证集,其余的N-1个样本作为训练集,所以LOO-CV会得到N个模型,用这N个模型最终的验证集的分类准确率的平均数作为此下LOO-CV分类器的性能指标。相比于前面的K-CV,LOO-CV有两个明显的优点:
    (1)每一回合中几乎所有的样本皆用于训练模型,因此最接近原始样本的分布,这样评估所得的结果比较可靠。
    (2)实验过程中没有随机因素会影响实验数据,确保实验过程是可以被复制的。
    但LOO-CV的缺点则是计算成本高,因为需要建立的模型数量与原始数据样本数量相同,当原始数据样本数量相当多时,LOO-CV在实作上便有困难几乎就是不显示,除非每次训练分类器得到模型的速度很快,或是可以用并行化计算减少计算所需的时间。
    展开全文
  • 5折交叉验证的回归分析

    万次阅读 2016-12-27 16:05:12
    R语言 5折交叉验证的回归分析
    w<-read.csv("C:\\Users\\Administrator\\Desktop\\mg.csv",header=T)
    #样本的个数为1385,5折交叉验证
    n=1385
    zz1=1:n
    zz2=rep(1:5,ceiling(1385/5))[1:n]
    set.seed(100)
    zz2=sample(zz2,n) #有放回抽样
    NMSE=rep(0,5)
    NMSE0=NMSE
    for(i in 1:5){
      m=zz1[zz2==i]
      a<-lm(y~.,w[-m,]) #线性回归模型
      y0<-predict(a,w[-m,]) #对训练集集预测
      y1=predict(a,w[m,])  #对测试集预测
      NMSE0[i]=mean((w$y[-m]-y0)^2)/mean((w$y[-m]-mean(w$y[-m]))^2)
      NMSE[i]=mean((w$y[m]-y1)^2)/mean((w$y[m]-mean(w$y[m]))^2)
    }
    NMSE0=mean(NMSE0) #训练集的标准化均方误差
    NMSE=mean(NMSE) 
    展开全文
  • 交叉验证 部分参考:模型选择中的交叉验证方法综述,山西大学,范永东(这是一篇硕士论文,原文内容有点啰嗦,存在一些错误。本文对其交叉验证部分校对整理) 交叉验证是一种通过估计模型的泛化误差,从而进行模型...

    交叉验证
    部分参考:模型选择中的交叉验证方法综述,山西大学,范永东(这是一篇硕士论文,原文内容有点啰嗦,存在一些错误。本文对其交叉验证部分校对整理)

    交叉验证是一种通过估计模型的泛化误差,从而进行模型选择的方法。没有任何假定前提,具有应用的普遍性,操作简便, 是一种行之有效的模型选择方法。

    1. 交叉验证的产生
    人们发现用同一数据集,既进行训练,又进行模型误差估计,对误差估计的很不准确,这就是所说的模型误差估计的乐观性。为了克服这个问题,提出了交叉验证。基本思想是将数据分为两部分,一部分数据用来模型的训练,称为训练集;另外一部分用于测试模型的误差,称为验证集。由于两部分数据不同,估计得到的泛化误差更接近真实的模型表现。数据量足够的情况下,可以很好的估计真实的泛化误差。但是实际中,往往只有有限的数据可用,需要对数据进行重用,从而对数据进行多次切分,得到好的估计。

    2. 交叉验证方法
    留一交叉验证(leave-one-out):每次从个数为N的样本集中,取出一个样本作为验证集,剩下的N-1个作为训练集,重复进行N次。最后平均N个结果作为泛化误差估计。
    留P交叉验证(leave-P-out):与留一类似,但是每次留P个样本。每次从个数为N的样本集中,取出P个样本作为验证集,剩下的N-P个作为训练集,重复进行CPNCNP次。最后平均N个结果作为泛化误差估计。
    以上两种方法基于数据完全切分,重复次数多,计算量大。因此提出几种基于数据部分切分的方法减轻计算负担。 
    - K折交叉验证:把数据分成K份,每次拿出一份作为验证集,剩下k-1份作为训练集,重复K次。最后平均K次的结果,作为误差评估的结果。与前两种方法对比,只需要计算k次,大大减小算法复杂度,被广泛应用。

    3.模型选择方法的评价
    衡量一个模型评估方法的好坏,往往从偏差和方差两方面进行。

    3.1偏差
    交叉验证只用了一部分数据用于模型训练,相对于足够多的数据进行训练的方法来说,模型训练的不充分,导致误差估计产生偏差。

    相对来说,留一交叉验证,每次只留下一个作为验证集,其余数据进行训练,产生泛化误差估计结果相对 真值偏差较小。很多文献表明留一交叉验证在回归下的泛化误差估计是渐进无偏的。

    留P交叉验证,取决于P的大小,P较小时,等同于留一交叉验证的情况。P较大,会产生较大的偏差,不可忽略。

    K折交叉验证,同样取决于K的大小。K较大时,类似留一交叉验证;K较小时,会产生不可忽略的偏差。

    训练数据越小,偏差越大。当偏差无法忽略时,需要对偏差进行纠正。

    3.2方差
    对于一个模型,训练数据固定后,不同的验证集得到的泛化误差评估结果的波动,称之为误差评估的方差。

    影响方差变化的因素,主要有数据的切分方法,模型的稳定性等。

    训练数据固定的情况下,验证集中样本数量越多,方差越小。 
    模型的稳定性是指模型对于数据微小变化的敏感程度。

    4.针对K折交叉验证的k的选择,及偏差和方差分析
    对于k的选择,实践中一般取k =10。这里有一种情况,k = N,(N为训练样本数量)。在这种情况下,k折交叉验证也称为留一交叉验证(leave-one-out cross validation)。由于在留一交叉验证中,每一次训练模型的样本几乎是一样的,这样就会造成估计的偏差很小但方差很大的情况出现,另外,需要调用N次学习算法,这在N很大的时候,对于计算量也是不小的开销。

    另一方面,如果取k = 10,那么交叉验证的方差会降低,但是偏差又会成为问题,这取决于训练样本的数量。当训练样本较小时,交叉验证很容易有较高的偏差,但是随着训练样本的增加,这种情况会得到改善。
    --------------------- 
    作者:evillist 
    来源:CSDN 
    原文:https://blog.csdn.net/evillist/article/details/76009632 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • 为何需要使用交叉验证交叉验证

    千次阅读 2019-05-11 10:29:50
    交叉验证是一种模型验证技术,可用于评估统计分析(模型)结果在其它独立数据集上的泛化能力。它主要用于预测,我们可以用它来评估预测模型在实践中的准确度。 验证集和训练集必须满足独立同分布条件,否则交叉验证...
  • 在训练数据的过程或者参加数据比赛的时候,常常会遇到数据量不够大的情况,想充分利用不多的数据进行有说服力力的验证,从而选到一个对分类至关重要的参数,可以采用—K折交叉验证法(k-fold CrossValidation),下面...
  • 数据分析交叉验证

    千次阅读 2019-09-16 21:14:50
    一、交叉检验cross-validation(CV): 以k-fold CV为例:在k个fold中,每个fold依次作为测试集、余下的作为训练集,进行k次训练,得到共计k个参数。把k个参数的均值作为模型的最终参数。 优点:最大特点是不再浪费...
  • 交叉验证思想

    2017-08-02 11:24:00
    交叉验证 写一个函数,实现交叉验证功能,不能用sklearn库。 交叉验证(Cross-Validation): 有时亦称循环估计, 是一种统计学上将数据样本切割成较小子集的实用方法。于是可以先在一个子集上做分析, 而其它子集则...
  • 机器学习之交叉验证

    千次阅读 2019-01-30 16:30:56
    1.交叉验证简介 交叉验证(Cross Validation) 是在机器学习建立模型和验证模型参数时常用的方法。顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集。用训练集来训练模型,测试集...
  • 交叉验证原理

    千次阅读 2016-04-13 10:39:53
    交叉验证(Cross-Validation): 有时亦称循环估计, 是一种统计学上将数据样本切割成较小子集的实用方法。于是可以先在一个子集上做分析,而其它子集则用来做后续对此分析的确认及验证。 一开始的子集被称为训练集。而...
  • 几种交叉验证法(超详细)

    万次阅读 多人点赞 2018-01-23 12:17:08
    交叉验证交叉验证是一种用来评价一个训练出的模型是否可以推广到另一个数据结构相同的数据集上的方法。主要用于PCR 、PLS 回归建模等建模应用中。主要用于估计一个预测模型在实际数据应用中的准确度。它是一种统计学...
  • 交叉验证 python

    千次阅读 2018-05-22 16:51:21
    以下简称交叉验证(Cross Validation)为CV.CV是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set),首先...
  • 常用的交叉验证方法

    千次阅读 2018-05-10 16:10:42
    引用自http://blog.sina.com.cn/s/blog_67331d610102vl2t.html中内容交叉验证(CrossValidation)方法思想 交叉验证(Cross Validation)简称为CV,是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将...
  • 模型评估-交叉验证

    千次阅读 2018-10-25 15:48:51
    交叉验证原理小结 原文链接:https://www.cnblogs.com/pinard/p/5992719.html#4098395 交叉验证是在机器学习建立模型和验证模型参数时常用的办法。交叉验证,顾名思义,就是重复的使用数据, 把得到的样本数据...
  • 交叉验证(cross_validation)

    千次阅读 2017-04-22 21:22:45
    交叉验证是数据分析时模型选择的方法之一,将数据集分为三份,分别为训练集(training set),验证集(valication set)和测试集(test set),分别功能为训练模型,选择模型和对学习方法的评估。其算法的思想为重复...
  • 在MATLAB中使用交叉验证函数的方法

    万次阅读 多人点赞 2015-05-17 15:45:04
    在MATLAB中使用交叉验证函数的方法。...交叉验证主要用于评估统计分析或机器学习算法的泛化能力等。 在评估机器学习算法的泛化能力时,我们可以选择随机分割后的一部分数据作为训练样本,另一部分作为测试样本。
  • 交叉验证及其目的

    千次阅读 2017-12-26 16:08:00
    首先,为什么要交叉...2.对于一个模型,参数的选择会影响结果,所以用交叉验证选择最合适的参数 然后,常用的交叉验证的方式是k折交叉验证(k-fold cross validation) 把数据集分为训练集和测试集: 先把所有...
  • k-折交叉验证

    千次阅读 2019-06-18 20:52:58
    )较小的k值会导致可用于建模的数据量太小,所以小数据集的交叉验证结果需要格外注意,建议选择较大的k值。 2.理论上:使用了交叉验证,模型方差“应该”降低了。 在理想情况下,我们认为k折交叉验证可以 O(1/k)O(1/...
  • 交叉验证评估模型性能

    千次阅读 2018-03-21 22:46:20
    为了使模型能够在欠拟合和过拟合之间找到一个折中方案,我们需要对模型进行评估,后面将会介绍holdout交叉验证和k折交叉验证,通过这两种方法,我们可以获得一个模型泛化误差的可靠估计,也就是模型在新数据上的性能...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 59,462
精华内容 23,784
关键字:

交叉验证结果分析