您的位置:首页 > 其它

机器学习之&&Andrew Ng课程复习--- 机器学习系统设计

2014-12-08 16:30 369 查看
Prioritizing what to Work on
接下来我们将谈到机器学习系统的设计,主要涉及你在设计复杂的机器学习系统时会遇到的问题,同时我们会给出一些如何构建一个复杂的机器学习系统的建议。接下来的讨论可能连贯性不够,但是它集中的表述了你在设计机器学习系统时可能会遇到的不同问题,虽然这些内容数学性不强,但是对于我们设计机器学习系统非常有用,从而节省大量时间。

首先我们要讲的是,当我们设计机器学习系统时会遇到问题。首先我们来看一个例子:

假如你想建立一个垃圾邮件分类器:

首先我们来看两封邮件,左边是一封垃圾邮件Spam,右边是一封非垃圾邮件Non-Spam:(垃圾邮件还是很聪明的,故意拼写错一些单词。比如w4tchs、med1cine)



假设:我们有加过标签的训练集,包括标注的垃圾邮件,表示为spam = 1 和非垃圾邮件spam = 0,我们如何以监督学习的方法来构造一个分类器,来区分垃圾邮件和非垃圾邮件呢?为了应用监督学习,我们必须首先确定的是如何用邮件的特征构造向量X,给出训练集中的特征X和标签Y,我们就能够训练出某种分类器,比如用逻辑回归,这里有一种选择邮件的一些特征变量的方法,比如我们可能会想出一系列单词或成百上千的单词,我们认为这些单词能够用来区分垃圾邮件或非垃圾邮件。(观察上面样本,垃圾邮件有许多features,那么我们想要建立一个Spam分类器,就要进行有监督学习,将Spam的features提取出来,而希望这些features能够很好的区分Spam
vs. Non-Spam)

如下图所示,我们提取出来deal,buy,discount,now等100个feature,建立一个feature向量:



我们根据一份邮件如上图右边这份,单词的出现与否,来得到这份邮件对应的feature向量(暂不考虑单词出现频率),这里我们是人工选择了100个看似是spam feature的feature作为特征,但在实际中,我们只需遍历整个训练集,选取spam中词频率最高的100,000 到50,000取而代之。

如果你正在建立一个垃圾邮件分类器,你会遇到这样一个问题:如何在有限的时间和精力下改进你的方法,从而使得你的垃圾邮件分类器具有较高的准确度。

1、从直觉上来讲是要收集大量的训练数据,事实上确实很多人这么做,很多人认为收集越多数据,算法就会表现的越好。事实上,就垃圾邮件分类而言,有一个叫做”Honey Pot”的项目,它可以建立一个假的邮箱地址,故意将这些地址泄露给发垃圾邮件的人,这样就收到了大量的垃圾邮件,这样我们就得到了非常多垃圾邮件来训练学习算法。

2、但是我们在前面的学习中知道,大量数据有可能有帮助,有可能没有。对于大部分机器学习问题,我们还有其他方法用来提升机器学习的效果。比如对于垃圾邮件而言,你会想到用更加复杂的特征变量,比如邮件的路径信息,但是垃圾邮件发送者也很聪明,他们试图模糊这些信息,或者用假的邮件标题,或者通过不常见的服务器、路由来发送垃圾邮件,所以我们可以根据邮件的标题部分构建更加复杂的特征,来获得邮件的路由信息,进而判断这是否是一份垃圾邮件。

3、你可能还会想到其他方法,比如从邮件的正文出发,建立复杂精确的feature库,比如”discount”、是否和”discounts”是一样的,有的单词小写,有的单词大写,或者我们是否用标点符号来构造复杂的特征变量,因为垃圾邮件可能会更多的感叹号。

4、同样我们也可能构造更加复杂的算法来检测或者纠正那些故意的拼写错误如上面邮件那样,如果用简单的方法来预测,我们不会将这些拼写错误的词汇(其实就是垃圾词汇)当做其垃圾邮件的特征,从而过滤掉它,影响我们的判断。

当然,上述策略并非全部奏效,如下面的练习题所示:



当我们构建机器学习系统的时候,我们总可以 “头脑风暴”一下,(This is Why I love Machine Learning)想出一堆方法来试试,就像上面这样。Ng说:当你尝试用 “头脑风暴”去想想一个问题:why,why and why,how,how and how。那么你已经超越了很多人!!!接下来,我们会讲到误差分析,怎么用一个更加系统的方法从一堆不同的方法中选取合适的那个(比如上面4个方法,-。-这是嘲讽Honey
Pot吗?不是,是交流吧,哈哈),你更有可能选择一个真正的好方法,在有限时间和精力里做深入的研究。

Error Analysis
上一节我们已经学习了面对机器学习问题,有很多提高算法表现的方法,在这节我们来看看误差分析的概念,这会更系统的帮助你做出决定。
如果你想学习机器学习系统或者构建机器学习系统最好的实践方法不是建立一个非常复杂的系统,拥有多么复杂的变量,而是构建一个简单的算法,这样你可以很快地实现它,每当我研究机器学习的问题时,最多花一天时间,就是24小时,来试图很快的把结果搞出来,即便效果不好,即使没用复杂的系统。但是只是很快的得到结果,即便运行的不完美,也把它运行一遍,最后通过交叉验证集来检验数据,一旦做完,你可以画learning curve,通过画出学习曲线以及检验误差,来找出你的算法是否有高偏差和高方差的问题,或者别的问题,这样的分析后再来决定用更多的数据训练,或者加入更多的特征变量是否有用,这么做对于刚接触机器学习来说效果很好,你并不能提前知道,你是否需要复杂的特征变量、你是否需要更多的数据
and son on…..但是你可以先做个简单的模型,然后通过learning curve来决定你的优化决策,这防止了电脑编程里的过早优化问题,这证明,我们需要用证据来领导我们的决策,怎么样分配自己的时间来优化算法,而不仅仅是自觉。除了LC,误差分析也是很有帮助的在我们构建机器学习系统过程中,比如构建垃圾邮件分类器时,我们可以观察交叉验证数据集,哪些邮件被算法错误的分类,通过这些被算法错误分类的垃圾邮件与非垃圾邮件,你可以发现某些系统性的规律,什么类型的邮件总是被错误分类,这样可以启发你构造新的特征变量,或者告诉你现在这个系统的缺点,然后启发你如何去提高它,具体的说,这里有一个例子。
我们仍然假设你正在构建一个垃圾邮件分类系统,你拥有500个实例在交叉验证集中,
假设在这个例子中,算法有非常高的误差率,它错误分类了一百个交叉验证实例,所以我们需要人工检查这100个错误,然后手工为它们分类,基于例如,这些是是类型的邮件,哪些变量能帮助这个算法能正确分类它们,比如我们分析这个100个被分类错误的邮件,可能会发现比如有关药物的邮件容易被误分类,基本这些邮件都是卖药的,或者卖假表、假货的邮件、钓鱼邮件等等,我们检查这些误分类集,讲起分类为以下类别:
1、建立Simple system并在CV set上做测试后,我们进行error analysis步骤,将所有spam分为pharma,replica/fake,Steal password 和其他,这四类。
2、找到一些可能有助于改善分类效果的features。



另外在构造一个机器学习系统的时候小技巧是:利用数值计算的方式来评估你的机器学习算法,而非是直觉(直觉这东西总骗人!)这种用数字说话方式,你的算法可能精确、可能有错,但它能准确的告诉你你的算法到底表现有多好,我们来看看例子:



这里,我们不要感性地去想,而是最好用数字体现效果。比如对于discount/discounts…是否应该都视为含有discount这个feature,我们不应该主观的去想,而是看如果都含有这个feature,那么结果是有3%的error,如果不都看做有这个feature,则有5%的error,由此可见哪种方法比较好。

PS:Ng为大家推荐了词干分析的一个软件,”Porter stemmer”。是否区分大小写同理。

Error Metrics for Skewed Classes

在前面,我们提到了误差分析,以及设定误差度量值的重要性,那就是设定某个实数来评估你的学习算法,并衡量它的表现,有了算法的评估和误差的度量值,有一件重要的事情要注意,就是用一个合适的误差度量值,这有时会对于你的学习算法造成非常微妙的影响,这种情况被称作是Skewed Classes 偏斜类的问题。那么我们来看看它是什么意思?

想想之前的癌症分类问题,我们拥有内科病人的特征变量,我们希望知道他们是否患有癌症,这就像恶性肿瘤和良性肿瘤的分类问题。我们假设Y=1表示患者患有癌症,否则Y=0.我们训练逻辑回归作为预测,假设我们用测试集检验了这个分类模型,并且发现它只有1%的错误,99%的做出了正确判断,看起来是个不错的结果。但是假如我们发现在测试集中,只有0.5%的患者真正得了癌症,因此在我们的筛选程序里,只有0.5%的患者患了癌症,因此在这个例子里,1%的错误率就不在显得那么好了,举个具体的例子:

function y=predictCancer(x)

y=0; %即忽略x中feature的影响

return;

以上代码不是机器学习代码,它忽略了输入值X,它让Y总等于0,因此它总是预测没人得癌症,那么以上的算法只有0.5%的错误率,因此这甚至比我们之前通过LR得到的1%的效果更好,这种情况发生在正例负例的比例非常接近一个极端,在这个例子中,正样本的数量与负样本的数量相比,非常非常少,我们把这种情况叫偏斜类。一个类的数据与另一个类的数据相比,多很多,通过总是预测Y=0或者Y=1算法可能表现的非常好,因此使用了分类误差或者分类精确度,来评估度量可能会产生如下问题,假如你有一个算法,它的精确度是99.2%,你对你的算法做出了一点改动,得到了99.5%的精确度,这到底是不是一个算法的提升呢?用某个实数来作为评估度量值的一个好处是它可以帮助我们迅速决定,我们是否需要对算法做出一些改动,但是如果你有一个偏斜类,分类精确度并不能很好的衡量算法的性能。这时我们需要一个不同的误差度量值或者不同的评估度量值。其中一种评估度量值叫做查准率和召回率。我们引入了Error
Metrics这个概念:

考虑一个二分问题,即将实例分成正类(positive)或负类(negative)。对一个二分问题来说,会出现四种情况。如果一个实例是正类并且也被预测成正类,即为真正类(True positive),如果实例是负类被预测成正类,称之为假正类(False positive)。相应地,如果实例是负类被预测成负类,称之为真负类(Truenegative),正类被预测成负类则为假负类(falsenegative)。
TP:正确肯定的数目;

FN:漏报,没有正确找到的匹配的数目;

FP:误报,给出的匹配是不正确的;

TN:正确拒绝的非匹配对数;

这样就可以建立一个Error Metrics(下图左),并定义precision和recall,如下图所示:



precision:正确预测正样本/我所有预测为正样本的;
recall:正确预测正样本/真实值为正样本的;
当且仅当Precision和Recall都高的时我们可以认为该predict算法work well !

这样我们即使有一个偏斜类,通过计算离这俩值我们也能准确判断出模型的好坏。PS:最后需要提醒大家的是,关于哪边作为true,哪边作为false的问题。对于上面那个问题,我们给定cancer的为true,实际应用中,我们应当在binary classification中指定类中sample较少的那一类作为true,另一类作为false。

Trading off Precision andRecall
(精读和召回率)间权衡
在上节我们谈到准确率和召回率,作为遇到偏斜类问题的评估度量,在很多应用中,我们希望能够保证准确率和召回率的相对平衡,在这节我们将学习应该怎么做!同时也向你展示一些准确率和召回率作为算法评估度量值的更有效的方式。

回忆一下,以下是查准率和召回率的定义



我们仍然用癌症分类的例子,如果患癌症则Y =1,分之Y =0,假设我们用LR模型训练数据,输出概率在0-1之间,具体如下图:



以上模型,我们可以计算准确率和召回率,这时阀值(threshold)等于0.5,但是阀值的不同,会有不同的准确率和召回率关系,

例如,我们希望在很确信的情况下才告诉病人患有癌症,这时我们的threshold相对较高比如0.7,该情况下:Higher threshold、Higher Precision、Lower recall。因为我们在很确信(得病概率高)的情况下,预测准确率Higher,但是我们只给很小一部分的病人预测Y=1,。

相反,我们为了避免漏掉患有癌症的人,即我们希望避免假阴性,比如病人确实患有癌症,但是我们并没有告诉他患有癌症,这可能造成严重后果,使得病人不能尽早的治疗,这时我们不在设置高的Threshold,相反较低,该情况下:Hight recall、Low Precision、Low threshold。

那么准确率和召回率之间的关系是怎么样的呢?如下图所示:



上图显示,随着Threshold变化,Precision和Recall不同,不同的数据,不同的算法,其曲线形式不同,但有一条规律不变:

threshold高对应高precision低recall;
threshold低对应低precision高recall;

但是Threshold有没有办法自动选取一个最佳值呢?或者说,如果我们有不同的算法、不同的想法,我们如何比较不同的准确率和召回率?如下图:



前面小节,我们已经知道比较算法的好坏最好的办法是通过评估值(数值)

比较,这样清晰明了,但是现在有俩个值,我们该如何比较?

也许你会想到计算准确率和召回率的平均值:

Average:(P+R)/2 看看那个模型有最高值。但事实证明这不是好的解决方案。



如图所示:Algorithm 3 的Average最高,但是我们发现recall=1,即predict所有y = 1,这显然违背了我们的初衷。这里我们介绍一个评价标准:F1-Score.






我们可以从公式中看到,F1 Scord不仅考虑了P和R的平均,而且考虑到了给P和R中小的一个加大权重,特别当,P=0 or R=0时,f = 0;P=1 && R=1时,f =1,最大;所以我们一般用F1 Scord来衡量一个算法的性能,也就是平衡Precision and Recall。

习题:



综上:这一节我们学习了如何权衡准确率和召回率,以及如何变动临界值来决定我们希望预测Y=1,还是Y=0,比如我们希望有一个70%还是90%置信度的临界值,通过变动临界值,你可以控制权衡准确率和召回率,最后我们讲到了F1 Scord,给了你一个评估度量值。当然如果你想自动选择临界值,来决定你希望预测y=1还是y=0,那么理想中一个不错的方法是,试一试不同的临界值,试一下不同临界值,然后评估这些不同的值,在交叉验证集上进行测试,然后选择哪一个临界值能够在交叉验证集上取得最高的F Scord。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐