文档过滤(集体智慧编程第6章)

来源:互联网 发布:java简单聊天代码 编辑:程序博客网 时间:2024/05/17 19:18

    文档分类是机器智能(machine intelligence)的一个应用,很有实用价值,而且越来越普及。关于文档过滤,最有价值也是人们所熟知的应用,恐怕要数垃圾邮件过滤了。本章中介绍的算法不是专门针对垃圾信息的。由于这些算法可以解决更为一般的问题,即学习并鉴别文档所属的分类,因此我们还可以将其应用于一些相比垃圾信息而言不那么令人生厌的问题。一种可能的应用就是根据邮件的征文自动将收件箱中的邮件划分为社交类邮件和工作类邮件。

      过滤垃圾信息

      早期使用的是基于规则的分类器,使用时会有人事先设计好一组规则,用以指明某条信息是否属于垃圾信息。垃圾信息制造者知道了这些规则后,就会避开这些规则。,其行为变得更加隐蔽。也就是垃圾信息事先我们是不能100%确定的,为了解决这一问题,本章所要考察的程序会在开始阶段和逐渐收到更多信息之后,根据人们提供给它的有关哪些是垃圾邮件,哪些不是垃圾邮件的信息,不断地进行学习。通过这种方法我们可以分别为不同的用户、群组或网站建立起各自的应用实例和数据集,它们对垃圾信息的界定将逐步形成自己的观点。

     文档和单词

     即将构造的分类器须要利用某些特征来对不同的内容项进行分类。所谓特征,是指任何可以用来判断内容中具备或缺失的东西。当考虑对文档进行分类时,所谓的内容就是文档,而特征就是文档中的单词。当将单词作为特征时,其假设是:某些单词相对而言更有可能会出现在垃圾信息中。这一假设是大多数垃圾信息过滤器背后所依赖的基本前提。不过,特征未必一定是一个个单词;它们也可以是词组或短语;或者任何可以归为文档中缺失或存在的其他东西。

    编写一些函数来从文档中提取特征。

    对分类器进行训练

    本章中讨论的分类器可以通过接受训练的方式来学习如何对文档进行分类。如果分类器掌握的文档及其正确分类的样本越多,其预测的效果也就越好。人们专门设计分类器,其目的也就是在此,即:从极为不确定的状态开始,随着分类器不断了解到那些特征对于分类而言更为重要,其确定性也在不断地增加。

     针对不同的用户、群组或查询,建立起多个分类器实例,并分别对它们进行训练,以响应特定群组的需求。

    计算概率

     既然我们已经对一封邮件在每个分类中的出现次数进行了统计,那么接下来的工作就是要将其转化为概率了。所谓概率就是一个0~1之间的数字,用以指示某一事件发生的可能性。在本例中,可以使用一个单词在一篇属于某分类的文档中出现的次数,除以该分类的文档总数,计算出单词在分类中出项的概率。这个概率为条件概率,通常标记为Pr(A|B),在给定B的条件下A的概率,在本例中,求的值为Pr(word|classification),即:对于一个给定的分类,某个单词出现的概率。比如,在三篇归类为"good"的文档中,有两篇出现了单词"quick",即:一篇"good"分类的文档中包含该单词的概率为:pr(quick|good)=0.666。

     从一个合理的推测开始

      以上的训练数据有个问题-----只根据以往见过的信息,会令其在训练的初期阶段,对于那些极少出现的单词变得异常敏感。在训练用的样本数据中,单词"money"只在一篇文档中出现过,并且由于这是一则设计赌博的广告,因此文档被归为了"bad"类,由于单词"money"在一篇'bad'中出现过,而任何‘good’类得文档中都没有该单词,所以使用上述方法计算出的‘money’在‘good’分类中出现的概率为0.这样做完全有点偏激,因为‘money’可能完全是一个中性词,只是恰好先出现在了一篇‘bad’类得文档而已。伴随着单词越来越多地出现在同一个分类的文档中,其对应的概率值也逐渐接近于0,恐怕这样才能更合理些。

      为了解决上述问题,在我们手头掌握的有关当前特征的信息极为有限时,我们还需要根据一个假设的概率来做出判断。一个推荐的初始值为0.5.我们还需要为假设的概率赋予以多大的权重----权重为1代表假设概率的权重与一个单词相当,返回一个加权的概率。

     在单词'money'的例子中,针对‘money’的加权概率对于所有的分类而言均是从0.5开始的。待到在classifier训练期间接受一篇'bad'分类的文档时,并且范闲‘money’适合于‘bad’分类时,其针对‘bad’分类的概率就会变成0.75,这是因为:

    (weight * assumedprob + count*fprob)/(count + weight)

    = (1*1.0 + 1 * 0.5)/(1.0 + 1.0) = 0.75

 

   选择0.5作为假设的概率初试值仅仅是因为它介于0和1的正中间。不过,也有可能我们已经掌握了更多的背景信息,从而使假设更加有据可依,这一点即便对于一个完全没有经过训练的分类器而言,也是可能的。不管咋样,对于一个过滤器而言,它最好应该有能力处理极少会出现的单词。

      朴素分类器

       一旦我们求出了指定单词在一篇属于某个分类中出现的概率,就需要有一种方法将各个单词的概率进行组合,从而得出整篇文档属于该分类的概率。本章将考虑两种不同的分类方法。这两种方法在大多数场合下都是可以使用的,只不过它们在面对特定任务时,在算法的性能级别上有些微的不同,本节中要讨论朴素贝叶斯分类器。它假设将要被组合的各个概率是彼此独立的,事实上这个假设是不成立的。这意味着,我们无法将采用朴素贝叶斯所求的的结果实际用作一篇文档属于某个分类的概率,因为这种独立性的假设会使其得到错误的结果。不过,我们还是可以对各个分类的计算结果进行比较,再看哪个分类的概率最大。在现实中,若不考虑假设的潜在缺陷,朴素贝叶斯分类器将被证明是一种非常优秀的文档分类方法。

   计算整篇文档的概率

  贝叶斯定理:

     pr(A|B) = Pr(B|A)*Pr(A)/Pr(B)

  在本例中,即为:

Pr(Category|Document) = Pr(Document|Category)*Pr(Category)/Pr(Document)

 Pr(Document|Category)计算方法已经介绍过,Pr(Category)是随机选择一篇文档属于该分类的概率,因此就是属于该分类的文档数除以文档的总数。

 至于Pr(Document),我们也可以计算它,但是这将会是一项不必要的工作。请记住,我们不会将这一计算结果当做真实的概率值。相反,我们会分别计算每个分类的概率值,然后对所有的计算结果进行比较。由于不论计算的是哪个分类,Pr(Document)的值都是一样的,其对结果所产生的影响也完全是一样的,因此我们完全可以忽略这一项。

     选择分类

    构造朴素贝叶斯分类器的最后一步是实际判定某个内容项所属的分类。此处最简单的方法,是计算被考察内容在每个不同分类中的概率,然后选择一个最大的分类。但是在一些应用中,对于分类器而言,承认不知道答案,要好过判断答案就是概率值稍大一些的分类。垃圾邮件过滤就是这情况。所以定义一个最小阈值,也就是对于一封将要被划归到某个分类的新邮件而言,其概率与针对所有其他分类的概率相比,必须大于某个指定的数值才行。

       费舍尔方法

      是前面介绍的朴素贝叶斯方法的以风格替代方案,它可以给出非常精确的结果,尤其适合来及信息过滤。与朴素贝叶斯过滤器利用特征来计算整篇文档的概率不同,费舍尔方法为文档的每个特征都求得了分类的概率,然后又将这些概率组合起来,并判断其是否有可能构成一个随机集合。该方法还会返回每个分类的概率,这些概率彼此间可以进行比较。尽管这种方法更为复杂,但是因为她在为分类选择临界值时允许更大的灵活性,所以还值得一学的。

     针对特征的分类概率

      计算Pr(category|feature)的常见方法为:

    (具有指定特征的属于某分类的文档数)/(具有指定特征的文档总数)

    上述计算公式并没有考虑我们收到某一分类的文档可能比其他分类更多的情况。所以也应该初始化一个固定概率,加权。

   将各概率值组合起来

   现在我们须要对应各个特征的概率值组合起来,形成一个总的概率值。理论上我们可以将它们连乘起来,利用相乘的结果在不同的分类间进行比较。当然由于特征不是彼此独立的,所以不能代表正式的概率,但是比贝叶斯分类要好不少了。

    对内容项进行分类

    在这可以每个分类设定下限,然后分类。

    将经过训练的分类器持久化

    在任何真实世界的应用中,所有的训练和分类工作都不太可能完全在一次会话中完成,所以将训练的结果保存在数据库中。

    与本章所介绍的分类器相比,神经网络和支持向量机的一个很大的优势:它们可以捕获到输入特征之间更为复杂的关系。

原创粉丝点击