本节通过垃圾邮件分类问题对系统学习系统设计展开描述。
下面分别是垃圾邮件和正常邮件:
1. 考虑哪些方法会起作用
1.1 提取特征向量
x=features of email (邮件的特征)x=features of email (邮件的特征)
y=spam(1) or not spam(0) (是否为垃圾邮件:1是、0否)
这里有一种选择邮件的一些特征变量的方法,比如说我们可能会想出一系列单词,我们可以认为这些单词能够用来区分垃圾邮件或非垃圾邮件。
比如说,如果有封邮件,包含单词deal,那么它就很有可能是一封垃圾邮件,同时包含单词buy的邮件也很有可能是一封垃圾邮件,包含discount的邮件也很有可能是垃圾邮件。
如果一封邮件中包含了我的名字,这有可能是一个知道我的人写的,说明这封邮件不太可能是垃圾邮件。因为某些原因,我认为now这个单词表明了这封邮件可能并不是垃圾邮件,因为我经常收到一些很紧急的邮件,当然还有别的单词。我们可以选出这样成百上千的单词。
因此可以用一个特征向量x来表示这些词汇是否出现在了邮件中,从而建立特征向量
从何处入手来提高分类准确度?
- 积累大量数据
从直觉上讲,是要收集大量的数据。事实上确实好多人这么做,很多人认为收集越多的数据,算法就会表现的越好。事实上就垃圾邮件分类而言,有一个叫做“Honey Pot”的项目,它可以建立一个假的邮箱地址,故意将这些地址泄露给发垃圾邮件的人,这样就能收集到大量的垃圾邮件了。这样的话我们就能得到非常多的垃圾邮件来训练学习算法了。 - 从email的header中提取路径等信息
大量的数据可能会有帮助,但也可能没有。对于大部分的机器学习问题,还有很多办法用来提升机器学习效果。比如对于垃圾邮件来说,也许你会想到用更复杂的特征变量,像是邮件的路径信息(这种信息通常会出现在邮件的标题中)。因此,垃圾邮件发送方在发送垃圾邮件时,他们总会试图让这个邮件的来源变得模糊一些,或者是用假的邮件标题,或者通过不常见的服务器来发送邮件,用不常用的路由来发送邮件。
因此可以通过邮件的标题部分来构造更加复杂的特征,来获得一系列的邮件路由信息,进而判定是不是一封垃圾邮件。 - 从email的正文中提取特征
你可能还会想到别的方法,比如从邮件的正文出发,寻找一些复杂点的特征,例如单词discount是否和单词discounts是一样的,又比如单词deal和dealer是否也应视为等同?甚至像这个例子中有的单词小写,有的单词大写。或者我们是否应该用标点符号来构造复杂的特征变量,因为垃圾邮件可能更多的使用感叹号。 - 构建错词识别算法,来区分邮件中恶意拼写错误的单词
同样的,我们也可能构造更加复杂的算法来检测或者纠正那些故意的拼写错误 ,例如m0rtgage,med1cine,w4tches。因为垃圾邮件发送方确实这么做了,因为如果你将4放到w4tches中,那么用我们之前提到的简单的方法,垃圾邮件分类器不会把w4tches和watches看成一样的,这样我们就很难区分这些故意拼错的垃圾邮件。发垃圾邮件的也很机智,他们这么做就逃避了一些过滤。
NG“说”
当我们使用机器学习时,总是可以“头脑风暴”一下,想出一堆方法来试试,就像这样。顺带一提,我有一段时间研究过垃圾邮件分类的问题,尽管我能够理解垃圾邮件分类的问题,我确实懂一些这方面的东西,但是我还是很难告诉你,这四种方法中,你最该去使用哪一种。
事实上,坦白地说,最常见的情况是:一个研究小组,可能会随机确定其中的一个方法,但是有时候,这种方法并不是最有成效的。你知道,你只是随机选择了其中的一种方法。实际上,当你需要通过头脑风暴来想出不同方法来尝试去提高精度的时候,你可能已经超越了很多人了。令人难过的是,大部分人他们并不尝试着列出可能的方法。他们做的只是某天早上醒来,因为某些原因,有了一个突发奇想:”让我们来试试 用Honey Pot项目 收集大量的数据吧”。不管出于什么奇怪的原因,早上的灵机一动,还是随机选一个,然后干上大半年。
但是我觉得我们有更好的方法,是的,我们将在随后的课程中讲到这个,那就是误差分析。
我会告诉你,怎样用一个更加系统性的方法从一堆不同的方法中选取合适的那一个。因此,你更有可能选择一个真正的好方法,能让你花上几天几周甚至是几个月去进行深入的研究。
2. 误差分析
也就是
1. 以一个你可以快速实现的简单的算法作为开始。实现它并且在交叉验证数据集上进行测试。
2. 绘制出学习曲线来进而决定是否需要更多的数据,或者更多的特征,等等。
3. 误差分析:主要检查出在你的算法下,有误差的(在交叉验证集中的)样本数据(手工检查)。具体如下:
如果你在构造一个学习算法,如果你能有一种评估你算法的方法,这将是非常有用的。
假设我们试图决定是否把像”discount”,”discounts”,”discounter”,”discountring”这样的单词都视为等同。
在自然语言处理中,这种方法是通过一种叫做词干提取的软件实现的。如果你想自己来试试,你可以在网上搜索“Porter
Stemmer(波特词干提取法)”,这是在词干提取方面一个比较不错的软件。这个软件会将单词”discount”、”discounts”等词视为同一个单词。
但是这类词干提取软件只会检查单词的开头几个字母,这虽然有用,但也可能会造成一些问题。举个例子,这个软件会把单词”universe(宇宙)”和”university(大学)”也视为同一个单词,因为他们的开头是一样的。
当你在决定是否应该使用词干提取软件来分类时,这总是很难说清楚到底是好还是坏。特别地,误差分析也并不能帮助你决定词干提取是不是一个好的方法。
与之相对地最好的方法来发现词干提取软件对你的分类器到底有没有用,是迅速的着手试一试,来看看它表现到底怎么样。
这也是为什么迅速代码实现一个相对简单的模型的原因!!!
2.3 小结
NG“说”:
当你在研究一个新的机器学习问题时,我总是推荐你实现一个较为简单快速即便不是那么完美的算法,我几乎从未见过人们是这样做。大家经常干的事情是花费大量的时间在构造算法上,构造他们以为的简单的方法,因此,不要担心你的算法太简单,或者太不完美,而是尽可能快地实现你的算法,当你有了初始的实现之后,它会变成一个非常有力的工具,来帮助你决定下一步的做法。因为我们可以先看看算法造成的错误,通过误差分析来看看它犯了什么错,然后来决定优化的方式。
另一件事,假设你有了一个快速而不完美的算法实现,又有一个数值的评估数据,这会帮助你尝试新的想法快速地发现你尝试的这些想法是否能够提高算法的表现。从而你会更快地做出决定,在算法中放弃什么,吸收什么。