《Arduino家居安全系统构建实战》——2.3 组合多个单词

2.3 组合多个单词

使用贝叶斯定理,我们找出了根据是否包含特定单词分类SMS的方法。这是一个进展,但是我们还远没有完成任务。一条消息中有许多单词,每个都以不同的强度表现非垃圾短信和垃圾短信的特征。如何将这些信息(它们可能传递相互矛盾的信号)组合为用于决策的单一值?

2.3.1 将文本分解为标记

举个例子,考虑下面这条假设的短信:“Driving, cant txt.”它是垃圾短信的概率有多高?

我们可以直接应用贝叶斯定理,在数据集中搜索整条短信。但是,这种方法估计不会有很好的效果。找到精确复制的概率很小,更不要说多个单词的精确复制了。另一方面,我们已经看到单词“FREE”携带一些相关信息。

我们要做的就是简单地将短信分解为一组单词:“driving”“cant”和“txt”,并用某种表现形式代替原始文本。然后,分析单独标记并将它们所代表的组合为单一值,据此做出决定。

将文本块分解为有意义的元素(单词或者其他符号)——标记(Token)的过程称作标记化。决定如何标记化是模型的重要部分,没有任何独特的正确方法——取决于所要解决的问题。现在,我们和以往一样从能够实施的最简单方法入手:如果一个单词“FREE”的信息量很丰富,扩展这一想法,将短信分解为单个单词。实际上,我们将把每条短信转换为一组特征,每个特征中存在或者不存在某个特定单词。

例如,如果我们有两个字符串“Programming is Fun”(编程很有趣)和“Functional programming is more fun!”(函数式编程更有趣!),可以将它们分解为“programming”“is” “fun”和“functional”“programming”“is”“more”“fun”。这种表现方式使我们可以更加高效,不需要检查某条消息是否包含特定的子字符串,可以将每个文档处理为一组标记,快速验证是否包含我们感兴趣的特殊标记。

■ 注意:

这一通用方法对于将文本转换为计算机可以处理的形式很有用。例如,我们可以收集语料库中找到的整组标记——[“functional”; “programming”; “is”; “more”; “fun”]——并通过计算每个标记找到的次数,对每个文档进行编码。第一个文本块变成[0; 1; 1; 0; 1],第二个文本块变成[1; 1; 1; 1; 1]。我们的数据集现在采用了人类完全不可读的形式,和第1章中的数字数据集很相似:每一行是一个观测值,每一列是一个特征,所有内容都编码为数字——例如,我们可以用这些数据确定两个文档的相似度。将观测值转换为一组计算机可以分析寻找模式的数字型特征(人类无法做到),是机器学习中很典型的做法。
这时,你可能会想:“这是严重的过度简化”,你是对的。毕竟,我们将整个句子转换成一组原始的单词,忽略了句法、语法或者词序。这种转换明显丢失了信息。例如,“I like carrots and hate broccoli”(我喜欢胡萝卜,讨厌花椰菜)和“I like broccoli and hate carrots”(我喜欢花椰菜,讨厌胡萝卜)这两个句子转换成同一组标记[and; broccoli; carrots; hate; i; like],因此被认为是完全一样的。与此同时,我们没有尝试理解句子的含义,只需要识别与特定行为有联系的词语。

我要强调的另一点是,虽然我们的标记化看起来相当简单,但是已经包含了许多隐含的决策。我们决定将“Programming”和“programming”当成同一个词,忽略大小写。这是个合理的假设吗?可能是,也可能不是。如果你曾经参加过在线讨论(如论坛或者YouTube评论),可能同意大量使用大写字母往往代表着讨论质量正在走下坡路。因此,这证明大小写很重要,可能提供分类消息的相关信息。另一个隐含的决定是丢弃“!”,这合理吗?标点也可能很重要。

好消息是,我们无须争论大小写或者标点符号是否重要,可以很容易地在以后的交叉验证中得到这个问题的答案。正如W. Edwards Deming的不朽名言:“我们信仰上帝——其他人都必须用数据证明自己。”为每个假设创建不同的模型,比较它们的表现,让数据做出决定。

2.3.2 简单组合得分

现在我们已经决定将短信分解为3个标志——“driving”“cant”和“txt”——仍然必须想出计算消息是非垃圾短信或垃圾短信概率的方法。“txt”表明有很大的概率是垃圾短信,而“driving”则指向非垃圾短信。我们如何组合所有证据?如果应用贝叶斯定理,确定在包含全部3个标记的条件下,某条短信是垃圾短信的概率,可以得到如下算式:

这个公式看上去有些可怕。但是,如果我们做一个简化的假定,事情就容易多了。我们假定这些标记相互独立——也就是说,在一条短信中看到一个标记对其他标记是否出现没有任何影响。在这种情况下,计算公式是:

P (SMS包含driving、cant、txt |SMS是垃圾短信 )

      =P (SMS包含“driving”| SMS是垃圾短信 )

      ×P (SMS包含“cant”| SMS是垃圾短信 )

      ×P (SMS包含“txt”| SMS是垃圾短信 )

对以上公式,借用一点点贝叶斯定理的“柔道”翻身之术,可以得到如下结果:

从根本上,我们做了如下工作:没有尝试建立完整、复杂的英语模型,而是使用简单得多的模型。想象一下,你有两个装单词的大桶,一个用于垃圾短信,另一个用于非垃圾短信,它们包含的单词所占比例不同。消息通过从其中一个桶里随机选择单词组合生成。当然,这是相当可笑的语言模型。与此同时,该模型也有一些明显的好处。更“正确”的模式可能专用于特定语言(例如需要考虑其语法和句法),因而有可能对其他语言无效。因此,从较差但对任何语言或者文档类型效果相似且容易处理的模型开始,看看它会将我们引向何方!

2.3.3 简化的文档得分

现在,我们几乎已经为编码实现分类器做好了准备。我们可以轻松求取P(SMS是垃圾短信)——训练集中垃圾短信的比例,以及P(SMS包含“X”|SMS是垃圾短信)——包含标记“X”的垃圾短信比例。

投入工作之前,先进行一些最后的调整。首先,你可能已经注意到,在垃圾短信和非垃圾短信中,冗长的贝叶斯公式都包括同一除数项——P(SMS包含“driving”“cant”“txt”)的运算。最终,我们感兴趣的是决定一条消息是垃圾短信还是非垃圾短信,而不是精确的概率。在这种情况下,我们可以去掉公共项,节约不必要的计算,简单地计算“得分”而非概率。

Score (SMS是垃圾短信|SMS包含driving、cant和txt )

           =P (SMS包含“driving”| SMS是垃圾短信 )

           ×P (SMS包含“cant”| SMS是垃圾短信 )

           ×P (SMS包含“txt”| SMS是垃圾短信 ) × P(SMS是垃圾短信 )

如果Score(垃圾短信)>Scrore(非垃圾短信),我们将把消息归类为垃圾短信。

实际上,如果我们仅需要一个得分,可以进一步解决另一个问题——与精度相关的问题。 从定义上看,从短信中任何特定标记上观察到的概率都是小于1的数字(通常接近0)。由于我们的公式包含这些概率的乘积,结果也接近0,可能造成舍入误差。

为了避免这一问题,习惯上是使用一种旧的技巧,将计算转换为对数。这方面的细节不是很重要,但正是使用这种方法的原因。因为log (a * b) = log a + log b,可以将公式从乘积转换成总和,避免了舍入问题。而且,因为对数是递增函数,通过对数转换公式将保留得分的排名。所以,我们使用如下公式代替原公式,求得消息的分数:

Score (SMS是垃圾短信 | SMS包含driving、cant和txt )=log (P ( SMS是垃圾短信 ))+

log(Laplace (SMS包含“driving”| 垃圾短信 ))+

log(Laplace (SMS包含“cant”| 垃圾短信 ))+

log(Laplace (SMS包含“txt”| 垃圾短信 ) )

在一定程度上,上式澄清了算法逻辑。每个标记都有一个非垃圾短信得分和垃圾短信得分,量化了它属于这两种情况的强度。尝试决定某个文档是不是垃圾短信时,算法首先计算垃圾短信得分——垃圾短信基准水平,每个标记都增加或者减少文档的垃圾短信得分,独立于其他标记。如果文档的垃圾短信得分最终高于非垃圾短信得分,则判定文档是垃圾短信。

时间: 2024-09-12 20:50:53

《Arduino家居安全系统构建实战》——2.3 组合多个单词的相关文章

《Arduino家居安全系统构建实战》——2.2 根据一个单词决定

2.2 根据一个单词决定 有了数据,我们就可以开始分析了.我们的最终目标是区分垃圾短信和非垃圾短信,但是和数字识别器的情况不同,我们还没有一组清晰的特征,唯一的材料是原始文本块--SMS本身.与此同时,人们会猜测文本中有许多信息可供利用.我们只需要找到一个途径,将这些字符串转换成可以使用的特征即可. 2.2.1 以单词作为线索 如果你仔细观察刚刚加载的数据集,就可能会注意到垃圾短信看起来和非垃圾短信有些不同.浏览这些短信,你的眼睛很容易找出某些值得警惕的线索,暗示着某一条短信可能是垃圾短信.举个

《Arduino家居安全系统构建实战》——第1章 家居安全系统的入门知识

第1章 家居安全系统的入门知识 Arduino家居安全系统构建实战在这一章中,我们将会介绍如下的内容: 什么是家居安全基础设施它是如何工作的部署这样一个系统都需要些什么在当前条件下为安全系统所做的准备有线安全系统和无线安全系统传统系统与现代化家居安全系统为了紧紧跟随硬件的发展趋势,本书介绍了随处可见且价格极为低廉的平台--Arduino.今时今日,我们可以在各种各样的公共场所如中小学校.高等院校.小型企业或者公共机构见到这个小电路板的身影. Arduino平台因其众多的优势而著名,例如低廉的成本

《Arduino家居安全系统构建实战》——导读

前言 机器学习项目开发实战 如果你手里拿着这本书,我就可以认定你是对机器学习感兴趣的.NET开发人员了.你可能对编写C#应用程序很熟悉,开发的很有可能是业务线应用程序.以前你可能遇到过F#,也可能没有.而且,你很有可能对机器学习感到好奇.这一主题每天都见诸报端,因为它和软件工程有着很紧密的联系,但是使用的是不熟悉.看似有些抽象的数学概念.简而言之,机器学习看上去是有趣的主题.值得学习的实用技能,但是从哪里入手难以说清. 本书的意图是作为开发人员的机器学习入门书.我的主要目标是使熟悉代码编写的读者

《Arduino家居安全系统构建实战》——1.2 工作原理

1.2 工作原理 之前讨论了家居安全系统基本的组成部分,但是这些要素都是什么,它们是如何工作的呢?通过对它们进行分类,我们可以将一个安全系统分成两个部分. 1.2.1 硬件部分 一个基础设施的硬件要素必须能够胜任软件的所有技术需求.可以将它们进一步细分为3个不同的子类别.这种分类方式不应该被理解为具有排斥性,因为一个要素经常可以被分到多个子类别中,这种分类方式反而有助于你理解系统所执行的功能. 传感器:传感器将作为系统的感觉器官,其作用就如同人类的身体感官.它们的功能就是从环境中搜集信息,并将这

《Arduino家居安全系统构建实战》——1.6 传统系统与现代化的家居安全系统的比较

1.6 传统系统与现代化的家居安全系统的比较 最后,我们将给出一个传统系统与现代化系统之间的比较,值得指出的是,在面对不同需求的时候,它们各自都有着特定的用处,这些需求例如减少模型的复杂性,提高系统的可靠性,增加系统可用性以及向开发者提供丰富的信息. 以前,如果综合考虑到多种因素,例如价格.技术的成熟度以及现有的基础设施(连接)等,以一个较低的成本来实现一个可以实时管理的系统几乎是不可能的. 而在智能手机和平板电脑已经普及的今天,这些设备有足够的能力来将硬件收集的数据即时进行发送和接收,并实现这

《Arduino家居安全系统构建实战》——1.1 家居安全的基础设施

1.1 家居安全的基础设施 当然,如果你被问到一个关于安全系统组成部分的问题,你可能会毫不犹豫地对这个问题做出回答,例如,你可能会就监控摄像头.运动传感器和报警器等设备侃侃而谈.但是你确实了解这些不同的组成模块了吗?你能清楚地说出它们之间所有的关联吗?你能详细地讲出它们的工作方式吗?你能准确地说出传统的系统和当前的系统的区别吗?不要着急,这些答案都将为你揭晓. 好了,现在我们这里已经有这些问题的答案了.安全基础设施包括了所有的硬件设备.软件部分以及它们之间关联的设计,将所有这些组件组合在一起构成

《Arduino家居安全系统构建实战》——1.3 部署安全系统的先决条件

1.3 部署安全系统的先决条件 如果你正在考虑部署一个安全系统,那么最有可能的原因就是你有这方面的关键需求.因此,在这里最重要的事情就是要准确地确定这种需求.如果做不到这一点,我们最终会步入歧途并造成损失或者导致半途而废. 如果并没有这种需求,你只是拥有着一颗对现代科技勇于探索的心,那么你可能是出于学习和娱乐的目的来设计这个系统,或者试图将自己的家打造成一个现代化的场所.你可以浏览一下这个行业的先进企业的网站以获得参考. 我们可以看到,大多数企业的系统是类似的,只是在某些部分存在一些差异,而这些

《Arduino家居安全系统构建实战》——2.6 改进分类器

2.6 改进分类器 现在我们已经有了基准-- 低于84.4%是糟糕的结果,至少要超过87.7%.是时候观察使用可以自由支配的两大手段(标记化程序和分类器选用的标记)能达到什么效果了. 2.6.1 使用每个单词 利用一个单词,我们就能将分类器的正确率从84.8%提升到87.7%.如果使用每个可用的标记代替单个词汇,预测正确率当然应该大幅提高.我们来尝试一下这个思路,首先,必须从训练集中提取每个标记.我们编写一个vocabulary函数,对每个文档应用标记化程序,将标记合并为单一集合,实现上述功能.

《Arduino家居安全系统构建实战》——2.5 训练第一个分类器

2.5 训练第一个分类器 实现通用算法之后,我们最终可以回到手上的问题--识别哪些消息是非垃圾短信,哪些是垃圾短信.Train函数的签名提供了目标的清晰概况:要获得分类器,需要一个示例训练集.一个标记化程序和选用的标记.我们已经得到了训练集,现在的目标是使用交叉验证指导分析,确定标记化程序和标记的最佳组合. 2.5.1 实现第一个标记化程序 考虑到上述情况,我们先完成可行的最简单工作,首先是标记化.我们所要做的是取得一个字符串,将其分解为单词,忽略大小写. 这项工作需要正则表达式:\w+模式匹配