<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thinking in A.I.</title>
	<atom:link href="http://thinkbot.info/feed/" rel="self" type="application/rss+xml" />
	<link>http://thinkbot.info</link>
	<description>imagine a smarter planet</description>
	<lastBuildDate>Sat, 19 Mar 2011 06:04:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>实验设计与分析(1)—简介</title>
		<link>http://thinkbot.info/2011/03/%e5%ae%9e%e9%aa%8c%e8%ae%be%e8%ae%a1%e4%b8%8e%e5%88%86%e6%9e%901%e2%80%94%e7%ae%80%e4%bb%8b/</link>
		<comments>http://thinkbot.info/2011/03/%e5%ae%9e%e9%aa%8c%e8%ae%be%e8%ae%a1%e4%b8%8e%e5%88%86%e6%9e%901%e2%80%94%e7%ae%80%e4%bb%8b/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 03:58:36 +0000</pubDate>
		<dc:creator>shuo wang</dc:creator>
				<category><![CDATA[数学]]></category>
		<category><![CDATA[实验设计与分析]]></category>

		<guid isPermaLink="false">http://thinkbot.info/?p=356</guid>
		<description><![CDATA[      我们大多数人，都有着对我们的世界进行更深刻了解的渴望。因为，如果知道了一些事物的规律，我们就有可能在此基础上，凭借自己的双手使我们的生活变得更加舒适美好。当然，我们并没有必要苛求自己变成科学达人，能够洞悉诸如量子物理这等高深的学问。因为，就算精通了流体力学，我们也可能依然不会游泳。大多数情况下，我们更加希望知道如何在生活上进行一些小小的改变，能够大大提高我们的幸福感。比如如何配比糖、盐和醋的比例，能让鱼香肉丝尝起来更美味，或者在哪几个零件上滴几滴润滑油能使我们心爱的自行车骑起来更省力。至于糖、醋、盐如何在油锅里相互作用，我们就没必要弄个清楚了。        对于如何提升我们的幸福感，我有一个好消息。那就是我们可以通过一些力所能及的实验来得到想要的答案。我们并不需要一个无菌实验室，也不大需要一打精密昂贵的实验设备（大概制备这些设施所带来的心痛，会残忍得吞噬掉我们的实验所带来的幸福感）。我们只需要确定一个研究对象，知道如何评价以及必要的设备。哦，大概还需要一台电脑，能够帮助我们处理一下数据。       如何进行我们的实验呢？这里我们以泡茶为例，来对实验过程进行一个简单的描述。       研究问题：如何泡茶才能够使其味道更加清香甜美。       实验目的：通过实验，找到改变泡茶的质量的方法，从而使我们充分享受绿茶所带来的美好感受。       实验前提：我们只对一种茶叶进行试验，比如同一袋铁观音。       实验步骤：       1. 列出所有可能影响茶水质量的因素。       在这里，我们需要使用头脑风暴，找出所有可能的因素。对于这个泡茶的课题，我能想到的因素有以下几种：水的来源（自来水，纯净水）；水的温度；水的多少；茶叶的多少；容器类别（玻璃杯，搪瓷杯，紫砂）。当然，对于这个问题，不同人会有不同的见解。我们也可以很无厘头地认为让茶水接受日光的照射，能够对其品质产生巨大的影响。不过根据常识，日光这个因素除了使实验变得复杂之外，大概不会带来其他意外的惊喜。所以，在这个步骤中，我们一定要充分运用我们的常识或者专业知识，指导我们筛选所需考虑的因素，力求做到稳、准、狠。这将对实验的效率产生重要的影响。       2. 进行因析设计，找出关键因素。       在这一步骤中，我们需要回答两个问题。（1）步骤1中所列出的因素，对茶水的质量的影响分别有多大？（2）哪些因素的影响可以区别于实验中的噪声，即哪些因素确实产生了影响？       为了回答以上问题，我们需要两种工具：因析设计与假设检验。       因析设计是实验设计方法中，一种十分简便并且行而有效的方法。因析设计的目的，是考察每个因素多个水平对结果影响的差异（如1克铁观音与3克铁观音）。通过因析设计，我们可以计算出所有因素主效应的大小，以及因素间交互作用的大小。对于我们的泡茶实验，可以能够得出五个主效应值的大小，分别为水的来源，水的温度，水的多少，茶叶多少以及容器类别。因素间的交互作用也就是因素之间的共同作用。其中两因素的交互作用共有10种，三因素的交互作用共有10种，四因素的交互作用共有5种，五因素交互作用1种。通过相应的计算，这些交互作用的大小也可以得到。看到这里，我们大概会想，对于五因素的因析设计，我们就有2^5-1种作用需要考虑。如果因素多些，那么其作用的总数就会以指数方式上升了！其实，我们并不需要过分担心这个问题。因为根据前人的经验，三因素或者三因素以上的交互作用很少发生，所以我们只需要注意主效应以及两因素交互作用，这将大大减小我们的工作量。另外，我们可以对因析设计进行改进，使得使用较少的实验，依然能够得出我们想要的结果。如果想知道我们该怎么做，我以后会慢慢道来。       假设检验是我们实验过程中，使用的另外一个强有力的工具。它能够从统计学的角度帮助我们判断一个命题是不是可以否定。通过假设检验，我们将能够把产生影响的因素从噪声中挑选出来，从而缩小考虑的范围，使我们的实验更加有的放矢。       3. 应用响应曲面法，寻找最优因子配比。       通过实验步骤2，我们费了许多力气，终于把真正在背后捣鬼的因素给揪了出来。所以，在步骤3中，我们就需要把这些因子研究个真真切切，明明白白。其实，在这里，我们需要做的事情并不复杂。我们需要在因子以及茶的味道之间建立某种数学关系。什么关系呢？当然，一个数学表达式就不错。有什么好方法呢？没错，最小二乘！如果这些因子的交互作用并不明显，我们可以拟合出一个一阶表达式。比如我们知道只有水温、茶叶量以及水量是主要因素。那么我们就可以得到茶的味道y与因子水温x1、茶叶量x2和水量x3的如下表达式：                                                           其中 第一项为常量， x前的希腊字母为因子系数，最后一项为误差。       但是，很多情况下，交互作用是明显的。比如水多茶少，味道就太淡。相反，茶多水少，味道就会过于苦涩。那么， 与 就存在交互作用。此时，我们需要拟合的表达时就会复杂一些，因为需要考虑所有二阶表达量。于是我们可以得到如下表达式：　　　　 　                                         　　       从拟合的公式可以看出，无论是一阶还是二阶（不考虑误差），在空间中都表示一个光滑的曲面。这就好办了，那么在给定的范围内，这个函数必然存在极值。这就是我们要的结果。下面拿起求导这个武器，不费吹灰之力的，我们就能够找到三个因子各取什么值的时候，我们能得到最佳口感。        4. 结果验证。 　　通过步骤３，我们已经知道了当水温为多少，茶叶放多少，水放多少的情况下，我们的茶最为可口。不过，为了保证效果，我们最好再做一些实验来验证效果。这里会出现两种情况。如果最优值所对应的因子在我们因析设计所考虑的范围内，那么一般情况下，结果不会有过大的偏差。但是，如果在考虑的范围外，那么我们得到的表达式就存在失拟的可能。在这种情况下，如果茶水的口感与我们所预期的相差甚远，那么很不幸，大概我们要从步骤２开始，重新把以上过程走一遍了。别灰心，别灰心，我们之前的工作并没有白费。因为我们可以从之前的结果得到了更多关于最优值可能出现的位置的信息。那么重新做实验后，我们就很有可能得到我们想要的结果了。                                         通过以上的描述，我们就大概知道了如何设计以及分析实验，能够使我们的茶更好喝。这里所提到的因析设计，响应曲面法等等方法，也只是众多方法中的几种而已。至于如何实现这些细节，以后的章节中会有具体的交代。各位看官如果有兴趣，就请继续跟踪下去。        [...]]]></description>
			<content:encoded><![CDATA[<p>      我们大多数人，都有着对我们的世界进行更深刻了解的渴望。因为，如果知道了一些事物的规律，我们就有可能在此基础上，凭借自己的双手使我们的生活变得更加舒适美好。当然，我们并没有必要苛求自己变成科学达人，能够洞悉诸如量子物理这等高深的学问。因为，就算精通了流体力学，我们也可能依然不会游泳。大多数情况下，我们更加希望知道如何在生活上进行一些小小的改变，能够大大提高我们的幸福感。比如如何配比糖、盐和醋的比例，能让鱼香肉丝尝起来更美味，或者在哪几个零件上滴几滴润滑油能使我们心爱的自行车骑起来更省力。至于糖、醋、盐如何在油锅里相互作用，我们就没必要弄个清楚了。 </p>
<p>      对于如何提升我们的幸福感，我有一个好消息。那就是我们可以通过一些力所能及的实验来得到想要的答案。我们并不需要一个无菌实验室，也不大需要一打精密昂贵的实验设备（大概制备这些设施所带来的心痛，会残忍得吞噬掉我们的实验所带来的幸福感）。我们只需要确定一个研究对象，知道如何评价以及必要的设备。哦，大概还需要一台电脑，能够帮助我们处理一下数据。</p>
<p>      如何进行我们的实验呢？这里我们以泡茶为例，来对实验过程进行一个简单的描述。</p>
<p>      研究问题：如何泡茶才能够使其味道更加清香甜美。</p>
<p>      实验目的：通过实验，找到改变泡茶的质量的方法，从而使我们充分享受绿茶所带来的美好感受。</p>
<p>      实验前提：我们只对一种茶叶进行试验，比如同一袋铁观音。</p>
<p>      实验步骤：</p>
<p>      1. 列出所有可能影响茶水质量的因素。</p>
<p>      在这里，我们需要使用头脑风暴，找出所有可能的因素。对于这个泡茶的课题，我能想到的因素有以下几种：水的来源（自来水，纯净水）；水的温度；水的多少；茶叶的多少；容器类别（玻璃杯，搪瓷杯，紫砂）。当然，对于这个问题，不同人会有不同的见解。我们也可以很无厘头地认为让茶水接受日光的照射，能够对其品质产生巨大的影响。不过根据常识，日光这个因素除了使实验变得复杂之外，大概不会带来其他意外的惊喜。所以，在这个步骤中，我们一定要充分运用我们的常识或者专业知识，指导我们筛选所需考虑的因素，力求做到稳、准、狠。这将对实验的效率产生重要的影响。</p>
<p>      2. 进行因析设计，找出关键因素。</p>
<p>      在这一步骤中，我们需要回答两个问题。（1）步骤1中所列出的因素，对茶水的质量的影响分别有多大？（2）哪些因素的影响可以区别于实验中的噪声，即哪些因素确实产生了影响？</p>
<p>      为了回答以上问题，我们需要两种工具：<strong>因析设计</strong>与<strong>假设检验</strong>。</p>
<p>     <strong> 因析设计</strong>是实验设计方法中，一种十分简便并且行而有效的方法。因析设计的目的，是考察每个因素多个水平对结果影响的差异（如1克铁观音与3克铁观音）。通过因析设计，我们可以计算出所有因素主效应的大小，以及因素间交互作用的大小。对于我们的泡茶实验，可以能够得出五个主效应值的大小，分别为水的来源，水的温度，水的多少，茶叶多少以及容器类别。因素间的交互作用也就是因素之间的共同作用。其中两因素的交互作用共有10种，三因素的交互作用共有10种，四因素的交互作用共有5种，五因素交互作用1种。通过相应的计算，这些交互作用的大小也可以得到。看到这里，我们大概会想，对于五因素的因析设计，我们就有2^5-1种作用需要考虑。如果因素多些，那么其作用的总数就会以指数方式上升了！其实，我们并不需要过分担心这个问题。因为根据前人的经验，三因素或者三因素以上的交互作用很少发生，所以我们只需要注意主效应以及两因素交互作用，这将大大减小我们的工作量。另外，我们可以对因析设计进行改进，使得使用较少的实验，依然能够得出我们想要的结果。如果想知道我们该怎么做，我以后会慢慢道来。</p>
<p>      <strong>假设检验</strong>是我们实验过程中，使用的另外一个强有力的工具。它能够从统计学的角度帮助我们判断一个命题是不是可以否定。通过假设检验，我们将能够把产生影响的因素从噪声中挑选出来，从而缩小考虑的范围，使我们的实验更加有的放矢。</p>
<p>      3. <strong>应用响应曲面法</strong>，寻找最优因子配比。</p>
<p>      通过实验步骤2，我们费了许多力气，终于把真正在背后捣鬼的因素给揪了出来。所以，在步骤3中，我们就需要把这些因子研究个真真切切，明明白白。其实，在这里，我们需要做的事情并不复杂。我们需要在因子以及茶的味道之间建立某种数学关系。什么关系呢？当然，一个数学表达式就不错。有什么好方法呢？没错，最小二乘！如果这些因子的交互作用并不明显，我们可以拟合出一个一阶表达式。比如我们知道只有水温、茶叶量以及水量是主要因素。那么我们就可以得到茶的味道y与因子水温x1、茶叶量x2和水量x3的如下表达式：</p>
<p>                                                        <a class="highslide img_4" href="http://thinkbot.info/wp-content/uploads/2011/03/一阶.png"  onclick="return hs.expand(this)"><img class="alignnone size-full wp-image-366" src="http://thinkbot.info/wp-content/uploads/2011/03/一阶.png" alt="" width="295" height="26" /></a></p>
<p> 其中 第一项为常量， x前的希腊字母为因子系数，最后一项为误差。</p>
<p>      但是，很多情况下，交互作用是明显的。比如水多茶少，味道就太淡。相反，茶多水少，味道就会过于苦涩。那么， 与 就存在交互作用。此时，我们需要拟合的表达时就会复杂一些，因为需要考虑所有二阶表达量。于是我们可以得到如下表达式：　　　　</p>
<p>　                                         　　<a class="highslide img_5" href="http://thinkbot.info/wp-content/uploads/2011/03/二阶.png"  onclick="return hs.expand(this)"><img class="alignnone size-full wp-image-364" src="http://thinkbot.info/wp-content/uploads/2011/03/二阶.png" alt="" width="318" height="81" /></a></p>
<p>      从拟合的公式可以看出，无论是一阶还是二阶（不考虑误差），在空间中都表示一个光滑的曲面。这就好办了，那么在给定的范围内，这个函数必然存在极值。这就是我们要的结果。下面拿起求导这个武器，不费吹灰之力的，我们就能够找到三个因子各取什么值的时候，我们能得到最佳口感。</p>
<p>       4. 结果验证。</p>
<p>　　通过步骤３，我们已经知道了当水温为多少，茶叶放多少，水放多少的情况下，我们的茶最为可口。不过，为了保证效果，我们最好再做一些实验来验证效果。这里会出现两种情况。如果最优值所对应的因子在我们因析设计所考虑的范围内，那么一般情况下，结果不会有过大的偏差。但是，如果在考虑的范围外，那么我们得到的表达式就存在失拟的可能。在这种情况下，如果茶水的口感与我们所预期的相差甚远，那么很不幸，大概我们要从步骤２开始，重新把以上过程走一遍了。别灰心，别灰心，我们之前的工作并没有白费。因为我们可以从之前的结果得到了更多关于最优值可能出现的位置的信息。那么重新做实验后，我们就很有可能得到我们想要的结果了。</p>
<p style="text-align: center">                                <a class="highslide img_6" href="http://thinkbot.info/wp-content/uploads/2011/03/流程1.png"  onclick="return hs.expand(this)"><img class="aligncenter size-full wp-image-375" src="http://thinkbot.info/wp-content/uploads/2011/03/流程1.png" alt="" width="325" height="329" /></a> </p>
<p>      通过以上的描述，我们就大概知道了如何设计以及分析实验，能够使我们的茶更好喝。这里所提到的因析设计，响应曲面法等等方法，也只是众多方法中的几种而已。至于如何实现这些细节，以后的章节中会有具体的交代。各位看官如果有兴趣，就请继续跟踪下去。</p>
<p>       其实，可以发现，整个实验设计与分析的过程，就是一个数学建模的过程。我们所有的努力，都是为了得到最后的拟合表达式，从而能够对所研究的对象，有一个简单近似的描述。一个统计学大牛曾经说过，所有的模型都是错的，但是却是有用的。所以，虽然我们得到的模型并不是那么精确，会忽略一些因素。但是只要我们能够通过它是我们的生活更美好，这就足够了。</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2011/03/%e5%ae%9e%e9%aa%8c%e8%ae%be%e8%ae%a1%e4%b8%8e%e5%88%86%e6%9e%901%e2%80%94%e7%ae%80%e4%bb%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>机器学习中的数学(6)-决策树模型组合之随机森林与GBDT</title>
		<link>http://thinkbot.info/2011/03/machinelearning6-randomforest-and-gbdt/</link>
		<comments>http://thinkbot.info/2011/03/machinelearning6-randomforest-and-gbdt/#comments</comments>
		<pubDate>Mon, 07 Mar 2011 16:00:22 +0000</pubDate>
		<dc:creator>谭望达</dc:creator>
				<category><![CDATA[数学]]></category>
		<category><![CDATA[GBDT]]></category>
		<category><![CDATA[决策树]]></category>
		<category><![CDATA[机器学习]]></category>
		<category><![CDATA[随机森林]]></category>

		<guid isPermaLink="false">http://thinkbot.info/2011/03/%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0%e4%b8%ad%e7%9a%84%e6%95%b0%e5%ad%a66-%e5%86%b3%e7%ad%96%e6%a0%91%e6%a8%a1%e5%9e%8b%e7%bb%84%e5%90%88%e4%b9%8b%e9%9a%8f%e6%9c%ba%e6%a3%ae%e6%9e%97%e4%b8%8egbdt/</guid>
		<description><![CDATA[版权声明： &#160;&#160;&#160; 本文由LeftNotEasy发布于http://leftnoteasy.cnblogs.com, 本文可以被全部的转载或者部分使用，但请注明出处，如果有问题，请联系wheeleast@gmail.com 前言： &#160;&#160;&#160; 决策树这种算法有着很多良好的特性，比如说训练时间复杂度较低，预测的过程比较快速，模型容易展示（容易将得到的决策树做成图片展示出来）等。但是同时，单决策树又有一些不好的地方，比如说容易over-fitting，虽然有一些方法，如剪枝可以减少这种情况，但是还是不够的。 &#160;&#160;&#160; 模型组合（比如说有Boosting，Bagging等）与决策树相关的算法比较多，这些算法最终的结果是生成N(可能会有几百棵以上）棵树，这样可以大大的减少单决策树带来的毛病，有点类似于三个臭皮匠等于一个诸葛亮的做法，虽然这几百棵决策树中的每一棵都很简单（相对于C4.5这种单决策树来说），但是他们组合起来确是很强大。 &#160;&#160;&#160; 在最近几年的paper上，如iccv这种重量级的会议，iccv 09年的里面有不少的文章都是与Boosting与随机森林相关的。模型组合+决策树相关的算法有两种比较基本的形式 &#8211; 随机森林与GBDT((Gradient Boost Decision Tree)，其他的比较新的模型组合+决策树的算法都是来自这两种算法的延伸。本文主要侧重于GBDT，对于随机森林只是大概提提，因为它相对比较简单。 &#160;&#160;&#160; 在看本文之前，建议先看看机器学习与数学(3)与其中引用的论文，本文中的GBDT主要基于此，而随机森林相对比较独立。 基础内容： &#160;&#160;&#160; 这里只是准备简单谈谈基础的内容，主要参考一下别人的文章，对于随机森林与GBDT，有两个地方比较重要，首先是information gain，其次是决策树。这里特别推荐Andrew Moore大牛的Decision Trees Tutorial，与Information Gain Tutorial。Moore的Data Mining Tutorial系列非常赞，看懂了上面说的两个内容之后的文章才能继续读下去。 &#160;&#160;&#160; 决策树实际上是将空间用超平面进行划分的一种方法，每次分割的时候，都将当前的空间一分为二，比如说下面的决策树： &#160;&#160;&#160; 就是将空间划分成下面的样子： &#160;&#160;&#160; 这样使得每一个叶子节点都是在空间中的一个不相交的区域，在进行决策的时候，会根据输入样本每一维feature的值，一步一步往下，最后使得样本落入N个区域中的一个（假设有N个叶子节点） 随机森林(Random Forest): &#160;&#160;&#160; 随机森林是一个最近比较火的算法，它有很多的优点： &#160;&#160;&#160; 在数据集上表现良好 &#160;&#160;&#160; 在当前的很多数据集上，相对其他算法有着很大的优势 &#160;&#160;&#160; 它能够处理很高维度（feature很多）的数据，并且不用做特征选择 &#160;&#160;&#160; 在训练完后，它能够给出哪些feature比较重要 &#160;&#160;&#160; 在创建随机森林的时候，对generlization error使用的是无偏估计 &#160;&#160;&#160; 训练速度快 &#160;&#160;&#160; 在训练过程中，能够检测到feature间的互相影响 [...]]]></description>
			<content:encoded><![CDATA[<p><strong><font size="5">版权声明：</font></strong></p>
<p><font size="4">&#160;&#160;&#160; 本文由LeftNotEasy发布于</font><a href="http://leftnoteasy.cnblogs.com/" class="aga aga_9"><font size="4">http://leftnoteasy.cnblogs.com</font></a><font size="4">, 本文可以被全部的转载或者部分使用，但请注明出处，如果有问题，请联系</font><a href="mailto:wheeleast@gmail.com"><font size="4">wheeleast@gmail.com</font></a></p>
<p><font size="5"><strong></strong></font></p>
<p><font size="5"><strong>前言：</strong></font></p>
<p><font size="4">&#160;&#160;&#160; 决策树这种算法有着很多良好的特性，比如说训练时间复杂度较低，预测的过程比较快速，模型容易展示（容易将得到的决策树做成图片展示出来）等。但是同时，单决策树又有一些不好的地方，比如说容易over-fitting，虽然有一些方法，如剪枝可以减少这种情况，但是还是不够的。</font></p>
<p><font size="4">&#160;&#160;&#160; 模型组合（比如说有Boosting，Bagging等）与决策树相关的算法比较多，这些算法最终的结果是生成N(可能会有几百棵以上）棵树，这样可以大大的减少单决策树带来的毛病，有点类似于三个臭皮匠等于一个诸葛亮的做法，虽然这几百棵决策树中的每一棵都很简单（相对于C4.5这种单决策树来说），但是他们组合起来确是很强大。</font></p>
<p><font size="4">&#160;&#160;&#160; 在最近几年的paper上，如iccv这种重量级的会议，</font><a href="http://www.cvpapers.com/iccv2009.html" class="aga aga_10"><font size="4">iccv 09</font></a><font size="4">年的里面有不少的文章都是与Boosting与随机森林相关的。模型组合+决策树相关的算法有两种比较基本的形式 &#8211; 随机森林与GBDT((Gradient Boost Decision Tree)，其他的比较新的模型组合+决策树的算法都是来自这两种算法的延伸。本文主要侧重于GBDT，对于随机森林只是大概提提，因为它相对比较简单。</font></p>
<p><font size="4">&#160;&#160;&#160; 在看本文之前，建议先看看</font><a href="http://www.cnblogs.com/LeftNotEasy/archive/2011/01/02/machine-learning-boosting-and-gradient-boosting.html" class="aga aga_11"><font size="4">机器学习与数学(3)</font></a><font size="4">与其中引用的论文，本文中的GBDT主要基于此，而随机森林相对比较独立。</font></p>
<p><font size="4"></font></p>
<p><font size="5"><strong>基础内容：</strong></font></p>
<p><font size="4">&#160;&#160;&#160; 这里只是准备简单谈谈基础的内容，主要参考一下别人的文章，对于随机森林与GBDT，有两个地方比较重要，首先是information gain，其次是决策树。这里特别推荐Andrew Moore大牛的<a href="http://www.autonlab.org/tutorials/dtree.html" class="aga aga_12">Decision Trees Tutorial</a>，与<a href="http://www.autonlab.org/tutorials/infogain.html" class="aga aga_13">Information Gain Tutorial</a>。Moore的<a href="http://www.autonlab.org/tutorials/" class="aga aga_14">Data Mining Tutorial系列</a>非常赞，看懂了上面说的两个内容之后的文章才能继续读下去。</font></p>
<p><font size="4">&#160;&#160;&#160; 决策树实际上是将空间用超平面进行划分的一种方法，每次分割的时候，都将<strong>当前的</strong>空间一分为二，比如说下面的决策树：</font></p>
<p><a class="highslide img_14" href="http://thinkbot.info/wp-content/uploads/2011/03/image.png"  onclick="return hs.expand(this)"><img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="169" alt="image" src="http://thinkbot.info/wp-content/uploads/2011/03/image_thumb.png" width="240" border="0" /></a></p>
<p><font size="4">&#160;&#160;&#160; 就是将空间划分成下面的样子：</font></p>
<p><a class="highslide img_15" href="http://thinkbot.info/wp-content/uploads/2011/03/image1.png"  onclick="return hs.expand(this)"><img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="221" alt="image" src="http://thinkbot.info/wp-content/uploads/2011/03/image_thumb1.png" width="240" border="0" /></a></p>
<p><font size="4">&#160;&#160;&#160; 这样使得<strong>每一个叶子节点都是在空间中的一个不相交的区域</strong>，在进行决策的时候，会根据输入样本每一维feature的值，一步一步往下，最后使得样本落入N个区域中的一个（假设有N个叶子节点）</font></p>
<p><font size="4"></font></p>
<p><font size="4"></font></p>
<p><font size="5"><strong>随机森林(Random Forest):</strong></font></p>
<p><font size="4">&#160;&#160;&#160; 随机森林是一个最近比较火的算法，它有很多的优点：</font></p>
<ul>
<li><font size="4">&#160;&#160;&#160; 在数据集上表现良好</font> </li>
<li><font size="4">&#160;&#160;&#160; 在当前的很多数据集上，相对其他算法有着很大的优势</font> </li>
<li><font size="4">&#160;&#160;&#160; 它能够处理很高维度（feature很多）的数据，并且不用做特征选择</font> </li>
<li><font size="4">&#160;&#160;&#160; 在训练完后，它能够给出哪些feature比较重要</font> </li>
<li><font size="4">&#160;&#160;&#160; 在创建随机森林的时候，对generlization error使用的是无偏估计</font> </li>
<li><font size="4">&#160;&#160;&#160; 训练速度快</font> </li>
<li><font size="4">&#160;&#160;&#160; 在训练过程中，能够检测到feature间的互相影响</font> </li>
<li><font size="4">&#160;&#160;&#160; 容易做成并行化方法</font> </li>
<li><font size="4">&#160;&#160;&#160; 实现比较简单</font> </li>
</ul>
<p><font size="4">&#160;&#160;&#160; 随机森林顾名思义，是用随机的方式建立一个森林，森林里面有很多的决策树组成，随机森林的每一棵决策树之间是没有关联的。在得到森林之后，当有一个新的输入样本进入的时候，就让森林中的每一棵决策树分别进行一下判断，看看这个样本应该属于哪一类（对于分类算法），然后看看哪一类被选择最多，就预测这个样本为那一类。</font></p>
<p><font size="4">&#160;&#160;&#160; 在建立每一棵决策树的过程中，有两点需要注意 &#8211; 采样与完全分裂。首先是两个随机采样的过程，random forest对输入的数据要进行行、列的采样。对于行采样，采用有放回的方式，也就是在采样得到的样本集合中，可能有重复的样本。假设输入样本为N个，那么采样的样本也为N个。这样使得在训练的时候，每一棵树的输入样本都不是全部的样本，使得相对不容易出现over-fitting。然后进行列采样，从M个feature中，选择m个(m &lt;&lt; M)。之后就是对采样之后的数据使用完全分裂的方式建立出决策树，这样决策树的某一个叶子节点要么是无法继续分裂的，要么里面的所有样本的都是指向的同一个分类。一般很多的决策树算法都一个重要的步骤 &#8211; 剪枝，但是这里不这样干，由于之前的两个随机采样的过程保证了随机性，所以就算不剪枝，也不会出现over-fitting。</font></p>
<p><font size="4">&#160;&#160;&#160; 按这种算法得到的随机森林中的每一棵都是很弱的，但是大家组合起来就很厉害了。我觉得可以这样比喻随机森林算法：每一棵决策树就是一个精通于某一个窄领域的专家（因为我们从M个feature中选择m让每一棵决策树进行学习），这样在随机森林中就有了很多个精通不同领域的专家，对一个新的问题（新的输入数据），可以用不同的角度去看待它，最终由各个专家，投票得到结果。</font></p>
<p><font size="4">&#160;&#160;&#160; 随机森林的过程请参考<a href="https://cwiki.apache.org/MAHOUT/random-forests.html" class="aga aga_15">Mahout的random forest</a></font><font size="4"> 。这个页面上写的比较清楚了，其中可能不明白的就是Information Gain，可以看看之前推荐过的Moore的页面。</font></p>
<p><font size="4"></font></p>
<p><font size="4"></font></p>
<p><font size="5"><strong>Gradient Boost Decision Tree:</strong></font></p>
<p><font size="4">&#160;&#160; GBDT是一个应用很广泛的算法，可以用来做分类、回归。在很多的数据上都有不错的效果。</font><font size="4">GBDT这个算法还有一些其他的名字，比如说MART(Multiple Additive Regression Tree)，GBRT(Gradient Boost Regression Tree)，Tree Net等，其实它们都是一个东西（参考自<a href="http://en.wikipedia.org/wiki/Gradient_boosting" class="aga aga_16">wikipedia – Gradient Boosting</a>)，发明者是Friedman</font></p>
<p><font size="4">&#160;&#160; Gradient Boost其实是一个框架，里面可以套入很多不同的算法，可以参考一下机器学习与数学(3)中的讲解。Boost是&quot;提升&quot;的意思，一般Boosting算法都是一个迭代的过程，每一次新的训练都是为了改进上一次的结果。</font></p>
<p><font size="4">&#160;&#160; 原始的Boost算法是在算法开始的时候，为每一个样本赋上一个权重值，初始的时候，大家都是一样重要的。在每一步训练中得到的模型，会使得数据点的估计有对有错，我们就在每一步结束后，增加分错的点的权重，减少分对的点的权重，这样使得某些点如果老是被分错，那么就会被“严重关注”，也就被赋上一个很高的权重。然后等进行了N次迭代（由用户指定），将会得到N个简单的分类器（basic learner），然后我们将它们组合起来（比如说可以对它们进行加权、或者让它们进行投票等），得到一个最终的模型。</font></p>
<p><font size="4">&#160;&#160; 而Gradient Boost与传统的Boost的区别是，每一次的计算是为了减少上一次的残差(residual)，而为了消除残差，我们可以在<strong>残差减少的梯度(Gradient)方向</strong>上建立一个新的模型。所以说，在Gradient Boost中，每个新的模型的简历是为了使得之前模型的残差往梯度方向减少，与传统Boost对正确、错误的样本进行加权有着很大的区别。</font></p>
<p><font size="4">&#160;&#160; 在分类问题中，有一个很重要的内容叫做Multi-Class Logistic，也就是多分类的Logistic问题，它适用于那些类别数&gt;2的问题，并且在分类结果中，样本x不是一定只属于某一个类可以得到样本x分别属于多个类的概率（也可以说样本x的估计y符合某一个几何分布），这实际上是属于Generalized Linear Model中讨论的内容，这里就先不谈了，以后有机会再用一个专门的章节去做吧。这里就用一个结论：<strong>如果一个分类问题符合几何分布，那么就可以用Logistic变换来进行之后的运算</strong>。</font></p>
<p><font size="4">&#160;&#160; 假设对于一个样本x，它可能属于K个分类，其估计值分别为F1(x)…FK(x)，<strong>Logistic变换如下</strong>，logistic变换是一个平滑且将数据规范化（使得向量的长度为1）的过程，结果为属于类别k的概率pk(x)，</font></p>
<p><a class="highslide img_16" href="http://thinkbot.info/wp-content/uploads/2011/03/image2.png"  onclick="return hs.expand(this)"><font color="#000000" size="4"><img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="65" alt="image" src="http://thinkbot.info/wp-content/uploads/2011/03/image_thumb2.png" width="337" border="0" /></font></a></p>
<p><font size="4">&#160;&#160; 对于Logistic变换后的结果，损失函数为：</font></p>
<p><a class="highslide img_17" href="http://thinkbot.info/wp-content/uploads/2011/03/image3.png"  onclick="return hs.expand(this)"><font color="#000000" size="4"><img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="62" alt="image" src="http://thinkbot.info/wp-content/uploads/2011/03/image_thumb3.png" width="306" border="0" /></font></a><font size="4">&#160;&#160;&#160; 其中，yk为输入的样本数据的估计值，当一个样本x属于类别k时，yk = 1，否则yk = 0。</font></p>
<p><font size="4">&#160;&#160;&#160; 将Logistic变换的式子带入损失函数，并且对其求导，可以得到<strong>损失函数的梯度</strong>：</font></p>
<p><a class="highslide img_18" href="http://thinkbot.info/wp-content/uploads/2011/03/image4.png"  onclick="return hs.expand(this)"><font color="#000000" size="4"><img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="75" alt="image" src="http://thinkbot.info/wp-content/uploads/2011/03/image_thumb4.png" width="597" border="0" /></font></a><font size="4">&#160;&#160;&#160; 上面说的比较抽象，下面举个例子：</font></p>
<p><font size="4">&#160;&#160;&#160; 假设输入数据x可能属于5个分类（分别为1,2,3,4,5），训练数据中，x属于类别3，则y = (0, 0, 1, 0, 0)，假设模型估计得到的F(x) = (0, 0.3, 0.6, 0, 0)，则经过Logistic变换后的数据p(x) = (0.16,0.21,0.29,0.16,0.16)，y &#8211; p得到梯度g：(-0.16, -0.21, 0.71, -0.16, -0.16)。观察这里可以得到一个比较有意思的结论：</font></p>
<p><font size="4">&#160;&#160;&#160; 假设gk为样本当某一维（某一个分类）上的梯度:</font></p>
<p><font size="4">&#160;&#160;&#160; gk&gt;0时，越大表示其在这一维上的概率p(x)越应该提高，比如说上面的第三维的概率为0.29，就应该提高，属于<strong>应该往“正确的方向”前进</strong></font></p>
<p><font size="4">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 越小表示这个估计越“准确”</font></p>
<p><font size="4">&#160;&#160;&#160; gk&lt;0时，越小，负得越多表示在这一维上的概率应该降低，比如说第二维0.21就应该得到降低。属于<strong>应该朝着“错误的反方向”前进</strong></font></p>
<p><font size="4">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 越大，负得越少表示这个估计越“不错误 ”</font></p>
<p><font size="4">&#160;&#160;&#160; 总的来说，<strong>对于一个样本，最理想的梯度是越接近0的梯度</strong>。所以，我们要能够让函数的估计值能够使得梯度往反方向移动（&gt;0的维度上，往负方向移动，&lt;0的维度上，往正方向移动）最终使得梯度尽量=0），并且<strong>该算法在会严重关注那些梯度比较大的样本，跟Boost的意思类似</strong>。</font></p>
<p><font size="4"></font></p>
<p><font size="4"></font></p>
<p><font size="4">&#160;&#160;&#160; 得到梯度之后，就是如何让梯度减少了。这里是用的一个<strong>迭代+决策树</strong>的方法，当初始化的时候，随便给出一个估计函数F(x)（可以让F(x)是一个随机的值，也可以让F(x)=0），然后之后每迭代一步就根据当前每一个样本的梯度的情况，建立一棵决策树。就让函数往梯度的反方向前进，最终使得迭代N步后，梯度越小。</font></p>
<p><font size="4">&#160;&#160;&#160; 这里建立的决策树和普通的决策树不太一样，首先，这个决策树是一个叶子节点数J固定的，当生成了J个节点后，就不再生成新的节点了。</font></p>
<p><font size="4">&#160;&#160;&#160; 算法的流程如下:（参考自treeBoost论文）</font></p>
<p><a class="highslide img_19" href="http://thinkbot.info/wp-content/uploads/2011/03/image5.png"  onclick="return hs.expand(this)"><font color="#000000" size="4"></font></a><a class="highslide img_20" href="http://thinkbot.info/wp-content/uploads/2011/03/image6.png"  onclick="return hs.expand(this)"><img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="360" alt="image" src="http://thinkbot.info/wp-content/uploads/2011/03/image_thumb5.png" width="630" border="0" /></a></a></a></p>
<p><font size="4">&#160;&#160;&#160;&#160; 0. 表示给定一个初始值</font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 1. 表示建立M棵决策树（迭代M次）</font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 2. 表示对函数估计值F(x)进行Logistic变换</font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 3. 表示对于K个分类进行下面的操作（其实这个for循环也可以理解为向量的操作，每一个样本点xi</font><font size="4">都对应了K种可能的分类yi，所以yi, F(xi), p(xi)都是一个K维的向量，这样或许容易理解一点）</font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 4. 表示求得残差减少的梯度方向</font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 5. 表示根据每一个样本点x，与其残差减少的梯度方向，得到一棵由J个叶子节点组成的决策树</font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 6. <strong>为当决策树建立完成后，通过这个公式，可以得到每一个叶子节点的增益（这个增益在预测的时候用的）</strong></font></p>
<p><font size="4">&#160;&#160;&#160;&#160;&#160;&#160; 每个增益的组成其实也是一个K维的向量，表示如果在决策树预测的过程中，如果某一个样本点掉入了这个叶子节点，则其对应的K个分类的值是多少。比如说，GBDT得到了三棵决策树，一个样本点在预测的时候，也会掉入3个叶子节点上，其增益分别为（假设为3分类的问题）：</font></p>
<p><font size="4">&#160;&#160;&#160;&#160;&#160;&#160; (0.5, 0.8, 0.1),&#160; (0.2, 0.6, 0.3),&#160; (0.4, 0.3, 0.3)，那么这样最终得到的分类为第二个，因为选择分类2的决策树是最多的。</font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 7. 的意思为，将当前得到的决策树与之前的那些决策树合并起来，作为新的一个模型(跟6中所举的例子差不多)</font></p>
<p><font size="4">&#160;&#160;&#160;&#160; <strong>GBDT的算法大概就讲到这里了，希望能够弥补一下上一篇文章中没有说清楚的部分：）</strong></font></p>
<p><font size="4"></font></p>
<p>&#160;</p>
<p><font size="5"><strong>实现：</strong></font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 看明白了算法，就需要去实现一下，或者看看别人实现的代码，这里推荐一下wikipedia中的gradient boosting页面，下面就有一些开源软件中的一些实现，比如说下面这个：</font><a href="http://elf-project.sourceforge.net/" class="aga aga_17"><font size="4">http://elf-project.sourceforge.net/</font></a><font size="4">&#160;</font></p>
<p><font size="4"></font></p>
<p><font size="5"><strong>参考资料：</strong></font></p>
<p><font size="4">&#160;&#160;&#160;&#160; 除了文章中的引用的内容（已经给出了链接）外，主要还是参考Friedman大牛的文章：Greedy function approximation : A Gradient Boosting Machine</font></p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2011/03/machinelearning6-randomforest-and-gbdt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>机器学习中的数学(5)-强大的矩阵奇异值分解(SVD)及其应用</title>
		<link>http://thinkbot.info/2011/01/svd-and-application/</link>
		<comments>http://thinkbot.info/2011/01/svd-and-application/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 14:30:58 +0000</pubDate>
		<dc:creator>谭望达</dc:creator>
				<category><![CDATA[人工智能]]></category>
		<category><![CDATA[分布式计算]]></category>
		<category><![CDATA[数学]]></category>
		<category><![CDATA[数据挖掘]]></category>
		<category><![CDATA[数理统计]]></category>
		<category><![CDATA[机器学习]]></category>

		<guid isPermaLink="false">http://thinkbot.info/2011/01/%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0%e4%b8%ad%e7%9a%84%e6%95%b0%e5%ad%a65-%e5%bc%ba%e5%a4%a7%e7%9a%84%e7%9f%a9%e9%98%b5%e5%a5%87%e5%bc%82%e5%80%bc%e5%88%86%e8%a7%a3svd%e5%8f%8a%e5%85%b6%e5%ba%94/</guid>
		<description><![CDATA[版权声明： 本文由LeftNotEasy发布于http://leftnoteasy.cnblogs.com, 本文可以被全部的转载或者部分使用，但请注明出处，如果有问题，请联系wheeleast@gmail.com 前言： 上一次写了关于PCA与LDA的文章，PCA的实现一般有两种，一种是用特征值分解去实现的，一种是用奇异值分解去实现的。在上篇文章中便是基于特征值分解的一种解释。特征值和奇异值在大部分人的印象中，往往是停留在纯粹的数学计算中。而且线性代数或者矩阵论里面，也很少讲任何跟特征值与奇异值有关的应用背景。奇异值分解是一个有着很明显的物理意义的一种方法，它可以将一个比较复杂的矩阵用更小更简单的几个子矩阵的相乘来表示，这些小矩阵描述的是矩阵的重要的特性。就像是描述一个人一样，给别人描述说这个人长得浓眉大眼，方脸，络腮胡，而且带个黑框的眼镜，这样寥寥的几个特征，就让别人脑海里面就有一个较为清楚的认识，实际上，人脸上的特征是有着无数种的，之所以能这么描述，是因为人天生就有着非常好的抽取重要特征的能力，让机器学会抽取重要的特征，SVD是一个重要的方法。 在机器学习领域，有相当多的应用与奇异值都可以扯上关系，比如做feature reduction的PCA，做数据压缩（以图像压缩为代表）的算法，还有做搜索引擎语义层次检索的LSI（Latent Semantic Indexing） 另外在这里抱怨一下，之前在百度里面搜索过SVD，出来的结果都是俄罗斯的一种狙击枪（AK47同时代的），是因为穿越火线这个游戏里面有一把狙击枪叫做SVD，而在Google上面搜索的时候，出来的都是奇异值分解（英文资料为主）。想玩玩战争游戏，玩玩COD不是非常好吗，玩山寨的CS有神马意思啊。国内的网页中的话语权也被这些没有太多营养的帖子所占据。真心希望国内的气氛能够更浓一点，搞游戏的人真正是喜欢制作游戏，搞Data Mining的人是真正喜欢挖数据的，都不是仅仅为了混口饭吃，这样谈超越别人才有意义，中文文章中，能踏踏实实谈谈技术的太少了，改变这个状况，从我自己做起吧。 前面说了这么多，本文主要关注奇异值的一些特性，另外还会稍稍提及奇异值的计算，不过本文不准备在如何计算奇异值上展开太多。另外，本文里面有部分不算太深的线性代数的知识，如果完全忘记了线性代数，看本文可能会有些困难。 一、奇异值与特征值基础知识： 特征值分解和奇异值分解在机器学习领域都是属于满地可见的方法。两者有着很紧密的关系，我在接下来会谈到，特征值分解和奇异值分解的目的都是一样，就是提取出一个矩阵最重要的特征。先谈谈特征值分解吧： 1）特征值： 如果说一个向量v是方阵A的特征向量，将一定可以表示成下面的形式： 这时候λ就被称为特征向量v对应的特征值，一个矩阵的一组特征向量是一组正交向量。特征值分解是将一个矩阵分解成下面的形式： 其中Q是这个矩阵A的特征向量组成的矩阵，Σ是一个对角阵，每一个对角线上的元素就是一个特征值。我这里引用了一些参考文献中的内容来说明一下。首先，要明确的是，一个矩阵其实就是一个线性变换，因为一个矩阵乘以一个向量后得到的向量，其实就相当于将这个向量进行了线性变换。比如说下面的一个矩阵： 它其实对应的线性变换是下面的形式： 因为这个矩阵M乘以一个向量(x,y)的结果是： 上面的矩阵是对称的，所以这个变换是一个对x，y轴的方向一个拉伸变换（每一个对角线上的元素将会对一个维度进行拉伸变换，当值&#62;1时，是拉长，当值&#60;1时时缩短），当矩阵不是对称的时候，假如说矩阵是下面的样子： 它所描述的变换是下面的样子： 这其实是在平面上对一个轴进行的拉伸变换（如蓝色的箭头所示），在图中，蓝色的箭头是一个最主要的变化方向（变化方向可能有不止一个），如果我们想要描述好一个变换，那我们就描述好这个变换主要的变化方向就好了。反过头来看看之前特征值分解的式子，分解得到的Σ矩阵是一个对角阵，里面的特征值是由大到小排列的，这些特征值所对应的特征向量就是描述这个矩阵变化方向（从主要的变化到次要的变化排列） 当矩阵是高维的情况下，那么这个矩阵就是高维空间下的一个线性变换，这个线性变化可能没法通过图片来表示，但是可以想象，这个变换也同样有很多的变换方向，我们通过特征值分解得到的前N个特征向量，那么就对应了这个矩阵最主要的N个变化方向。我们利用这前N个变化方向，就可以近似这个矩阵（变换）。也就是之前说的：提取这个矩阵最重要的特征。总结一下，特征值分解可以得到特征值与特征向量，特征值表示的是这个特征到底有多重要，而特征向量表示这个特征是什么，可以将每一个特征向量理解为一个线性的子空间，我们可以利用这些线性的子空间干很多的事情。不过，特征值分解也有很多的局限，比如说变换的矩阵必须是方阵。 （说了这么多特征值变换，不知道有没有说清楚，请各位多提提意见。） 2）奇异值： 下面谈谈奇异值分解。特征值分解是一个提取矩阵特征很不错的方法，但是它只是对方阵而言的，在现实的世界中，我们看到的大部分矩阵都不是方阵，比如说有N个学生，每个学生有M科成绩，这样形成的一个N * M的矩阵就不可能是方阵，我们怎样才能描述这样普通的矩阵呢的重要特征呢？奇异值分解可以用来干这个事情，奇异值分解是一个能适用于任意的矩阵的一种分解的方法： 假设A是一个N * M的矩阵，那么得到的U是一个N * N的方阵（里面的向量是正交的，U里面的向量称为左奇异向量），Σ是一个N * M的矩阵（除了对角线的元素都是0，对角线上的元素称为奇异值），V’(V的转置)是一个N * N的矩阵，里面的向量也是正交的，V里面的向量称为右奇异向量），从图片来反映几个相乘的矩阵的大小可得下面的图片 那么奇异值和特征值是怎么对应起来的呢？首先，我们将一个矩阵A的转置 * A，将会得到一个方阵，我们用这个方阵求特征值可以得到： 这里得到的v，就是我们上面的右奇异向量。此外我们还可以得到： 这里的σ就是上面说的奇异值，u就是上面说的左奇异向量。奇异值σ跟特征值类似，在矩阵Σ中也是从大到小排列，而且σ的减少特别的快，在很多情况下，前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了。也就是说，我们也可以用前r大的奇异值来近似描述矩阵，这里定义一下部分奇异值分解： r是一个远小于m、n的数，这样矩阵的乘法看起来像是下面的样子： 右边的三个矩阵相乘的结果将会是一个接近于A的矩阵，在这儿，r越接近于n，则相乘的结果越接近于A。而这三个矩阵的面积之和（在存储观点来说，矩阵面积越小，存储量就越小）要远远小于原始的矩阵A，我们如果想要压缩空间来表示原矩阵A，我们存下这里的三个矩阵：U、Σ、V就好了。 二、奇异值的计算： 奇异值的计算是一个难题，是一个O(N^3)的算法。在单机的情况下当然是没问题的，matlab在一秒钟内就可以算出1000 * 1000的矩阵的所有奇异值，但是当矩阵的规模增长的时候，计算的复杂度呈3次方增长，就需要并行计算参与了。Google的吴军老师在数学之美系列谈到SVD的时候，说起Google实现了SVD的并行化算法，说这是对人类的一个贡献，但是也没有给出具体的计算规模，也没有给出太多有价值的信息。 其实SVD还是可以用并行的方式去实现的，在解大规模的矩阵的时候，一般使用迭代的方法，当矩阵的规模很大（比如说上亿）的时候，迭代的次数也可能会上亿次，如果使用Map-Reduce框架去解，则每次Map-Reduce完成的时候，都会涉及到写文件、读文件的操作。个人猜测Google云计算体系中除了Map-Reduce以外应该还有类似于MPI的计算模型，也就是节点之间是保持通信，数据是常驻在内存中的，这种计算模型比Map-Reduce在解决迭代次数非常多的时候，要快了很多倍。 Lanczos迭代就是一种解对称方阵部分特征值的方法（之前谈到了，解A’* A得到的对称方阵的特征值就是解A的右奇异向量），是将一个对称的方程化为一个三对角矩阵再进行求解。按网上的一些文献来看，Google应该是用这种方法去做的奇异值分解的。请见Wikipedia上面的一些引用的论文，如果理解了那些论文，也“几乎”可以做出一个SVD了。 由于奇异值的计算是一个很枯燥，纯数学的过程，而且前人的研究成果（论文中）几乎已经把整个程序的流程图给出来了。更多的关于奇异值计算的部分，将在后面的参考文献中给出，这里不再深入，我还是focus在奇异值的应用中去。 三、奇异值与主成分分析（PCA）： 主成分分析在上一节里面也讲了一些，这里主要谈谈如何用SVD去解PCA的问题。PCA的问题其实是一个基的变换，使得变换后的数据有着最大的方差。方差的大小描述的是一个变量的信息量，我们在讲一个东西的稳定性的时候，往往说要减小方差，如果一个模型的方差很大，那就说明模型不稳定了。但是对于我们用于机器学习的数据（主要是训练数据），方差大才有意义，不然输入的数据都是同一个点，那方差就为0了，这样输入的多个数据就等同于一个数据了。以下面这张图为例子： [...]]]></description>
			<content:encoded><![CDATA[<p><strong><span style="color: #0080ff; font-size: medium;">版权声明：</span></strong></p>
<p>本文由LeftNotEasy发布于<a href="http://leftnoteasy.cnblogs.com/" class="aga aga_26">http://leftnoteasy.cnblogs.com</a>, 本文可以被全部的转载或者部分使用，但请注明出处，如果有问题，请联系<a href="mailto:wheeleast@gmail.com">wheeleast@gmail.com</a></p>
<p><strong><span style="color: #0080ff; font-size: medium;">前言：</span></strong></p>
<p>上一次写了关于<a href="http://www.cnblogs.com/LeftNotEasy/archive/2011/01/08/lda-and-pca-machine-learning.html" class="aga aga_27">PCA与LDA</a>的文章，PCA的实现一般有两种，一种是用特征值分解去实现的，一种是用奇异值分解去实现的。在上篇文章中便是基于特征值分解的一种解释。特征值和奇异值在大部分人的印象中，往往是停留在纯粹的数学计算中。而且线性代数或者矩阵论里面，也很少讲任何跟特征值与奇异值有关的应用背景。奇异值分解是一个有着很明显的物理意义的一种方法，它可以将一个比较复杂的矩阵用更小更简单的几个子矩阵的相乘来表示，这些小矩阵描述的是矩阵的重要的特性。就像是描述一个人一样，给别人描述说这个人长得浓眉大眼，方脸，络腮胡，而且带个黑框的眼镜，这样寥寥的几个特征，就让别人脑海里面就有一个较为清楚的认识，实际上，人脸上的特征是有着无数种的，之所以能这么描述，是因为人天生就有着非常好的抽取重要特征的能力，让机器学会抽取重要的特征，SVD是一个重要的方法。</p>
<p>在机器学习领域，有相当多的应用与奇异值都可以扯上关系，比如做feature reduction的PCA，做数据压缩（以图像压缩为代表）的算法，还有做搜索引擎语义层次检索的LSI（Latent Semantic Indexing）</p>
<p>另外在这里抱怨一下，之前在百度里面搜索过SVD，出来的结果都是俄罗斯的一种狙击枪（AK47同时代的），是因为穿越火线这个游戏里面有一把狙击枪叫做SVD，而在Google上面搜索的时候，出来的都是奇异值分解（英文资料为主）。想玩玩战争游戏，玩玩COD不是非常好吗，玩山寨的CS有神马意思啊。国内的网页中的话语权也被这些没有太多营养的帖子所占据。真心希望国内的气氛能够更浓一点，搞游戏的人真正是喜欢制作游戏，搞Data Mining的人是真正喜欢挖数据的，都不是仅仅为了混口饭吃，这样谈超越别人才有意义，中文文章中，能踏踏实实谈谈技术的太少了，改变这个状况，从我自己做起吧。</p>
<p>前面说了这么多，本文主要关注奇异值的一些特性，另外还会稍稍提及奇异值的计算，不过本文不准备在如何计算奇异值上展开太多。另外，本文里面有部分不算太深的线性代数的知识，如果完全忘记了线性代数，看本文可能会有些困难。</p>
<p><strong><span style="color: #0080ff; font-size: medium;">一、奇异值与特征值基础知识：</span></strong></p>
<p>特征值分解和奇异值分解在机器学习领域都是属于满地可见的方法。两者有着很紧密的关系，我在接下来会谈到，特征值分解和奇异值分解的目的都是一样，就是提取出一个矩阵最重要的特征。先谈谈特征值分解吧：</p>
<p><span style="font-size: medium;"> 1）<strong>特征值：</strong></span></p>
<p>如果说一个向量v是方阵A的特征向量，将一定可以表示成下面的形式：</p>
<p><a class="highslide img_44" href="http://thinkbot.info/wp-content/uploads/2011/01/image46.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb48.png" border="0" alt="image" width="84" height="34" /></a></p>
<p>这时候λ就被称为特征向量v对应的特征值，一个矩阵的一组特征向量是一组正交向量。特征值分解是将一个矩阵分解成下面的形式：</p>
<p><a class="highslide img_45" href="http://thinkbot.info/wp-content/uploads/2011/01/image47.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb49.png" border="0" alt="image" width="112" height="38" /></a></p>
<p>其中Q是这个矩阵A的特征向量组成的矩阵，Σ是一个对角阵，每一个对角线上的元素就是一个特征值。我这里引用了一些参考文献中的内容来说明一下。首先，要明确的是，一个矩阵其实就是一个线性变换，因为一个矩阵乘以一个向量后得到的向量，其实就相当于将这个向量进行了线性变换。比如说下面的一个矩阵：</p>
<p><a class="highslide img_46" href="http://thinkbot.info/wp-content/uploads/2011/01/image48.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb50.png" border="0" alt="image" width="105" height="55" /></a> 它其实对应的线性变换是下面的形式：</p>
<p><a class="highslide img_47" href="http://thinkbot.info/wp-content/uploads/2011/01/image49.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb51.png" border="0" alt="image" width="371" height="170" /></a> 因为这个矩阵M乘以一个向量(x,y)的结果是：</p>
<p><a class="highslide img_48" href="http://thinkbot.info/wp-content/uploads/2011/01/image50.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb52.png" border="0" alt="image" width="162" height="58" /></a> 上面的矩阵是对称的，所以这个变换是一个对x，y轴的方向一个拉伸变换（每一个对角线上的元素将会对一个维度进行拉伸变换，当值&gt;1时，是拉长，当值&lt;1时时缩短），当矩阵不是对称的时候，假如说矩阵是下面的样子：</p>
<p><a class="highslide img_49" href="http://thinkbot.info/wp-content/uploads/2011/01/image51.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb53.png" border="0" alt="image" width="100" height="53" /></a></p>
<p>它所描述的变换是下面的样子：</p>
<p><a class="highslide img_50" href="http://thinkbot.info/wp-content/uploads/2011/01/image52.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb54.png" border="0" alt="image" width="366" height="171" /></a></p>
<p>这其实是在平面上对一个轴进行的拉伸变换（如蓝色的箭头所示），在图中，蓝色的箭头是一个最<strong>主要的</strong>变化方向（变化方向可能有不止一个），<strong>如果我们想要描述好一个变换，那我们就描述好这个变换主要的变化方向就好了</strong>。反过头来看看之前特征值分解的式子，分解得到的Σ矩阵是一个对角阵，里面的特征值是由大到小排列的，这些特征值所对应的特征向量就是描述这个矩阵变化方向（从主要的变化到次要的变化排列）</p>
<p>当矩阵是高维的情况下，那么这个矩阵就是高维空间下的一个线性变换，这个线性变化可能没法通过图片来表示，但是可以想象，这个变换也同样有很多的变换方向，我们通过特征值分解得到的前N个特征向量，那么就对应了这个矩阵最主要的N个变化方向。我们利用这前N个变化方向，就可以近似这个矩阵（变换）。也就是之前说的：<strong>提取这个矩阵最重要的特征。</strong>总结一下，特征值分解可以得到特征值与特征向量，特征值表示的是这个特征到底有多重要，而特征向量表示这个特征是什么，可以将每一个特征向量理解为一个线性的子空间，我们可以利用这些线性的子空间干很多的事情。不过，<strong>特征值分解也有很多的局限，比如说变换的矩阵必须是方阵。</strong></p>
<p>（说了这么多特征值变换，不知道有没有说清楚，请各位多提提意见。）</p>
<p><span style="font-size: medium;"><strong> 2）奇异值：</strong></span></p>
<p>下面谈谈奇异值分解。特征值分解是一个提取矩阵特征很不错的方法，但是它只是对方阵而言的，在现实的世界中，我们看到的大部分矩阵都不是方阵，比如说有N个学生，每个学生有M科成绩，这样形成的一个N * M的矩阵就不可能是方阵，<strong>我们怎样才能描述这样普通的矩阵呢的重要特征呢？</strong>奇异值分解可以用来干这个事情，<strong>奇异值分解是一个能适用于任意的矩阵的一种分解的方法</strong>：</p>
<p><a class="highslide img_51" href="http://thinkbot.info/wp-content/uploads/2011/01/image53.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb55.png" border="0" alt="image" width="118" height="40" /></a> 假设A是一个N * M的矩阵，那么得到的U是一个N * N的方阵（里面的向量是正交的，U里面的向量称为左奇异向量），Σ是一个N * M的矩阵（除了对角线的元素都是0，对角线上的元素称为奇异值），V’(V的转置)是一个N * N的矩阵，里面的向量也是正交的，V里面的向量称为右奇异向量），从图片来反映几个相乘的矩阵的大小可得下面的图片</p>
<p><a class="highslide img_52" href="http://thinkbot.info/wp-content/uploads/2011/01/image54.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb56.png" border="0" alt="image" width="439" height="152" /></a></p>
<p>那么奇异值和特征值是怎么对应起来的呢？首先，我们将一个矩阵A的转置 * A，将会得到一个方阵，我们用这个方阵求特征值可以得到：<a class="highslide img_53" href="http://thinkbot.info/wp-content/uploads/2011/01/image55.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb57.png" border="0" alt="image" width="153" height="44" /></a> 这里得到的v，就是我们上面的右奇异向量。此外我们还可以得到：</p>
<p><a class="highslide img_54" href="http://thinkbot.info/wp-content/uploads/2011/01/image56.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb58.png" border="0" alt="image" width="100" height="104" /></a> 这里的σ就是上面说的奇异值，u就是上面说的左奇异向量。奇异值σ跟特征值类似，在矩阵Σ中也是从大到小排列，而且σ的减少特别的快，<strong>在很多情况下，前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了</strong>。也就是说，我们也可以用前r大的奇异值来近似描述矩阵，这里定义一下<strong>部分奇异值分解</strong>：</p>
<p><a class="highslide img_55" href="http://thinkbot.info/wp-content/uploads/2011/01/image57.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb59.png" border="0" alt="image" width="204" height="45" /></a></p>
<p>r是一个远小于m、n的数，这样矩阵的乘法看起来像是下面的样子：</p>
<p><a class="highslide img_56" href="http://thinkbot.info/wp-content/uploads/2011/01/image58.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb60.png" border="0" alt="image" width="352" height="184" /></a></p>
<p>右边的三个矩阵相乘的结果将会是一个接近于A的矩阵，在这儿，r越接近于n，则相乘的结果越接近于A。而这三个矩阵的面积之和（在存储观点来说，矩阵面积越小，存储量就越小）要远远小于原始的矩阵A，我们如果想要压缩空间来表示原矩阵A，我们存下这里的三个矩阵：U、Σ、V就好了。</p>
<p><span style="color: #0080ff; font-size: medium;"><strong>二、奇异值的计算：</strong></span></p>
<p>奇异值的计算是一个难题，是一个O(N^3)的算法。在单机的情况下当然是没问题的，matlab在一秒钟内就可以算出1000 * 1000的矩阵的所有奇异值，但是当矩阵的规模增长的时候，计算的复杂度呈3次方增长，就需要并行计算参与了。Google的<strong>吴军</strong>老师在<strong>数学之美</strong>系列谈到SVD的时候，说起Google实现了SVD的并行化算法，说这是对人类的一个贡献，但是也没有给出具体的计算规模，也没有给出太多有价值的信息。</p>
<p>其实SVD还是可以用并行的方式去实现的，在解大规模的矩阵的时候，一般使用迭代的方法，当矩阵的规模很大（比如说上亿）的时候，迭代的次数也可能会上亿次，如果使用Map-Reduce框架去解，则每次Map-Reduce完成的时候，都会涉及到写文件、读文件的操作。个人猜测Google云计算体系中除了Map-Reduce以外应该还有类似于MPI的计算模型，也就是节点之间是保持通信，数据是常驻在内存中的，这种计算模型比Map-Reduce在解决迭代次数非常多的时候，要快了很多倍。</p>
<p><a href="http://en.wikipedia.org/wiki/Lanczos_algorithm" class="aga aga_28">Lanczos迭代</a>就是一种解<strong>对称方阵部分特征值</strong>的方法（之前谈到了，解A’* A得到的对称方阵的特征值就是解A的右奇异向量），是将一个对称的方程化为一个三对角矩阵再进行求解。按网上的一些文献来看，Google应该是用这种方法去做的奇异值分解的。请见Wikipedia上面的一些引用的论文，如果理解了那些论文，也“几乎”可以做出一个SVD了。</p>
<p>由于奇异值的计算是一个很枯燥，纯数学的过程，而且前人的研究成果（论文中）几乎已经把整个程序的流程图给出来了。更多的关于奇异值计算的部分，将在后面的参考文献中给出，这里不再深入，我还是focus在奇异值的应用中去。</p>
<p><span style="color: #0080ff; font-size: medium;"><strong>三、奇异值与主成分分析（PCA）：</strong></span></p>
<p>主成分分析在上一节里面也讲了一些，这里主要谈谈如何用SVD去解PCA的问题。PCA的问题其实是一个基的变换，使得变换后的数据有着最大的方差。方差的大小描述的是一个变量的信息量，我们在讲一个东西的稳定性的时候，往往说要减小方差，如果一个模型的方差很大，那就说明模型不稳定了。但是对于我们用于机器学习的数据（主要是训练数据），方差大才有意义，不然输入的数据都是同一个点，那方差就为0了，这样输入的多个数据就等同于一个数据了。以下面这张图为例子：</p>
<p><a class="highslide img_57" href="http://thinkbot.info/wp-content/uploads/2011/01/image59.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb61.png" border="0" alt="image" width="240" height="184" /></a> 这个假设是一个摄像机采集一个物体运动得到的图片，上面的点表示物体运动的位置，假如我们想要用一条直线去拟合这些点，那我们会选择什么方向的线呢？当然是图上标有signal的那条线。如果我们把这些点单纯的投影到x轴或者y轴上，最后在x轴与y轴上得到的方差是相似的（因为这些点的趋势是在45度左右的方向，所以投影到x轴或者y轴上都是类似的），如果我们使用原来的xy坐标系去看这些点，容易看不出来这些点真正的方向是什么。但是如果我们进行坐标系的变化，横轴变成了signal的方向，纵轴变成了noise的方向，则就很容易发现什么方向的方差大，什么方向的方差小了。</p>
<p>一般来说，方差大的方向是信号的方向，方差小的方向是噪声的方向，我们在数据挖掘中或者数字信号处理中，往往要提高信号与噪声的比例，也就是信噪比。对上图来说，如果我们只保留signal方向的数据，也可以对原数据进行不错的近似了。</p>
<p>PCA的全部工作简单点说，就是对原始的空间中顺序地找一组相互正交的坐标轴，第一个轴是使得方差最大的，第二个轴是在与第一个轴正交的平面中使得方差最大的，第三个轴是在与第1、2个轴正交的平面中方差最大的，这样假设在N维空间中，我们可以找到N个这样的坐标轴，我们取前r个去近似这个空间，这样就从一个N维的空间压缩到r维的空间了，但是我们选择的r个坐标轴能够使得空间的压缩使得数据的损失最小。</p>
<p>还是假设我们矩阵每一行表示一个样本，每一列表示一个feature，用矩阵的语言来表示，将一个m * n的矩阵A的进行坐标轴的变化，P就是一个变换的矩阵从一个N维的空间变换到另一个N维的空间，在空间中就会进行一些类似于旋转、拉伸的变化。</p>
<p><a class="highslide img_58" href="http://thinkbot.info/wp-content/uploads/2011/01/image60.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb62.png" border="0" alt="image" width="160" height="44" /></a></p>
<p>而将一个m * n的矩阵A变换成一个m * r的矩阵，这样就会使得本来有n个feature的，变成了有r个feature了（r &lt; n)，这r个其实就是对n个feature的一种提炼，我们就把这个称为feature的压缩。用数学语言表示就是：</p>
<p><a class="highslide img_59" href="http://thinkbot.info/wp-content/uploads/2011/01/image61.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb63.png" border="0" alt="image" width="167" height="43" /></a> 但是这个怎么和SVD扯上关系呢？之前谈到，SVD得出的奇异向量也是从奇异值由大到小排列的，按PCA的观点来看，就是方差最大的坐标轴就是第一个奇异向量，方差次大的坐标轴就是第二个奇异向量…我们回忆一下之前得到的SVD式子：</p>
<p><a class="highslide img_60" href="http://thinkbot.info/wp-content/uploads/2011/01/image62.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb64.png" border="0" alt="image" width="224" height="43" /></a> 在矩阵的两边同时乘上一个矩阵V，由于V是一个正交的矩阵，所以V转置乘以V得到单位阵I，所以可以化成后面的式子</p>
<p><a class="highslide img_61" href="http://thinkbot.info/wp-content/uploads/2011/01/image63.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb65.png" border="0" alt="image" width="304" height="81" /></a> 将后面的式子与A * P那个m * n的矩阵变换为m * r的矩阵的式子对照看看，在这里，其实V就是P，也就是一个变化的向量。这里是将一个m * n 的矩阵压缩到一个m * r的矩阵，也就是对列进行压缩，如果我们想对行进行压缩（在PCA的观点下，对行进行压缩可以理解为，将一些相似的sample合并在一起，或者将一些没有太大价值的sample去掉）怎么办呢？同样我们写出一个通用的行压缩例子：</p>
<p><a class="highslide img_62" href="http://thinkbot.info/wp-content/uploads/2011/01/image64.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb66.png" border="0" alt="image" width="164" height="39" /></a> 这样就从一个m行的矩阵压缩到一个r行的矩阵了，对SVD来说也是一样的，我们对SVD分解的式子两边乘以U的转置U&#8217;</p>
<p><a class="highslide img_63" href="http://thinkbot.info/wp-content/uploads/2011/01/image65.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb67.png" border="0" alt="image" width="240" height="51" /></a> 这样我们就得到了对行进行压缩的式子。可以看出，其实PCA几乎可以说是对SVD的一个包装，如果我们实现了SVD，那也就实现了PCA了，而且更好的地方是，有了SVD，我们就可以得到两个方向的PCA，如果我们对A’A进行特征值的分解，只能得到一个方向的PCA。</p>
<p><span style="color: #0080ff; font-size: medium;"><strong>四、奇异值与潜在语义索引LSI：</strong></span></p>
<p>潜在语义索引（Latent Semantic Indexing）与PCA不太一样，至少不是实现了SVD就可以直接用的，不过LSI也是一个严重依赖于SVD的算法，之前吴军老师在<a href="http://www.google.com.hk/ggblog/googlechinablog/2006/12/blog-post_8935.html" class="aga aga_29">矩阵计算与文本处理中的分类问题</a>中谈到：</p>
<p><em><span style="font-size: medium;"> “三个矩阵有非常清楚的物理含义。第一个矩阵X中的每一行表示意思相关的一类词，其中的每个非零元素表示这类词中每个词的重要性（或者说相关性），数值越大越相关。最后一个矩阵Y中的每一列表示同一主题一类文章，其中每个元素表示这类文章中每篇文章的相关性。中间的矩阵则表示类词和文章雷之间的相关性。因此，我们只要对关联矩阵A进行一次奇异值分解，w 我们就可以同时完成了近义词分类和文章的分类。（同时得到每类文章和每类词的相关性）。”</span></em></p>
<p>上面这段话可能不太容易理解，不过这就是LSI的精髓内容，我下面举一个例子来说明一下，下面的例子来自LSA tutorial，具体的网址我将在最后的引用中给出：</p>
<p><a class="highslide img_64" href="http://thinkbot.info/wp-content/uploads/2011/01/image66.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb68.png" border="0" alt="image" width="316" height="285" /></a> 这就是一个矩阵，不过不太一样的是，这里的一行表示一个词在哪些title中出现了（一行就是之前说的一维feature），一列表示一个title中有哪些词，（这个矩阵其实是我们之前说的那种一行是一个sample的形式的一种转置，这个会使得我们的左右奇异向量的意义产生变化，但是不会影响我们计算的过程）。比如说T1这个title中就有guide、investing、market、stock四个词，各出现了一次，我们将这个矩阵进行SVD，得到下面的矩阵：</p>
<p><a class="highslide img_65" href="http://thinkbot.info/wp-content/uploads/2011/01/image67.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb69.png" border="0" alt="image" width="624" height="266" /></a> 左奇异向量表示词的一些特性，右奇异向量表示文档的一些特性，中间的奇异值矩阵表示左奇异向量的一行与右奇异向量的一列的重要程序，数字越大越重要。</p>
<p>继续看这个矩阵还可以发现一些有意思的东西，首先，左奇异向量的第一列表示每一个词的出现频繁程度，虽然不是线性的，但是可以认为是一个大概的描述，比如book是0.15对应文档中出现的2次，investing是0.74对应了文档中出现了9次，rich是0.36对应文档中出现了3次；</p>
<p>其次，右奇异向量中一的第一行表示每一篇文档中的出现词的个数的近似，比如说，T6是0.49，出现了5个词，T2是0.22，出现了2个词。</p>
<p>然后我们反过头来看，我们可以将左奇异向量和右奇异向量都取后2维（之前是3维的矩阵），投影到一个平面上，可以得到：</p>
<p><a class="highslide img_66" href="http://thinkbot.info/wp-content/uploads/2011/01/image68.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb70.png" border="0" alt="image" width="497" height="390" /></a> 在图上，每一个红色的点，都表示一个词，每一个蓝色的点，都表示一篇文档，这样我们可以对这些词和文档进行聚类，比如说stock 和 market可以放在一类，因为他们老是出现在一起，real和estate可以放在一类，dads，guide这种词就看起来有点孤立了，我们就不对他们进行合并了。按这样聚类出现的效果，可以提取文档集合中的近义词，这样当用户检索文档的时候，是用语义级别（近义词集合）去检索了，而不是之前的词的级别。这样一减少我们的检索、存储量，因为这样压缩的文档集合和PCA是异曲同工的，二可以提高我们的用户体验，用户输入一个词，我们可以在这个词的近义词的集合中去找，这是传统的索引无法做到的。</p>
<p>不知道按这样描述，再看看吴军老师的文章，是不是对SVD更清楚了？:-D</p>
<p><span style="color: #0080ff; font-size: medium;"><strong>参考资料：</strong></span></p>
<p>1）A Tutorial on Principal Component Analysis, Jonathon Shlens<br />
这是我关于用SVD去做PCA的主要参考资料<br />
2）<a href="http://www.ams.org/samplings/feature-column/fcarc-svd" class="aga aga_30">http://www.ams.org/samplings/feature-column/fcarc-svd</a><br />
关于svd的一篇概念好文，我开头的几个图就是从这儿截取的<br />
3）<a href="http://www.puffinwarellc.com/index.php/news-and-articles/articles/30-singular-value-decomposition-tutorial.html" class="aga aga_31">http://www.puffinwarellc.com/index.php/news-and-articles/articles/30-singular-value-decomposition-tutorial.html</a><br />
另一篇关于svd的入门好文<br />
4）<a href="http://www.puffinwarellc.com/index.php/news-and-articles/articles/33-latent-semantic-analysis-tutorial.html" class="aga aga_32">http://www.puffinwarellc.com/index.php/news-and-articles/articles/33-latent-semantic-analysis-tutorial.html</a><br />
svd与LSI的好文，我后面LSI中例子就是来自此<br />
5）<a href="http://www.miislita.com/information-retrieval-tutorial/svd-lsi-tutorial-1-understanding.html" class="aga aga_33">http://www.miislita.com/information-retrieval-tutorial/svd-lsi-tutorial-1-understanding.html</a><br />
另一篇svd与LSI的文章，也还是不错，深一点，也比较长<br />
6）Singular Value Decomposition and Principal Component Analysis, Rasmus Elsborg Madsen, Lars Kai Hansen and Ole Winther, 2004<br />
跟1）里面的文章比较类似</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2011/01/svd-and-application/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>机器学习中的数学(4)-线性判别分析（LDA）, 主成分分析(PCA)</title>
		<link>http://thinkbot.info/2011/01/lda-pca-machine-learnin/</link>
		<comments>http://thinkbot.info/2011/01/lda-pca-machine-learnin/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 07:09:27 +0000</pubDate>
		<dc:creator>谭望达</dc:creator>
				<category><![CDATA[人工智能]]></category>
		<category><![CDATA[数学]]></category>
		<category><![CDATA[数据挖掘]]></category>
		<category><![CDATA[lda]]></category>
		<category><![CDATA[pca]]></category>
		<category><![CDATA[数理统计]]></category>
		<category><![CDATA[机器学习]]></category>

		<guid isPermaLink="false">http://thinkbot.info/2011/01/%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0%e4%b8%ad%e7%9a%84%e6%95%b0%e5%ad%a64-%e7%ba%bf%e6%80%a7%e5%88%a4%e5%88%ab%e5%88%86%e6%9e%90%ef%bc%88lda%ef%bc%89-%e4%b8%bb%e6%88%90%e5%88%86%e5%88%86%e6%9e%90p/</guid>
		<description><![CDATA[版权声明： 本文由LeftNotEasy发布于http://leftnoteasy.cnblogs.com, 本文可以被全部的转载或者部分使用，但请注明出处，如果有问题，请联系wheeleast@gmail.com 前言： 第二篇的文章中谈到，和部门老大一宁出去outing的时候，他给了我相当多的机器学习的建议，里面涉及到很多的算法的意义、学习方法等等。一宁上次给我提到，如果学习分类算法，最好从线性的入手，线性分类器最简单的就是LDA，它可以看做是简化版的SVM，如果想理解SVM这种分类器，那理解LDA就是很有必要的了。 谈到LDA，就不得不谈谈PCA，PCA是一个和LDA非常相关的算法，从推导、求解、到算法最终的结果，都有着相当的相似。 本次的内容主要是以推导数学公式为主，都是从算法的物理意义出发，然后一步一步最终推导到最终的式子，LDA和PCA最终的表现都是解一个矩阵特征值的问题，但是理解了如何推导，才能更深刻的理解其中的含义。本次内容要求读者有一些基本的线性代数基础，比如说特征值、特征向量的概念，空间投影，点乘等的一些基本知识等。除此之外的其他公式、我都尽量讲得更简单清楚。 LDA： LDA的全称是Linear Discriminant Analysis（线性判别分析），是一种supervised learning。有些资料上也称为是Fisher’s Linear Discriminant，因为它被Ronald Fisher发明自1936年，Discriminant这次词我个人的理解是，一个模型，不需要去通过概率的方法来训练、预测数据，比如说各种贝叶斯方法，就需要获取数据的先验、后验概率等等。LDA是在目前机器学习、数据挖掘领域经典且热门的一个算法，据我所知，百度的商务搜索部里面就用了不少这方面的算法。 LDA的原理是，将带上标签的数据（点），通过投影的方法，投影到维度更低的空间中，使得投影后的点，会形成按类别区分，一簇一簇的情况，相同类别的点，将会在投影后的空间中更接近。要说明白LDA，首先得弄明白线性分类器(Linear Classifier)：因为LDA是一种线性分类器。对于K-分类的一个分类问题，会有K个线性函数： 当满足条件：对于所有的j，都有Yk &#62; Yj,的时候，我们就说x属于类别k。对于每一个分类，都有一个公式去算一个分值，在所有的公式得到的分值中，找一个最大的，就是所属的分类了。 上式实际上就是一种投影，是将一个高维的点投影到一条高维的直线上，LDA最求的目标是，给出一个标注了类别的数据集，投影到了一条直线之后，能够使得点尽量的按类别区分开，当k=2即二分类问题的时候，如下图所示： 红色的方形的点为0类的原始点、蓝色的方形点为1类的原始点，经过原点的那条线就是投影的直线，从图上可以清楚的看到，红色的点和蓝色的点被原点明显的分开了，这个数据只是随便画的，如果在高维的情况下，看起来会更好一点。下面我来推导一下二分类LDA问题的公式： 假设用来区分二分类的直线（投影函数)为： LDA分类的一个目标是使得不同类别之间的距离越远越好，同一类别之中的距离越近越好，所以我们需要定义几个关键的值。 类别i的原始中心点为：（Di表示属于类别i的点) 类别i投影后的中心点为： 衡量类别i投影后，类别点之间的分散程度（方差）为： 最终我们可以得到一个下面的公式，表示LDA投影到w后的损失函数： 我们分类的目标是，使得类别内的点距离越近越好（集中），类别间的点越远越好。分母表示每一个类别内的方差之和，方差越大表示一个类别内的点越分散，分子为两个类别各自的中心点的距离的平方，我们最小化J(w)就可以求出最优的w了。想要求出最优的w，可以使用拉格朗日乘子法，但是现在我们得到的J(w)里面，w是不能被单独提出来的，我们就得想办法将w单独提出来。 我们定义一个投影前的各类别分散程度的矩阵，这个矩阵看起来有一点麻烦，其实意思是，如果某一个分类的输入点集Di里面的点距离这个分类的中心店mi越近，则Si里面元素的值就越小，如果分类的点都紧紧地围绕着mi，则Si里面的元素值越更接近0. 带入Si，将J(w)分母化为： 同样的将J(w)分子化为： 这样损失函数可以化成下面的形式： 这样就可以用最喜欢的拉格朗日乘子法了，但是还有一个问题，如果分子、分母是都可以取任意值的，那就会使得有无穷解，我们将分母限制为长度为1（这是用拉格朗日乘子法一个很重要的技巧，在下面将说的PCA里面也会用到，如果忘记了，请复习一下高数），并作为拉格朗日乘子法的限制条件，带入得到： 这样的式子就是一个求特征值的问题了。 对于N(N&#62;2)分类的问题，我就直接写出下面的结论了： 这同样是一个求特征值的问题，我们求出的第i大的特征向量，就是对应的Wi了。 这里想多谈谈特征值，特征值在纯数学、量子力学、固体力学、计算机等等领域都有广泛的应用，特征值表示的是矩阵的性质，当我们取到矩阵的前N个最大的特征值的时候，我们可以说提取到的矩阵主要的成分（这个和之后的PCA相关，但是不是完全一样的概念）。在机器学习领域，不少的地方都要用到特征值的计算，比如说图像识别、pagerank、LDA、还有之后将会提到的PCA等等。 下图是图像识别中广泛用到的特征脸（eigen face），提取出特征脸有两个目的，首先是为了压缩数据，对于一张图片，只需要保存其最重要的部分就是了，然后是为了使得程序更容易处理，在提取主要特征的时候，很多的噪声都被过滤掉了。跟下面将谈到的PCA的作用非常相关。 特征值的求法有很多，求一个D * D的矩阵的时间复杂度是O(D^3), 也有一些求Top M的方法，比如说power method，它的时间复杂度是O(D^2 * M), 总体来说，求特征值是一个很费时间的操作，如果是单机环境下，是很局限的。 PCA： 主成分分析（PCA）与LDA有着非常近似的意思，LDA的输入数据是带标签的，而PCA的输入数据是不带标签的，所以PCA是一种unsupervised learning。LDA通常来说是作为一个独立的算法存在，给定了训练数据后，将会得到一系列的判别函数（discriminate function），之后对于新的输入，就可以进行预测了。而PCA更像是一个预处理的方法，它可以将原本的数据降低维度，而使得降低了维度的数据之间的方差最大（也可以说投影误差最小，具体在之后的推导里面会谈到）。 方差这个东西是个很有趣的，有些时候我们会考虑减少方差（比如说训练模型的时候，我们会考虑到方差-偏差的均衡），有的时候我们会尽量的增大方差。方差就像是一种信仰（强哥的话），不一定会有很严密的证明，从实践来说，通过尽量增大投影方差的PCA算法，确实可以提高我们的算法质量。 说了这么多，推推公式可以帮助我们理解。我下面将用两种思路来推导出一个同样的表达式。首先是最大化投影后的方差，其次是最小化投影后的损失（投影产生的损失最小）。 [...]]]></description>
			<content:encoded><![CDATA[<p><strong><span style="font-size: medium;">版权声明：</span></strong></p>
<p>本文由LeftNotEasy发布于<a href="http://leftnoteasy.cnblogs.com" class="aga aga_38">http://leftnoteasy.cnblogs.com</a>, 本文可以被全部的转载或者部分使用，但请注明出处，如果有问题，请联系<a href="mailto:wheeleast@gmail.com">wheeleast@gmail.com</a></p>
<p><strong><span style="font-size: medium;">前言：</span></strong></p>
<p><a href="http://www.cnblogs.com/LeftNotEasy/archive/2010/12/19/mathmatic_in_machine_learning_2_regression_and_bias_variance_trade_off.html" class="aga aga_39">第二篇</a>的文章中谈到，和部门老大一宁出去outing的时候，他给了我相当多的机器学习的建议，里面涉及到很多的算法的意义、学习方法等等。一宁上次给我提到，如果学习分类算法，最好从线性的入手，线性分类器最简单的就是LDA，它可以看做是简化版的SVM，如果想理解SVM这种分类器，那理解LDA就是很有必要的了。</p>
<p>谈到LDA，就不得不谈谈PCA，PCA是一个和LDA非常相关的算法，从推导、求解、到算法最终的结果，都有着相当的相似。</p>
<p>本次的内容主要是以推导数学公式为主，都是从算法的物理意义出发，然后一步一步最终推导到最终的式子，LDA和PCA最终的表现都是解一个矩阵特征值的问题，但是理解了如何推导，才能更深刻的理解其中的含义。本次内容要求读者有一些基本的线性代数基础，比如说特征值、特征向量的概念，空间投影，点乘等的一些基本知识等。除此之外的其他公式、我都尽量讲得更简单清楚。</p>
<p><strong><span style="font-size: medium;">LDA：</span></strong></p>
<p>LDA的全称是Linear Discriminant Analysis（线性判别分析），<strong>是一种supervised learning。</strong>有些资料上也称为是Fisher’s Linear Discriminant，因为它被Ronald Fisher发明自1936年，Discriminant这次词我个人的理解是，一个模型，不需要去通过概率的方法来训练、预测数据，比如说各种贝叶斯方法，就需要获取数据的先验、后验概率等等。LDA是在<strong>目前机器学习、数据挖掘领域经典且热门</strong>的一个算法，据我所知，百度的商务搜索部里面就用了不少这方面的算法。</p>
<p>LDA的原理是，将带上标签的数据（点），通过投影的方法，投影到维度更低的空间中，使得投影后的点，会形成按类别区分，一簇一簇的情况，相同类别的点，将会在投影后的空间中更接近。要说明白LDA，首先得弄明白线性分类器(<a href="http://en.wikipedia.org/wiki/Linear_classifier" class="aga aga_40">Linear Classifier</a>)：因为LDA是一种线性分类器。对于K-分类的一个分类问题，会有K个线性函数：</p>
<p><a class="highslide img_93" href="http://thinkbot.info/wp-content/uploads/2011/01/image21.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb22.png" border="0" alt="image" width="153" height="33" /></a></p>
<p>当满足条件：对于所有的j，都有Yk &gt; Yj,的时候，我们就说x属于类别k。对于每一个分类，都有一个公式去算一个分值，在所有的公式得到的分值中，找一个最大的，就是所属的分类了。</p>
<p>上式实际上就是一种投影，是将一个高维的点投影到一条高维的直线上，LDA最求的目标是，给出一个标注了类别的数据集，投影到了一条直线之后，能够使得点尽量的按类别区分开，当k=2即二分类问题的时候，如下图所示：</p>
<p><a class="highslide img_94" href="file:///C:\Documents%20and%20Settings\Administrator\Local%20Settings\Temp\WindowsLiveWriter-429641856\supfiles4CEE5\image%5b15%5d.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="clip_image002" src="http://thinkbot.info/wp-content/uploads/2011/01/clip_image002.gif" border="0" alt="clip_image002" width="328" height="318" /></a></p>
<p>红色的方形的点为0类的原始点、蓝色的方形点为1类的原始点，经过原点的那条线就是投影的直线，从图上可以清楚的看到，红色的点和蓝色的点被<strong>原点</strong>明显的分开了，这个数据只是随便画的，如果在高维的情况下，看起来会更好一点。下面我来推导一下二分类LDA问题的公式：</p>
<p>假设用来区分二分类的直线（投影函数)为：</p>
<p><a class="highslide img_95" href="http://thinkbot.info/wp-content/uploads/2011/01/image22.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb23.png" border="0" alt="image" width="84" height="32" /></a></p>
<p>LDA分类的一个目标是使得不同类别之间的距离越远越好，同一类别之中的距离越近越好，所以我们需要定义几个关键的值。</p>
<p>类别i的原始中心点为：（Di表示属于类别i的点)<a class="highslide img_96" href="http://thinkbot.info/wp-content/uploads/2011/01/image23.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb24.png" border="0" alt="image" width="106" height="55" /></a></p>
<p>类别i投影后的中心点为：</p>
<p><a class="highslide img_97" href="http://thinkbot.info/wp-content/uploads/2011/01/image24.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb25.png" border="0" alt="image" width="105" height="41" /></a></p>
<p>衡量类别i投影后，类别点之间的分散程度（方差）为：</p>
<p><a class="highslide img_98" href="http://thinkbot.info/wp-content/uploads/2011/01/image25.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb26.png" border="0" alt="image" width="163" height="62" /></a></p>
<p>最终我们可以得到一个下面的公式，表示LDA投影到w后的损失函数：</p>
<p><a class="highslide img_99" href="http://thinkbot.info/wp-content/uploads/2011/01/image26.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb27.png" border="0" alt="image" width="159" height="73" /></a></p>
<p>我们<strong>分类的目标是，使得类别内的点距离越近越好（集中），类别间的点越远越好。</strong>分母表示每一个类别内的方差之和，方差越大表示一个类别内的点越分散，分子为两个类别各自的中心点的距离的平方，我们最小化J(w)就可以求出最优的w了。想要求出最优的w，可以使用拉格朗日乘子法，但是现在我们得到的J(w)里面，w是不能被单独提出来的，我们就得想办法将w单独提出来。</p>
<p>我们定义一个投影前的各类别分散程度的矩阵，这个矩阵看起来有一点麻烦，其实意思是，如果某一个分类的输入点集Di里面的点距离这个分类的中心店mi越近，则Si里面元素的值就越小，如果分类的点都紧紧地围绕着mi，则Si里面的元素值越更接近0.</p>
<p><a class="highslide img_100" href="http://thinkbot.info/wp-content/uploads/2011/01/image27.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb28.png" border="0" alt="image" width="212" height="54" /></a></p>
<p>带入Si，将J(w)分母化为：</p>
<p><a class="highslide img_101" href="http://thinkbot.info/wp-content/uploads/2011/01/image28.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb29.png" border="0" alt="image" width="521" height="57" /></a></p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb30.png" border="0" alt="image" width="314" height="42" /></p>
<p>同样的将J(w)分子化为：</p>
<p><a class="highslide img_102" href="http://thinkbot.info/wp-content/uploads/2011/01/image29.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb31.png" border="0" alt="image" width="383" height="41" /></a></p>
<p>这样损失函数可以化成下面的形式：</p>
<p><a class="highslide img_103" href="http://thinkbot.info/wp-content/uploads/2011/01/image30.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb32.png" border="0" alt="image" width="139" height="56" /></a></p>
<p>这样就可以用最喜欢的拉格朗日乘子法了，但是还有一个问题，如果分子、分母是都可以取任意值的，那就会使得有无穷解，我们将分母限制为长度为1（这是用拉格朗日乘子法一个很重要的技巧，在下面将说的PCA里面也会用到，如果忘记了，请复习一下高数），并作为拉格朗日乘子法的限制条件，带入得到：</p>
<p><a class="highslide img_104" href="http://thinkbot.info/wp-content/uploads/2011/01/image31.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb33.png" border="0" alt="image" width="266" height="123" /></a></p>
<p>这样的式子就是一个求特征值的问题了。</p>
<p>对于N(N&gt;2)分类的问题，我就直接写出下面的结论了：</p>
<p><a class="highslide img_105" href="http://thinkbot.info/wp-content/uploads/2011/01/image32.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb34.png" border="0" alt="image" width="240" height="143" /></a></p>
<p>这同样是一个求特征值的问题，我们求出的第i大的特征向量，就是对应的Wi了。</p>
<p>这里想多谈谈特征值，特征值在纯数学、量子力学、固体力学、计算机等等领域都有广泛的应用，特征值表示的是矩阵的性质，当我们取到矩阵的前N个最大的特征值的时候，我们可以说提取到的矩阵主要的成分（这个和之后的PCA相关，但是不是完全一样的概念）。在机器学习领域，不少的地方都要用到特征值的计算，比如说图像识别、pagerank、LDA、还有之后将会提到的PCA等等。</p>
<p>下图是图像识别中广泛用到的特征脸（eigen face），提取出特征脸有两个目的，首先是为了压缩数据，对于一张图片，只需要保存其最重要的部分就是了，然后是为了使得程序更容易处理，在提取主要特征的时候，很多的噪声都被过滤掉了。跟下面将谈到的PCA的作用非常相关。</p>
<p><a class="highslide img_106" href="http://thinkbot.info/wp-content/uploads/2011/01/image33.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb35.png" border="0" alt="image" width="192" height="230" /></a></p>
<p>特征值的求法有很多，求一个D * D的矩阵的时间复杂度是O(D^3), 也有一些求Top M的方法，比如说<a href="http://en.wikipedia.org/wiki/Power_method" class="aga aga_41">power method</a>，它的时间复杂度是O(D^2 * M), 总体来说，求特征值是一个很费时间的操作，如果是单机环境下，是很局限的。</p>
<p><strong><span style="font-size: medium;">PCA：</span></strong></p>
<p>主成分分析（PCA）与LDA有着非常近似的意思，LDA的输入数据是带标签的，而PCA的输入数据是不带标签的，所以PCA是一种unsupervised learning。LDA通常来说是作为一个独立的算法存在，给定了训练数据后，将会得到一系列的判别函数（discriminate function），之后对于新的输入，就可以进行预测了。而PCA更像是一个预处理的方法，它可以将原本的数据降低维度，而使得降低了维度的数据之间的方差最大（也可以说投影误差最小，具体在之后的推导里面会谈到）。</p>
<p>方差这个东西是个很有趣的，有些时候我们会考虑减少方差（比如说训练模型的时候，我们会考虑到方差-偏差的均衡），有的时候我们会尽量的增大方差。方差就像是一种信仰（强哥的话），不一定会有很严密的证明，从实践来说，通过尽量增大投影方差的PCA算法，确实可以提高我们的算法质量。</p>
<p>说了这么多，推推公式可以帮助我们理解。<strong>我下面将用两种思路来推导出一个同样的表达式。首先是最大化投影后的方差，其次是最小化投影后的损失（投影产生的损失最小）。</strong></p>
<p><strong> 最大化方差法：</strong></p>
<p>假设我们还是将一个空间中的点投影到一个向量中去。首先，给出原空间的中心点：</p>
<p><a class="highslide img_107" href="http://thinkbot.info/wp-content/uploads/2011/01/image34.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb36.png" border="0" alt="image" width="113" height="61" /></a> 假设u1为投影向量，投影之后的方差为：</p>
<p><a class="highslide img_108" href="http://thinkbot.info/wp-content/uploads/2011/01/image35.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb37.png" border="0" alt="image" width="240" height="60" /></a> 上面这个式子如果看懂了之前推导LDA的过程，应该比较容易理解，如果线性代数里面的内容忘记了，可以再温习一下，优化上式等号右边的内容，还是用拉格朗日乘子法：</p>
<p><a class="highslide img_109" href="http://thinkbot.info/wp-content/uploads/2011/01/image36.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb38.png" border="0" alt="image" width="162" height="38" /></a> 将上式求导，使之为0，得到：</p>
<p><a class="highslide img_110" href="http://thinkbot.info/wp-content/uploads/2011/01/image37.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb39.png" border="0" alt="image" width="79" height="33" /></a> 这是一个标准的特征值表达式了，λ对应的特征值，u对应的特征向量。上式的左边取得最大值的条件就是λ1最大，也就是取得最大的特征值的时候。假设我们是要将一个D维的数据空间投影到M维的数据空间中（M &lt; D)， 那我们取前M个特征向量构成的投影矩阵就是能够使得方差最大的矩阵了。</p>
<p><strong> 最小化损失法：</strong></p>
<p>假设输入数据x是在D维空间中的点，那么，我们可以用D个正交的D维向量去完全的表示这个空间（这个空间中所有的向量都可以用这D个向量的线性组合得到）。在D维空间中，有无穷多种可能找这D个正交的D维向量，哪个组合是最合适的呢？</p>
<p>假设我们已经找到了这D个向量，可以得到：</p>
<p><a class="highslide img_111" href="http://thinkbot.info/wp-content/uploads/2011/01/image38.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb40.png" border="0" alt="image" width="100" height="58" /></a> 我们可以用近似法来表示投影后的点：</p>
<p><a class="highslide img_112" href="http://thinkbot.info/wp-content/uploads/2011/01/image39.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb41.png" border="0" alt="image" width="191" height="68" /></a> 上式表示，得到的新的x是由前M 个基的线性组合加上后D &#8211; M个基的线性组合，注意这里的z是对于每个x都不同的，而b对于每个x是相同的，这样我们就可以用M个数来表示空间中的一个点，也就是使得数据降维了。但是这样降维后的数据，必然会产生一些扭曲，我们用J描述这种扭曲，我们的目标是，使得J最小：</p>
<p><a class="highslide img_113" href="http://thinkbot.info/wp-content/uploads/2011/01/image40.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb42.png" border="0" alt="image" width="163" height="58" /></a> 上式的意思很直观，就是对于每一个点，将降维后的点与原始的点之间的距离的平方和加起来，求平均值，我们就要使得这个平均值最小。我们令：</p>
<p><a class="highslide img_114" href="http://thinkbot.info/wp-content/uploads/2011/01/image41.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb43.png" border="0" alt="image" width="344" height="50" /></a> 将上面得到的z与b带入降维的表达式：</p>
<p><a class="highslide img_115" href="http://thinkbot.info/wp-content/uploads/2011/01/image42.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb44.png" border="0" alt="image" width="240" height="57" /></a> 将上式带入J的表达式得到：</p>
<p><a class="highslide img_116" href="http://thinkbot.info/wp-content/uploads/2011/01/image43.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb45.png" border="0" alt="image" width="366" height="66" /></a> 再用上拉普拉斯乘子法（此处略），可以得到，取得我们想要的投影基的表达式为：</p>
<p><a class="highslide img_117" href="http://thinkbot.info/wp-content/uploads/2011/01/image44.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb46.png" border="0" alt="image" width="85" height="41" /></a> 这里又是一个特征值的表达式，我们想要的前M个向量其实就是这里最大的M个特征值所对应的特征向量。证明这个还可以看看，我们J可以化为：</p>
<p><a class="highslide img_118" href="http://thinkbot.info/wp-content/uploads/2011/01/image45.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb47.png" border="0" alt="image" width="85" height="60" /></a> 也就是当误差J是由最小的D &#8211; M个特征值组成的时候，J取得最小值。跟上面的意思相同。</p>
<p>下图是PCA的投影的一个表示，黑色的点是原始的点，带箭头的虚线是投影的向量，Pc1表示特征值最大的特征向量，pc2表示特征值次大的特征向量，两者是彼此正交的，因为这原本是一个2维的空间，所以最多有两个投影的向量，如果空间维度更高，则投影的向量会更多。</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://lion.cs.uiuc.edu/projects/wmn/fig2.jpg" alt="" width="284" height="208" /></p>
<p><span style="font-size: medium;"><strong>总结：</strong></span></p>
<p>本次主要讲了两种方法，PCA与LDA，两者的思想和计算方法非常类似，但是一个是作为独立的算法存在，另一个更多的用于数据的预处理的工作。另外对于PCA和LDA还有核方法，本次的篇幅比较大了，先不说了，以后有时间再谈：</p>
<p><span style="font-size: medium;"><strong>参考资料：</strong></span></p>
<p>prml bishop，introduce to LDA（对不起，这个真没有查到出处）</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2011/01/lda-pca-machine-learnin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>机器学习中的数学(3)-模型组合(Model Combining)之Boosting与Gradient Boosting</title>
		<link>http://thinkbot.info/2011/01/model-combining-boosting-and-gradient-descent/</link>
		<comments>http://thinkbot.info/2011/01/model-combining-boosting-and-gradient-descent/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 14:06:12 +0000</pubDate>
		<dc:creator>谭望达</dc:creator>
				<category><![CDATA[人工智能]]></category>
		<category><![CDATA[数学]]></category>
		<category><![CDATA[boosting]]></category>
		<category><![CDATA[GBDT]]></category>
		<category><![CDATA[gradient descent]]></category>
		<category><![CDATA[数据挖掘]]></category>
		<category><![CDATA[机器学习]]></category>

		<guid isPermaLink="false">http://thinkbot.info/2011/01/%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0%e4%b8%ad%e7%9a%84%e6%95%b0%e5%ad%a63-%e6%a8%a1%e5%9e%8b%e7%bb%84%e5%90%88model-combining%e4%b9%8bboosting%e4%b8%8egradient-boosting/</guid>
		<description><![CDATA[版权声明：     本文由LeftNotEasy发布于http://thinkbot.info, 本文可以被全部的转载或者部分使用，但请注明出处，如果有问题，请联系wheeleast@gmail.com 前言：     本来上一章的结尾提到，准备写写线性分类的问题，文章都已经写得差不多了，但是突然听说最近Team准备做一套分布式的分类器，可能会使用Random Forest来做，下了几篇论文看了看，简单的random forest还比较容易弄懂，复杂一点的还会与boosting等算法结合（参见iccv09），对于boosting也不甚了解，所以临时抱佛脚的看了看。说起boosting，强哥之前实现过一套Gradient Boosting Descent Tree（GBDT)算法，正好参考一下。     最近看的一些论文中发现了模型组合的好处，比如GBDT或者rf，都是将简单的模型组合起来，效果比单个更复杂的模型好。组合的方式很多，随机化（比如random forest），Boosting（比如GBDT）都是其中典型的方法，今天主要谈谈Gradient Boosting方法（这个与传统的Boosting还有一些不同）的一些数学基础，有了这个数学基础，上面的应用可以看Freidman的Gradient Boosting Machine。     本文要求读者学过基本的大学数学，另外对分类、回归等基本的机器学习概念了解。     本文主要参考资料是prml与Gradient Boosting Machine。 Boosting方法：     Boosting这其实思想相当的简单，大概是，对一份数据，建立M个模型（比如分类），一般这种模型比较简单，称为弱分类器(weak learner)每次分类都将上一次分错的数据权重提高一点再进行分类，这样最终得到的分类器在测试数据与训练数据上都可以得到比较好的成绩。         上图（图片来自prml p660）就是一个Boosting的过程，绿色的线表示目前取得的模型（模型是由前m次得到的模型合并得到的），虚线表示当前这次模型。每次分类的时候，会更关注分错的数据，上图中，红色和蓝色的点就是数据，点越大表示权重越高，看看右下角的图片，当m=150的时候，获取的模型已经几乎能够将红色和蓝色的点区分开了。     Boosting可以用下面的公式来表示：     训练集中一共有n个点，我们可以为里面的每一个点赋上一个权重Wi(0 &#60;= i &#60; n)，表示这个点的重要程度，通过依次训练模型的过程，我们对点的权重进行修正，如果分类正确了，权重提高，如果分类错了，则权重降低，初始的时候，权重都是一样的。上图中绿色的线就是表示依次训练模型，可以想象得到，程序越往后执行，训练出的模型就越会在意那些容易分错的点。当全部的程序执行完后，会得到M个模型，分别对应上图的y1(x)…yM(x)，通过加权的方式组合成一个最终的模型YM(x)。     我觉得Boosting更像是一个人学习的过程，开始学一样东西的时候，会去做一些习题，但是常常连一些简单的题目都会弄错，但是越到后面，简单的题目已经难不倒他了，就会去做更复杂的题目，等到他做了很多的题目后，不管是难题还是简单的题都可以解决掉了。 Gradient Boosting方法：     其实Boosting更像是一种思想，Gradient Boosting是一种Boosting的方法，它主要的思想是，每一次建立模型是在之前建立模型损失函数的梯度下降方向。这句话有一点拗口，损失函数(loss function)描述的是模型的不靠谱程度，损失函数越大，则说明模型越容易出错（其实这里有一个方差、偏差均衡的问题，但是这里就假设损失函数越大，模型越容易出错）。如果我们的模型能够让损失函数持续的下降，则说明我们的模型在不停的改进，而最好的方式就是让损失函数在其梯度（Gradient)的方向上下降。     下面的内容就是用数学的方式来描述Gradient Boosting，数学上不算太复杂，只要潜下心来看就能看懂：）     可加的参数的梯度表示：     假设我们的模型能够用下面的函数来表示，P表示参数，可能有多个参数组成，P [...]]]></description>
			<content:encoded><![CDATA[<p><strong><span style="font-size: medium;">版权声明：</span></strong></p>
<p>    本文由LeftNotEasy发布于<a href="http://thinkbot.info" >http://thinkbot.info</a>, 本文可以被全部的转载或者部分使用，但请注明出处，如果有问题，请联系<a href="mailto:wheeleast@gmail.com">wheeleast@gmail.com</a></p>
<p><span style="font-size: medium;"><strong>前言：</strong></span></p>
<p>    本来上一章的结尾提到，准备写写线性分类的问题，文章都已经写得差不多了，但是突然听说最近Team准备做一套分布式的分类器，可能会使用Random Forest来做，下了几篇论文看了看，简单的random forest还比较容易弄懂，复杂一点的还会与boosting等算法结合（参见iccv09），对于boosting也不甚了解，所以临时抱佛脚的看了看。说起boosting，<a href="http://bqzhao.blogspot.com/" class="aga aga_44">强哥</a>之前实现过一套Gradient Boosting Descent Tree（GBDT)算法，正好参考一下。</p>
<p>    最近看的一些论文中发现了模型组合的好处，比如GBDT或者rf，都是将简单的模型组合起来，效果比单个更复杂的模型好。组合的方式很多，随机化（比如random forest），Boosting（比如GBDT）都是其中典型的方法，今天主要谈谈Gradient Boosting方法（这个与传统的Boosting还有一些不同）的一些数学基础，有了这个数学基础，上面的应用可以看Freidman的Gradient Boosting Machine。</p>
<p>    本文要求读者学过基本的大学数学，另外对分类、回归等基本的机器学习概念了解。</p>
<p>    本文主要参考资料是prml与Gradient Boosting Machine。</p>
<p><span style="font-size: medium;"><strong>Boosting方法：</strong></span></p>
<p>    Boosting这其实思想相当的简单，大概是，对一份数据，建立M个模型（比如分类），一般这种模型比较简单，称为弱分类器(weak learner)每次分类都将上一次分错的数据权重提高一点再进行分类，这样最终得到的分类器在测试数据与训练数据上都可以得到比较好的成绩。</p>
<p>    <a class="highslide img_140" href="http://thinkbot.info/wp-content/uploads/2011/01/image.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb.png" border="0" alt="image" width="588" height="284" /></a></p>
<p>    上图（图片来自prml p660）就是一个Boosting的过程，绿色的线表示目前取得的模型（模型是由前m次得到的模型合并得到的），虚线表示当前这次模型。每次分类的时候，会更关注分错的数据，上图中，红色和蓝色的点就是数据，点越大表示权重越高，看看右下角的图片，当m=150的时候，获取的模型已经几乎能够将红色和蓝色的点区分开了。</p>
<p>    Boosting可以用下面的公式来表示：<a class="highslide img_141" href="http://thinkbot.info/wp-content/uploads/2011/01/image1.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb1.png" border="0" alt="image" width="386" height="270" /></a></p>
<p>    训练集中一共有n个点，我们可以为里面的每一个点赋上一个权重Wi(0 &lt;= i &lt; n)，表示这个点的重要程度，通过依次训练模型的过程，我们对点的权重进行修正，如果分类正确了，权重提高，如果分类错了，则权重降低，初始的时候，权重都是一样的。上图中绿色的线就是表示依次训练模型，<strong>可以想象得到，程序越往后执行，训练出的模型就越会在意那些容易分错的点。</strong>当全部的程序执行完后，会得到M个模型，分别对应上图的y1(x)…yM(x)，通过加权的方式组合成一个最终的模型YM(x)。</p>
<p>    我觉得Boosting更像是一个人学习的过程，开始学一样东西的时候，会去做一些习题，但是常常连一些简单的题目都会弄错，但是越到后面，简单的题目已经难不倒他了，就会去做更复杂的题目，等到他做了很多的题目后，不管是难题还是简单的题都可以解决掉了。</p>
<p><span style="font-size: medium;"><strong>Gradient Boosting方法：</strong></span></p>
<p>    其实Boosting更像是一种思想，Gradient Boosting是一种Boosting的方法，它主要的思想是，每一次建立模型是在之前建立模型损失函数的梯度下降方向。这句话有一点拗口，损失函数(loss function)描述的是模型的不靠谱程度，损失函数越大，则说明模型越容易出错（其实这里有一个<a href="http://www.cnblogs.com/LeftNotEasy/archive/2010/12/19/mathmatic_in_machine_learning_2_regression_and_bias_variance_trade_off.html" class="aga aga_45">方差、偏差均衡</a>的问题，但是这里就假设损失函数越大，模型越容易出错）。如果我们的模型能够让损失函数持续的下降，则说明我们的模型在不停的改进，而最好的方式就是让损失函数在其梯度（Gradient)的方向上下降。</p>
<p>    下面的内容就是用数学的方式来描述Gradient Boosting，数学上不算太复杂，只要潜下心来看就能看懂：）</p>
<p><strong><span style="font-size: small; color: #0080ff;">    可加的参数的梯度表示：</span></strong></p>
<p>    假设我们的模型能够用下面的函数来表示，P表示参数，可能有多个参数组成，P = {p0,p1,p2….}，F(x;P)表示以P为参数的x的函数，也就是我们的预测函数。我们的模型是由多个模型加起来的，β表示每个模型的权重，α表示模型里面的参数。为了优化F，我们就可以优化{β,α}也就是P。</p>
<p><a class="highslide img_142" href="http://thinkbot.info/wp-content/uploads/2011/01/image2.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb2.png" border="0" alt="image" width="329" height="48" /></a></p>
<p>    我们还是用P来表示模型的参数，可以得到，Φ(P)表示P的likelihood函数，也就是模型F(x;P)的loss函数，Φ(P)=…后面的一块看起来很复杂，只要理解成是一个损失函数就行了，不要被吓跑了。</p>
<p><a class="highslide img_143" href="http://thinkbot.info/wp-content/uploads/2011/01/image3.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb3.png" border="0" alt="image" width="226" height="61" /></a>   既然模型(F(x;P))是可加的，对于参数P，我们也可以得到下面的式子：<a class="highslide img_144" href="http://thinkbot.info/wp-content/uploads/2011/01/image4.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb4.png" border="0" alt="image" width="101" height="73" /></a>   这样优化P的过程，就可以是一个梯度下降的过程了，假设当前已经得到了m-1个模型，想要得到第m个模型的时候，我们首先对前m-1个模型求梯度。得到最快下降的方向，gm就是最快下降的方向。</p>
<p><a class="highslide img_145" href="http://thinkbot.info/wp-content/uploads/2011/01/image5.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb5.png" border="0" alt="image" width="240" height="54" /></a>    这里有一个很重要的假设，<strong>对于求出的前m-1个模型，我们认为是已知的了，不要去改变它，而我们的目标是放在之后的模型建立上。</strong>就像做事情的时候，之前做错的事就没有后悔药吃了，只有努力在之后的事情上别犯错：</p>
<p><a class="highslide img_146" href="http://thinkbot.info/wp-content/uploads/2011/01/image6.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb6.png" border="0" alt="image" width="99" height="47" /></a>    我们得到的新的模型就是，它就在P似然函数的梯度方向。ρ是在梯度方向上下降的距离。</p>
<p><a class="highslide img_147" href="http://thinkbot.info/wp-content/uploads/2011/01/image7.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb7.png" border="0" alt="image" width="111" height="44" /></a>    我们最终可以通过优化下面的式子来得到最优的ρ：</p>
<p><a class="highslide img_148" href="http://thinkbot.info/wp-content/uploads/2011/01/image8.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb8.png" border="0" alt="image" width="240" height="33" /></a></p>
<p><span style="font-size: small; color: #0080ff;"><strong>    可加的函数的梯度表示：</strong></span></p>
<p>    上面通过参数P的可加性，得到了参数P的似然函数的梯度下降的方法。我们可以将参数P的可加性推广到函数空间，我们可以得到下面的函数，此处的fi(x)类似于上面的h(x;α)，因为作者的文献中这样使用，我这里就用作者的表达方法：</p>
<p><a class="highslide img_149" href="http://thinkbot.info/wp-content/uploads/2011/01/image9.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb9.png" border="0" alt="image" width="296" height="63" /></a>    同样，我们可以得到函数F(x)的梯度下降方向g(x)</p>
<p><a class="highslide img_150" href="http://thinkbot.info/wp-content/uploads/2011/01/image10.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb10.png" border="0" alt="image" width="464" height="62" /></a>    最终可以得到第m个模型fm(x)的表达式:</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb11.png" border="0" alt="image" width="156" height="35" /></p>
<p><span style="font-size: small; color: #0080ff;"><strong>    通用的Gradient Descent Boosting的框架： </strong></span></p>
<p>   下面我将推导一下Gradient Descent方法的通用形式，之前讨论过的：</p>
<p><a class="highslide img_151" href="http://thinkbot.info/wp-content/uploads/2011/01/image11.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb12.png" border="0" alt="image" width="186" height="51" /></a>    对于模型的参数{β,α}，我们可以用下面的式子来进行表示，这个式子的意思是，对于N个样本点(xi,yi)计算其在模型F(x;α,β)下的损失函数，最优的{α,β}就是能够使得这个损失函数最小的{α,β}。<a class="highslide img_152" href="http://thinkbot.info/wp-content/uploads/2011/01/image12.png"  onclick="return hs.expand(this)"><img style="display: inline; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb13.png" border="0" alt="image" width="71" height="32" /></a> 表示两个m维的参数：</p>
<p><a class="highslide img_153" href="http://thinkbot.info/wp-content/uploads/2011/01/image13.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb14.png" border="0" alt="image" width="319" height="48" /></a>    写成梯度下降的方式就是下面的形式，也就是我们将要得到的模型fm(x)的参数{αm,βm}能够使得fm的方向是之前得到的模型Fm-1(x)的损失函数下降最快的方向：</p>
<p><a class="highslide img_154" href="http://thinkbot.info/wp-content/uploads/2011/01/image14.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb15.png" border="0" alt="image" width="341" height="47" /></a></p>
<p>    对于每一个数据点xi都可以得到一个gm(xi)，最终我们可以得到一个完整梯度下降方向</p>
<p><a class="highslide img_155" href="http://thinkbot.info/wp-content/uploads/2011/01/image15.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb16.png" border="0" alt="image" width="150" height="47" /></a></p>
<p><a class="highslide img_156" href="http://thinkbot.info/wp-content/uploads/2011/01/image16.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb17.png" border="0" alt="image" width="240" height="54" /></a>    为了使得fm(x)能够在gm(x)的方向上，我们可以优化下面的式子得到，可以使用最小二乘法：</p>
<p><a class="highslide img_157" href="http://thinkbot.info/wp-content/uploads/2011/01/image17.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb18.png" border="0" alt="image" width="291" height="49" /></a>    得到了α的基础上，然后可以得到βm。   <a class="highslide img_158" href="http://thinkbot.info/wp-content/uploads/2011/01/image18.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb19.png" border="0" alt="image" width="313" height="47" /></a>    最终合并到模型中：</p>
<p><a class="highslide img_159" href="http://thinkbot.info/wp-content/uploads/2011/01/image19.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb20.png" border="0" alt="image" width="240" height="45" /></a></p>
<p>    算法的流程图如下</p>
<p><a class="highslide img_160" href="http://thinkbot.info/wp-content/uploads/2011/01/image20.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2011/01/image_thumb21.png" border="0" alt="image" width="468" height="219" /></a>     之后，作者还说了这个算法在其他的地方的推广，其中，Multi-class logistic regression and classification就是GBDT的一种实现，可以看看，流程图跟上面的算法类似的。这里不打算继续写下去，再写下去就成论文翻译了，请参考文章：Greedy function Approximation – A Gradient Boosting Machine，作者Freidman。</p>
<p><span style="font-size: medium;"><strong>总结：</strong></span></p>
<p>    本文主要谈了谈Boosting与Gradient Boosting的方法，Boosting主要是一种思想，表示“知错就改”。而Gradient Boosting是在这个思想下的一种函数（也可以说是模型）的优化的方法，首先将函数分解为可加的形式（其实所有的函数都是可加的，只是是否好放在这个框架中，以及最终的效果如何）。然后进行m次迭代，通过使得损失函数在梯度方向上减少，最终得到一个优秀的模型。值得一提的是，每次模型在梯度方向上的减少的部分，可以认为是一个“小”的或者“弱”的模型，最终我们会通过加权(也就是每次在梯度方向上下降的距离）的方式将这些“弱”的模型合并起来，形成一个更好的模型。</p>
<p>    有了这个Gradient Descent这个基础，还可以做很多的事情。也在机器学习的道路上更进一步了：）</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2011/01/model-combining-boosting-and-gradient-descent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>机器学习中的数学(2)-线性回归，偏差、方差权衡</title>
		<link>http://thinkbot.info/2010/12/mathmatic_in_machine_learning_2_regression_and_bias_variance_trade_off/</link>
		<comments>http://thinkbot.info/2010/12/mathmatic_in_machine_learning_2_regression_and_bias_variance_trade_off/#comments</comments>
		<pubDate>Sun, 19 Dec 2010 10:12:55 +0000</pubDate>
		<dc:creator>谭望达</dc:creator>
				<category><![CDATA[人工智能]]></category>
		<category><![CDATA[数学]]></category>
		<category><![CDATA[数据挖掘]]></category>
		<category><![CDATA[regression]]></category>
		<category><![CDATA[数理统计]]></category>
		<category><![CDATA[机器学习]]></category>

		<guid isPermaLink="false">http://thinkbot.info/2010/12/%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0%e4%b8%ad%e7%9a%84%e6%95%b0%e5%ad%a62-%e7%ba%bf%e6%80%a7%e5%9b%9e%e5%bd%92%ef%bc%8c%e5%81%8f%e5%b7%ae%e3%80%81%e6%96%b9%e5%b7%ae%e6%9d%83%e8%a1%a1/</guid>
		<description><![CDATA[版权声明： 本文发布于http://thinkbot.info。如果转载，请注明出处，在未经作者同意下将本文用于商业用途，将追究其法律责任。如果有问题，请联系作者 wheeleast@gmail.com 前言： 距离上次发文章，也快有半个月的时间了，这半个月的时间里又在学习机器学习的道路上摸索着前进，积累了一点心得，以后会慢慢的写写这些心得。写文章是促进自己对知识认识的一个好方法，看书的时候往往不是非常细，所以有些公式、知识点什么的就一带而过，里面的一些具体意义就不容易理解了。而写文章，特别是写科普性的文章，需要对里面的具体意义弄明白，甚至还要能举出更生动的例子，这是一个挑战。为了写文章，往往需要把之前自己认为看明白的内容重新理解一下。 机器学习可不是一个完全的技术性的东西，之前和部门老大在outing的时候一直在聊这个问题，机器学习绝对不是一个一个孤立的算法堆砌起来的，想要像看《算法导论》这样看机器学习是个不可取的方法，机器学习里面有几个东西一直贯穿全书，比如说数据的分布、最大似然（以及求极值的几个方法，不过这个比较数学了），偏差、方差的权衡，还有特征选择，模型选择，混合模型等等知识，这些知识像砖头、水泥一样构成了机器学习里面的一个个的算法。想要真正学好这些算法，一定要静下心来将这些基础知识弄清楚，才能够真正理解、实现好各种机器学习算法。 今天的主题是线性回归，也会提一下偏差、方差的均衡这个主题。 线性回归定义： 在上一个主题中，也是一个与回归相关的，不过上一节更侧重于梯度这个概念，这一节更侧重于回归本身与偏差和方差的概念。 回归最简单的定义是，给出一个点集D，用一个函数去拟合这个点集，并且使得点集与拟合函数间的误差最小。 上图所示，给出一个点集(x,y), 需要用一个函数去拟合这个点集，蓝色的点是点集中的点，而红色的曲线是函数的曲线，第一张图是一个最简单的模型，对应的函数为y = f(x) = ax + b，这个就是一个线性函数， 第二张图是二次曲线，对应的函数是y = f(x) = ax^2 + b。 第三张图我也不知道是什么函数，瞎画的。 第四张图可以认为是一个N次曲线，N = M &#8211; 1，M是点集中点的个数，有一个定理是，对于给定的M个点，我们可以用一个M &#8211; 1次的函数去完美的经过这个点集。 真正的线性回归，不仅会考虑使得曲线与给定点集的拟合程度最好，还会考虑模型最简单，这个话题我们将在本章后面的偏差、方差的权衡中深入的说，另外这个话题还可以参考我之前的一篇文章：贝叶斯、概率分布与机器学习，里面对模型复杂度的问题也进行了一些讨论。 线性回归(linear regression)，并非是指的线性函数，也就是 （为了方便起见，以后向量我就不在上面加箭头了） x0,x1…表示一个点不同的维度，比如说上一节中提到的，房子的价钱是由包括面积、房间的个数、房屋的朝向等等因素去决定的。而是用广义的线性函数： wj是系数，w就是这个系数组成的向量，它影响着不同维度的Φj(x)在回归函数中的影响度，比如说对于房屋的售价来说，房间朝向的w一定比房间面积的w更小。Φ(x)是可以换成不同的函数，不一定要求Φ(x)=x，这样的模型我们认为是广义线性模型。 最小二乘法与最大似然： 这个话题在此处有一个很详细的讨论，我这里主要谈谈这个问题的理解。最小二乘法是线性回归中一个最简单的方法，它的推导有一个假设，就是回归函数的估计值与真实值间的误差假设是一个高斯分布。这个用公式来表示是下面的样子： ，y(x,w)就是给定了w系数向量下的回归函数的估计值，而t就是真实值了，ε表示误差。我们可以接下来推出下面的式子： 这是一个简单的条件概率表达式，表示在给定了x，w，β的情况下，得到真实值t的概率，由于ε服从高斯分布，则从估计值到真实值间的概率也是高斯分布的，看起来像下面的样子： 贝叶斯、概率分布与机器学习这篇文章中对分布影响结果这个话题讨论比较多，可以回过头去看看，由于最小二乘法有这样一个假设，则会导致，如果我们给出的估计函数y(x,w)与真实值t不是高斯分布的，甚至是一个差距很大的分布，那么算出来的模型一定是不正确的，当给定一个新的点x’想要求出一个估计值y’，与真实值t’可能就非常的远了。 概率分布是一个可爱又可恨的东西，当我们能够准确的预知某些数据的分布时，那我们可以做出一个非常精确的模型去预测它，但是在大多数真实的应用场景中，数据的分布是不可知的，我们也很难去用一个分布、甚至多个分布的混合去表示数据的真实分布，比如说给定了1亿篇网页，希望用一个现有的分布（比如说混合高斯分布）去匹配里面词频的分布，是不可能的。在这种情况下，我们只能得到词的出现概率，比如p(的)的概率是0.5，也就是一个网页有1/2的概率出现“的”。如果一个算法，是对里面的分布进行了某些假设，那么可能这个算法在真实的应用中就会表现欠佳。最小二乘法对于类似的一个复杂问题，就很无力了 偏差、方差的权衡(trade-off)： 偏差(bias)和方差(variance)是统计学的概念，刚进公司的时候，看到每个人的嘴里随时蹦出这两个词，觉得很可怕。首先得明确的，方差是多个模型间的比较，而非对一个模型而言的，对于单独的一个模型，比如说: 这样的一个给定了具体系数的估计函数，是不能说f(x)的方差是多少。而偏差可以是单个数据集中的，也可以是多个数据集中的，这个得看具体的定义。 方差和偏差一般来说，是从同一个数据集中，用科学的采样方法得到几个不同的子数据集，用这些子数据集得到的模型，就可以谈他们的方差和偏差的情况了。方差和偏差的变化一般是和模型的复杂程度成正比的，就像本文一开始那四张小图片一样，当我们一味的追求模型精确匹配，则可能会导致同一组数据训练出不同的模型，它们之间的差异非常大。这就叫做方差，不过他们的偏差就很小了，如下图所示： 上图的蓝色和绿色的点是表示一个数据集中采样得到的不同的子数据集，我们有两个N次的曲线去拟合这些点集，则可以得到两条曲线（蓝色和深绿色），它们的差异就很大，但是他们本是由同一个数据集生成的，这个就是模型复杂造成的方差大。模型越复杂，偏差就越小，而模型越简单，偏差就越大，方差和偏差是按下面的方式进行变化的: 当方差和偏差加起来最优的点，就是我们最佳的模型复杂度。 用一个很通俗的例子来说，现在咱们国家一味的追求GDP，GDP就像是模型的偏差，国家希望现有的GDP和目标的GDP差异尽量的小，但是其中使用了很多复杂的手段，比如说倒卖土地、强拆等等，这个增加了模型的复杂度，也会使得偏差（居民的收入分配）变大，穷的人越穷(被赶出城市的人与进入城市买不起房的人），富的人越富（倒卖土地的人与卖房子的人）。其实本来模型不需要这么复杂，能够让居民的收入分配与国家的发展取得一个平衡的模型是最好的模型。 最后还是用数学的语言来描述一下偏差和方差： E(L)是损失函数，h(x)表示真实值的平均，第一部分是与y（模型的估计函数）有关的，这个部分是由于我们选择不同的估计函数（模型）带来的差异，而第二部分是与y无关的，这个部分可以认为是模型的固有噪声。 对于上面公式的第一部分，我们可以化成下面的形式： [...]]]></description>
			<content:encoded><![CDATA[<p><strong><span style="font-size: medium;">版权声明：</span></strong></p>
<p>本文发布于<a href="http://thinkbot.info" >http://thinkbot.info</a>。如果转载，请注明出处，在未经作者同意下将本文用于商业用途，将追究其法律责任。如果有问题，请联系作者 wheeleast@gmail.com</p>
<p><strong><span style="font-size: medium;">前言：</span></strong></p>
<p>距离上次发文章，也快有半个月的时间了，这半个月的时间里又在学习机器学习的道路上摸索着前进，积累了一点心得，以后会慢慢的写写这些心得。写文章是促进自己对知识认识的一个好方法，看书的时候往往不是非常细，所以有些公式、知识点什么的就一带而过，里面的一些具体意义就不容易理解了。而写文章，特别是写科普性的文章，需要对里面的具体意义弄明白，甚至还要能举出更生动的例子，这是一个挑战。为了写文章，往往需要把之前自己认为看明白的内容重新理解一下。</p>
<p>机器学习可不是一个完全的技术性的东西，之前和部门老大在outing的时候一直在聊这个问题，机器学习绝对不是一个一个孤立的算法堆砌起来的，想要像看《算法导论》这样看机器学习是个不可取的方法，机器学习里面有几个东西一直贯穿全书，比如说数据的分布、最大似然（以及求极值的几个方法，不过这个比较数学了），偏差、方差的权衡，还有特征选择，模型选择，混合模型等等知识，这些知识像砖头、水泥一样构成了机器学习里面的一个个的算法。想要真正学好这些算法，一定要静下心来将这些基础知识弄清楚，才能够真正理解、实现好各种机器学习算法。</p>
<p>今天的主题是线性回归，也会提一下偏差、方差的均衡这个主题。</p>
<p><strong><span style="font-size: medium;">线性回归定义：</span></strong></p>
<p>在<a href="http://www.cnblogs.com/LeftNotEasy/archive/2010/12/05/mathmatic_in_machine_learning_1_regression_and_gradient_descent.html" class="aga aga_50">上一个主题</a>中，也是一个与回归相关的，不过上一节更侧重于梯度这个概念，这一节更侧重于回归本身与偏差和方差的概念。</p>
<p>回归最简单的定义是，给出一个点集D，用一个函数去拟合这个点集，并且使得点集与拟合函数间的误差最小。</p>
<p><a class="highslide img_173" href="http://thinkbot.info/wp-content/uploads/2010/12/image12.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb12.png" border="0" alt="image" width="521" height="364" /></a> 上图所示，给出一个点集(x,y), 需要用一个函数去拟合这个点集，蓝色的点是点集中的点，而红色的曲线是函数的曲线，第一张图是一个最简单的模型，对应的函数为y = f(x) = ax + b，这个就是一个线性函数，</p>
<p>第二张图是二次曲线，对应的函数是y = f(x) = ax^2 + b。</p>
<p>第三张图我也不知道是什么函数，瞎画的。</p>
<p>第四张图可以认为是一个N次曲线，N = M &#8211; 1，M是点集中点的个数，有一个定理是，对于给定的M个点，我们可以用一个M &#8211; 1次的函数去完美的经过这个点集。</p>
<p>真正的线性回归，不仅会考虑使得曲线与给定点集的拟合程度最好，还会考虑模型最简单，这个话题我们将在本章后面的偏差、方差的权衡中深入的说，另外这个话题还可以参考我之前的一篇文章：<a href="http://www.cnblogs.com/LeftNotEasy/archive/2010/09/27/1837163.html" class="aga aga_51">贝叶斯、概率分布与机器学习</a>，里面对模型复杂度的问题也进行了一些讨论。</p>
<p>线性回归(linear regression)，并非是指的线性函数，也就是</p>
<p><a class="highslide img_174" href="http://thinkbot.info/wp-content/uploads/2010/12/image13.png"  onclick="return hs.expand(this)"><img style="display: inline; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb13.png" border="0" alt="image" width="240" height="34" /></a> （为了方便起见，以后向量我就不在上面加箭头了）</p>
<p>x0,x1…表示一个点不同的维度，比如说上一节中提到的，房子的价钱是由包括面积、房间的个数、房屋的朝向等等因素去决定的。而是用广义的线性函数：</p>
<p><a class="highslide img_175" href="http://thinkbot.info/wp-content/uploads/2010/12/image14.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb14.png" border="0" alt="image" width="240" height="48" /></a> wj是系数，w就是这个系数组成的向量，它影响着不同维度的Φj(x)在回归函数中的影响度，比如说对于房屋的售价来说，房间朝向的w一定比房间面积的w更小。Φ(x)是可以换成不同的函数，不一定要求Φ(x)=x，这样的模型我们认为是广义线性模型。</p>
<p><strong><span style="font-size: medium;">最小二乘法与最大似然：</span></strong></p>
<p>这个话题在<a href="http://zh.wikipedia.org/zh-cn/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95" class="aga aga_52">此处</a>有一个很详细的讨论，我这里主要谈谈这个问题的理解。最小二乘法是线性回归中一个最简单的方法，它的推导有一个假设，就是<strong>回归函数的估计值与真实值间的误差假设是一个高斯分布</strong>。这个用公式来表示是下面的样子：<a class="highslide img_176" href="http://thinkbot.info/wp-content/uploads/2010/12/image15.png"  onclick="return hs.expand(this)"><img style="display: inline; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb15.png" border="0" alt="image" width="103" height="22" /></a> ，y(x,w)就是给定了w系数向量下的回归函数的估计值，而t就是真实值了，ε表示误差。我们可以接下来推出下面的式子：</p>
<p><a class="highslide img_177" href="http://thinkbot.info/wp-content/uploads/2010/12/image16.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb16.png" border="0" alt="image" width="240" height="29" /></a> 这是一个简单的条件概率表达式，表示在给定了x，w，β的情况下，得到真实值t的概率，由于ε服从高斯分布，则从估计值到真实值间的概率也是高斯分布的，看起来像下面的样子：</p>
<p><a class="highslide img_178" href="http://thinkbot.info/wp-content/uploads/2010/12/image17.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb17.png" border="0" alt="image" width="240" height="187" /></a> <a href="http://www.cnblogs.com/LeftNotEasy/archive/2010/09/27/1837163.html" class="aga aga_53">贝叶斯、概率分布与机器学习</a>这篇文章中对分布影响结果这个话题讨论比较多，可以回过头去看看，由于最小二乘法有这样一个假设，则会导致，如果我们给出的估计函数y(x,w)与真实值t不是高斯分布的，甚至是一个差距很大的分布，那么算出来的模型一定是不正确的，当给定一个新的点x’想要求出一个估计值y’，与真实值t’可能就非常的远了。</p>
<p>概率分布是一个可爱又可恨的东西，当我们能够准确的预知某些数据的分布时，那我们可以做出一个非常精确的模型去预测它，但是在大多数真实的应用场景中，数据的分布是不可知的，我们也很难去用一个分布、甚至多个分布的混合去表示数据的真实分布，比如说给定了1亿篇网页，希望用一个现有的分布（比如说混合高斯分布）去匹配里面词频的分布，是不可能的。在这种情况下，我们只能得到词的出现概率，比如p(的)的概率是0.5，也就是一个网页有1/2的概率出现“的”。如果一个算法，是对里面的分布进行了某些假设，那么可能这个算法在真实的应用中就会表现欠佳。<strong>最小二乘法对于类似的一个复杂问题，就很无力了</strong></p>
<p><strong><span style="font-size: medium;">偏差、方差的权衡(trade-off)：</span></strong></p>
<p>偏差(bias)和方差(variance)是统计学的概念，刚进公司的时候，看到每个人的嘴里随时蹦出这两个词，觉得很可怕。首先得明确的，方差是多个模型间的比较，而非对一个模型而言的，对于单独的一个模型，比如说:</p>
<p><a class="highslide img_179" href="http://thinkbot.info/wp-content/uploads/2010/12/image13.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb13.png" border="0" alt="image" width="240" height="34" /></a></p>
<p>这样的一个给定了具体系数的估计函数，是不能说f(x)的方差是多少。而偏差可以是单个数据集中的，也可以是多个数据集中的，这个得看具体的定义。</p>
<p>方差和偏差一般来说，是从同一个数据集中，用科学的采样方法得到几个不同的子数据集，用这些子数据集得到的模型，就可以谈他们的方差和偏差的情况了。方差和偏差的变化一般是和模型的复杂程度成正比的，就像本文一开始那四张小图片一样，当我们一味的追求模型精确匹配，则可能会导致同一组数据训练出不同的模型，它们之间的差异非常大。这就叫做方差，不过他们的偏差就很小了，如下图所示：</p>
<p><a class="highslide img_180" href="http://thinkbot.info/wp-content/uploads/2010/12/image18.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb18.png" border="0" alt="image" width="416" height="293" /></a> 上图的蓝色和绿色的点是表示一个数据集中采样得到的不同的子数据集，我们有两个N次的曲线去拟合这些点集，则可以得到两条曲线（蓝色和深绿色），它们的差异就很大，但是他们本是由同一个数据集生成的，这个就是模型复杂造成的方差大。模型越复杂，偏差就越小，而模型越简单，偏差就越大，方差和偏差是按下面的方式进行变化的:</p>
<p><a class="highslide img_181" href="http://thinkbot.info/wp-content/uploads/2010/12/image19.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb19.png" border="0" alt="image" width="384" height="325" /></a> 当方差和偏差加起来最优的点，就是我们最佳的模型复杂度。</p>
<p>用一个很通俗的例子来说，现在咱们国家一味的追求GDP，GDP就像是模型的偏差，国家希望现有的GDP和目标的GDP差异尽量的小，但是其中使用了很多复杂的手段，比如说倒卖土地、强拆等等，这个增加了模型的复杂度，也会使得偏差（居民的收入分配）变大，穷的人越穷(被赶出城市的人与进入城市买不起房的人），富的人越富（倒卖土地的人与卖房子的人）。其实本来模型不需要这么复杂，能够让居民的收入分配与国家的发展取得一个平衡的模型是最好的模型。</p>
<p>最后还是用数学的语言来描述一下偏差和方差：</p>
<p><a class="highslide img_182" href="http://thinkbot.info/wp-content/uploads/2010/12/image20.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb20.png" border="0" alt="image" width="385" height="34" /></a> E(L)是损失函数，h(x)表示真实值的平均，第一部分是与y（模型的估计函数）有关的，这个部分是由于我们选择不同的估计函数（模型）带来的差异，而第二部分是与y无关的，这个部分可以认为是模型的固有噪声。</p>
<p>对于上面公式的第一部分，我们可以化成下面的形式：</p>
<p><a class="highslide img_183" href="http://thinkbot.info/wp-content/uploads/2010/12/image21.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb21.png" border="0" alt="image" width="413" height="59" /></a> 这个部分在PRML的1.5.5推导，前一半是表示偏差，而后一半表示方差，我们可以得出：损失函数=偏差^2+方差+固有噪音。</p>
<p>下图也来自PRML：</p>
<p><a class="highslide img_184" href="http://thinkbot.info/wp-content/uploads/2010/12/image22.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb22.png" border="0" alt="image" width="445" height="457" /></a></p>
<p>这是一个曲线拟合的问题，对同分布的不同的数据集进行了多次的曲线拟合，左边表示方差，右边表示偏差，绿色是真实值函数。ln lambda表示模型的复杂程度，这个值越小，表示模型的复杂程度越高，在第一行，大家的复杂度都很低（每个人都很穷）的时候，方差是很小的，但是偏差同样很小（国家也很穷），但是到了最后一幅图，我们可以得到，每个人的复杂程度都很高的情况下，不同的函数就有着天壤之别了（贫富差异大），但是偏差就很小了（国家很富有）。</p>
<p><strong><span style="font-size: medium;">预告：</span></strong></p>
<p>接下来准备谈谈线性分类的一些问题，敬请关注：）</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2010/12/mathmatic_in_machine_learning_2_regression_and_bias_variance_trade_off/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>机器学习中的数学(1)-回归(regression)、梯度下降(gradient descent)</title>
		<link>http://thinkbot.info/2010/12/math-in-machine-learning-regression-gradient_descent/</link>
		<comments>http://thinkbot.info/2010/12/math-in-machine-learning-regression-gradient_descent/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 12:30:45 +0000</pubDate>
		<dc:creator>谭望达</dc:creator>
				<category><![CDATA[数学]]></category>
		<category><![CDATA[数据挖掘]]></category>
		<category><![CDATA[gradient]]></category>
		<category><![CDATA[regression]]></category>
		<category><![CDATA[数理统计]]></category>
		<category><![CDATA[机器学习]]></category>

		<guid isPermaLink="false">http://thinkbot.info/2010/12/%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0%e4%b8%ad%e7%9a%84%e6%95%b0%e5%ad%a61-%e5%9b%9e%e5%bd%92regression%e3%80%81%e6%a2%af%e5%ba%a6%e4%b8%8b%e9%99%8dgradient-descent/</guid>
		<description><![CDATA[前言: 上次写过一篇关于贝叶斯概率论的数学，最近时间比较紧，coding的任务比较重，不过还是抽空看了一些机器学习的书和视频，其中很推荐两个：一个是stanford的machine learning公开课，在verycd可下载，可惜没有翻译。不过还是可以看。另外一个是prml-pattern recognition and machine learning, Bishop的一部反响不错的书，而且是2008年的，算是比较新的一本书了。 前几天还准备写一个分布式计算的系列，只写了个开头，又换到写这个系列了。以后看哪边的心得更多，就写哪一个系列吧。最近干的事情比较杂，有跟机器学习相关的，有跟数学相关的，也有跟分布式相关的。 这个系列主要想能够用数学去描述机器学习，想要学好机器学习，首先得去理解其中的数学意义，不一定要到能够轻松自如的推导中间的公式，不过至少得认识这些式子吧，不然看一些相关的论文可就看不懂了，这个系列主要将会着重于去机器学习的数学描述这个部分，将会覆盖但不一定局限于回归、聚类、分类等算法。 回归与梯度下降： 回归在数学上来说是给定一个点集，能够用一条曲线去拟合之，如果这个曲线是一条直线，那就被称为线性回归，如果曲线是一条二次曲线，就被称为二次回归，回归还有很多的变种，如locally weighted回归，logistic回归，等等，这个将在后面去讲。 用一个很简单的例子来说明回归，这个例子来自很多的地方，也在很多的open source的软件中看到，比如说weka。大概就是，做一个房屋价值的评估系统，一个房屋的价值来自很多地方，比如说面积、房间的数量（几室几厅）、地段、朝向等等，这些影响房屋价值的变量被称为特征(feature)，feature在机器学习中是一个很重要的概念，有很多的论文专门探讨这个东西。在此处，为了简单，假设我们的房屋就是一个变量影响的，就是房屋的面积。 假设有一个房屋销售的数据如下： 面积(m^2)  销售价钱（万元） 123            250 150            320 87              160 102            220 …               … 这个表类似于帝都5环左右的房屋价钱，我们可以做出一个图，x轴是房屋的面积。y轴是房屋的售价，如下： 如果来了一个新的面积，假设在销售价钱的记录中没有的，我们怎么办呢？ 我们可以用一条曲线去尽量准的拟合这些数据，然后如果有新的输入过来，我们可以在将曲线上这个点对应的值返回。如果用一条直线去拟合，可能是下面的样子： 绿色的点就是我们想要预测的点。 首先给出一些概念和常用的符号，在不同的机器学习书籍中可能有一定的差别。 房屋销售记录表 &#8211; 训练集(training set)或者训练数据(training data), 是我们流程中的输入数据，一般称为x 房屋销售价钱 &#8211; 输出数据，一般称为y 拟合的函数（或者称为假设或者模型），一般写做 y = h(x) 训练数据的条目数(#training set), 一条训练数据是由一对输入数据和输出数据组成的 输入数据的维度(特征的个数，#features)，n 下面是一个典型的机器学习的过程，首先给出一个输入数据，我们的算法会通过一系列的过程得到一个估计的函数，这个函数有能力对没有见过的新数据给出一个新的估计，也被称为构建一个模型。就如同上面的线性回归函数。 我们用X1，X2..Xn 去描述feature里面的分量，比如x1=房间的面积，x2=房间的朝向，等等，我们可以做出一个估计函数： θ在这儿称为参数，在这儿的意思是调整feature中每个分量的影响力，就是到底是房屋的面积更重要还是房屋的地段更重要。为了如果我们令X0 = [...]]]></description>
			<content:encoded><![CDATA[<p><strong><span style="font-size: medium;">前言:</span></strong></p>
<p>上次写过一篇关于贝叶斯概率论的数学，最近时间比较紧，coding的任务比较重，不过还是抽空看了一些机器学习的书和视频，其中很推荐两个：一个是stanford的machine learning公开课，在verycd可下载，可惜没有翻译。不过还是可以看。另外一个是prml-pattern recognition and machine learning, Bishop的一部反响不错的书，而且是2008年的，算是比较新的一本书了。</p>
<p>前几天还准备写一个分布式计算的系列，只写了个开头，又换到写这个系列了。以后看哪边的心得更多，就写哪一个系列吧。最近干的事情比较杂，有跟机器学习相关的，有跟数学相关的，也有跟分布式相关的。</p>
<p>这个系列主要想能够用数学去描述机器学习，想要学好机器学习，首先得去理解其中的数学意义，不一定要到能够轻松自如的推导中间的公式，不过至少得认识这些式子吧，不然看一些相关的论文可就看不懂了，这个系列主要将会着重于去机器学习的数学描述这个部分，将会覆盖但不一定局限于回归、聚类、分类等算法。</p>
<p><strong><span style="font-size: medium;">回归与梯度下降：</span></strong></p>
<p>回归在数学上来说是给定一个点集，能够用一条曲线去拟合之，如果这个曲线是一条直线，那就被称为线性回归，如果曲线是一条二次曲线，就被称为二次回归，回归还有很多的变种，如locally weighted回归，logistic回归，等等，这个将在后面去讲。</p>
<p>用一个很简单的例子来说明回归，这个例子来自很多的地方，也在很多的open source的软件中看到，比如说weka。大概就是，做一个房屋价值的评估系统，一个房屋的价值来自很多地方，比如说面积、房间的数量（几室几厅）、地段、朝向等等，这些影响房屋价值的变量被称为特征(feature)，feature在机器学习中是一个很重要的概念，有很多的论文专门探讨这个东西。在此处，为了简单，假设我们的房屋就是一个变量影响的，就是房屋的面积。</p>
<p>假设有一个房屋销售的数据如下：</p>
<p>面积(m^2)  销售价钱（万元）</p>
<p>123            250</p>
<p>150            320</p>
<p>87              160</p>
<p>102            220</p>
<p>…               …</p>
<p>这个表类似于帝都5环左右的房屋价钱，我们可以做出一个图，x轴是房屋的面积。y轴是房屋的售价，如下：</p>
<p><a class="highslide img_197" href="http://thinkbot.info/wp-content/uploads/2010/12/image.png"  onclick="return hs.expand(this)"><img style="display: inline; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb.png" border="0" alt="image" width="240" height="155" /></a></p>
<p>如果来了一个新的面积，假设在销售价钱的记录中没有的，我们怎么办呢？</p>
<p>我们可以用一条曲线去尽量准的拟合这些数据，然后如果有新的输入过来，我们可以在将曲线上这个点对应的值返回。如果用一条直线去拟合，可能是下面的样子：</p>
<p><a class="highslide img_198" href="http://thinkbot.info/wp-content/uploads/2010/12/image1.png"  onclick="return hs.expand(this)"><img style="display: inline; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb1.png" border="0" alt="image" width="240" height="166" /></a></p>
<p>绿色的点就是我们想要预测的点。</p>
<p>首先给出一些概念和常用的符号，在不同的机器学习书籍中可能有一定的差别。</p>
<p>房屋销售记录表 &#8211; 训练集(training set)或者训练数据(training data), 是我们流程中的输入数据，一般称为x</p>
<p>房屋销售价钱 &#8211; 输出数据，一般称为y</p>
<p>拟合的函数（或者称为假设或者模型），一般写做 y = h(x)</p>
<p>训练数据的条目数(#training set), 一条训练数据是由一对输入数据和输出数据组成的</p>
<p>输入数据的维度(特征的个数，#features)，n</p>
<p>下面是一个典型的机器学习的过程，首先给出一个输入数据，我们的算法会通过一系列的过程得到一个估计的函数，这个函数有能力对没有见过的新数据给出一个新的估计，也被称为构建一个模型。就如同上面的线性回归函数。</p>
<p><a class="highslide img_199" href="http://thinkbot.info/wp-content/uploads/2010/12/image2.png"  onclick="return hs.expand(this)"><img style="display: inline; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb2.png" border="0" alt="image" width="312" height="176" /></a></p>
<p>我们用X1，X2..Xn 去描述feature里面的分量，比如x1=房间的面积，x2=房间的朝向，等等，我们可以做出一个估计函数：</p>
<p><a class="highslide img_200" href="http://thinkbot.info/wp-content/uploads/2010/12/image3.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb3.png" border="0" alt="image" width="240" height="29" /></a></p>
<p>θ在这儿称为参数，在这儿的意思是调整feature中每个分量的影响力，就是到底是房屋的面积更重要还是房屋的地段更重要。为了如果我们令X0 = 1，就可以用向量的方式来表示了：</p>
<p><a class="highslide img_201" href="http://thinkbot.info/wp-content/uploads/2010/12/image4.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb4.png" border="0" alt="image" width="124" height="30" /></a></p>
<p>我们程序也需要一个机制去评估我们θ是否比较好，所以说需要对我们做出的h函数进行评估，一般这个函数称为损失函数（loss function）或者错误函数(error function)，描述h函数<strong>不好</strong>的程度，在下面，我们称这个函数为J函数</p>
<p>在这儿我们可以做出下面的一个错误函数：</p>
<p><a class="highslide img_202" href="http://thinkbot.info/wp-content/uploads/2010/12/image5.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb5.png" border="0" alt="image" width="240" height="89" /></a></p>
<p>这个错误估计函数是去对x(i)的估计值与真实值y(i)差的平方和作为错误估计函数，前面乘上的1/2是为了在求导的时候，这个系数就不见了。</p>
<p>如何调整θ以使得J(θ)取得最小值有很多方法，其中有最小二乘法(min square)，是一种完全是数学描述的方法，在stanford机器学习开放课最后的部分会推导最小二乘法的公式的来源，这个来很多的机器学习和数学书上都可以找到，这里就不提最小二乘法，而谈谈梯度下降法。</p>
<p>梯度下降法是按下面的流程进行的：</p>
<p>1）首先对θ赋值，这个值可以是随机的，也可以让θ是一个全零的向量。</p>
<p>2）改变θ的值，使得J(θ)按梯度下降的方向进行减少。</p>
<p>为了更清楚，给出下面的图：</p>
<p><a class="highslide img_203" href="http://thinkbot.info/wp-content/uploads/2010/12/image6.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb6.png" border="0" alt="image" width="350" height="258" /></a> 这是一个表示参数θ与误差函数J(θ)的关系图，红色的部分是表示J(θ)有着比较高的取值，我们需要的是，能够让J(θ)的值尽量的低。也就是深蓝色的部分。θ0，θ1表示θ向量的两个维度。</p>
<p>在上面提到梯度下降法的第一步是给θ给一个初值，假设随机给的初值是在图上的十字点。</p>
<p>然后我们将θ按照梯度下降的方向进行调整，就会使得J(θ)往更低的方向进行变化，如图所示，算法的结束将是在θ下降到无法继续下降为止。</p>
<p><a class="highslide img_204" href="http://thinkbot.info/wp-content/uploads/2010/12/image7.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb7.png" border="0" alt="image" width="303" height="222" /></a> 当然，可能梯度下降的最终点并非是全局最小点，可能是一个局部最小点，可能是下面的情况：</p>
<p><a class="highslide img_205" href="http://thinkbot.info/wp-content/uploads/2010/12/image8.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb8.png" border="0" alt="image" width="315" height="234" /></a></p>
<p>上面这张图就是描述的一个局部最小点，这是我们重新选择了一个初始点得到的，看来我们这个算法将会在很大的程度上被初始点的选择影响而陷入局部最小点</p>
<p>下面我将用一个例子描述一下梯度减少的过程，对于我们的函数J(θ)求偏导J：（求导的过程如果不明白，可以温习一下微积分）</p>
<p><a class="highslide img_206" href="http://thinkbot.info/wp-content/uploads/2010/12/image9.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb9.png" border="0" alt="image" width="334" height="41" /></a></p>
<p>下面是更新的过程，也就是θi会向着梯度最小的方向进行减少。θi表示更新之前的值，-后面的部分表示按梯度方向减少的量，α表示步长，也就是每次按照梯度减少的方向变化多少。</p>
<p><a class="highslide img_207" href="http://thinkbot.info/wp-content/uploads/2010/12/image10.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb10.png" border="0" alt="image" width="340" height="52" /></a> 一个很重要的地方值得注意的是，梯度是有方向的，对于一个向量θ，每一维分量θi都可以求出一个梯度的方向，我们就可以找到一个整体的方向，在变化的时候，我们就朝着下降最多的方向进行变化就可以达到一个最小点，不管它是局部的还是全局的。</p>
<p>用更简单的数学语言进行描述步骤2）是这样的：</p>
<p><a class="highslide img_208" href="http://thinkbot.info/wp-content/uploads/2010/12/image11.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://thinkbot.info/wp-content/uploads/2010/12/image_thumb11.png" border="0" alt="image" width="128" height="179" /></a> 倒三角形表示梯度，按这种方式来表示，θi就不见了，看看用好向量和矩阵，真的会大大的简化数学的描述啊。</p>
<p><span style="font-size: medium;"><strong>总结与预告：</strong></span></p>
<p>本文中的内容主要取自stanford的课程第二集，希望我把意思表达清楚了：）本系列的下一篇文章也将会取自stanford课程的第三集，下一次将会深入的讲讲回归、logistic回归、和Newton法，不过本系列并不希望做成stanford课程的笔记版，再往后面就不一定完全与stanford课程保持一致了。</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2010/12/math-in-machine-learning-regression-gradient_descent/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>分布式计算概述</title>
		<link>http://thinkbot.info/2010/12/an_introduce_to_parallel_computing/</link>
		<comments>http://thinkbot.info/2010/12/an_introduce_to_parallel_computing/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 16:24:41 +0000</pubDate>
		<dc:creator>谭望达</dc:creator>
				<category><![CDATA[云计算]]></category>
		<category><![CDATA[分布式计算]]></category>
		<category><![CDATA[MapReduce]]></category>
		<category><![CDATA[并行计算]]></category>
		<category><![CDATA[数据挖掘]]></category>

		<guid isPermaLink="false">http://thinkbot.info/?p=131</guid>
		<description><![CDATA[前言： 云计算以及很多误解 云计算这个概念被炒作得非常的火热，只要跟互联网沾边的公司，都喜欢用上云计算这个词。云计算其实不是一个那样广义的概念，云计算的定义并不是若干台机器用某种方式管理起来，然后用于存储或者计算这么简单，包括很多的云杀毒、云安全、云存储等等，都不一定是真正的云计算。 上wikipedia可以看看相对来说比较完备的云计算定义，云计算一个很重要的特性是跟虚拟化相关的，像水、电一样为用户提供计算的资源。另外在key features这个章节上说明了很多云计算的特性，如果某一个系统只具备了里面的一个或者很少的几个特性，那称其为云计算就有点那么勉强了。 云计算一些很重要的特性包括 1）可扩展性，用户能够方便的增加、减少计算和存储的能力，而且有着足够的扩展性。按这个定义、一堆GPU或者CPU组成的网格可能就很难称为云计算了，这种超级计算机有着非常好的计算能力，但是对存储的支持相对较差，据内部人士透露，天河的存储能力就相当的差，做做计算还不错，但是数据大了就只有傻眼了） 2）成本相对低廉，云计算对终端用户而言，消费相对较低，对于公司而言，也能减少管理成本。按这个定义，某些很“高级”的服务器组成的集群就很难称为云计算了，之前听说广东公安局的身份证处理电脑的硬盘是单机320T的磁盘阵列，硬盘这种东西就是，买起来很便宜，但是硬盘架非常的贵，想在单机组成一个大的磁盘阵列，那可能就非常的高了。而且云计算的集群管理成本也不高。以一个极端的例子来说，一般一个大一点（100-200台电脑）的网吧都要配2-3个网管。但是我所在的公司几万台服务器，管理服务器的人就在20个人左右，相对管理成本很低。 3）稳定性，至少在程序运行的时候，错误处理能够做好，比如说N个节点计算，某个节点死机了，那程序是不是一定得重新运行？或者集群中某台电脑的硬盘坏掉了，那这些数据会不会就丢失了？按这个定义，普通的多点存储（简单的将数据备份到2块或者多块硬盘中去），以及那些某个节点出错了，计算任务就需要完全重跑的计算方式可能就不算云计算了（比如说MPI，这儿本章后面将会更详细一点提到） 由此看出，云计算是一个很庞大的系统，并非一般的开源项目（大的开源项目还是可以的，比如说Hadoop）可以完成的。就算能完成，也会有这样那样的问题，比如Hadoop集群就没有实现Service的常驻运行（只能跑job，也就是跑完就结束的那种） 分布式的数据挖掘 另一方面，数据挖掘也是一个很有意思、被很多人看重，也在很多领域上发挥大作用的一门学科，从个人而言，我对数据挖掘的兴趣非常的大。传统的计算机想要用数据挖掘，玩玩简单的算法可以，但是在工业界看来，总体来说是一个玩具。比如说weka，学习算法用它还行，但是想要对大规模的数据进行处理，是不太可能的。为了进行大规模的数据处理，分布式计算就很必要了。 分布式计算分类： 一般来说，现在比较常见的并行计算有下面的方式：OpenMP, CUDA，MPI，MapReduce。 OpenMP： 是对于多核的条件下，也就是一些超级计算机可以使用的方式，一个很重要的特性是共享存储，多个instance的关系是线程与线程的关系，也就限制了OpenMP主要是在单机（可能是超级计算机）中进行科学计算的任务。 CUDA: 这个概念是最近几年的事情，似乎ATI最近也搞了一个通用计算的内容，主要是用GPU并联起来进行计算，由于GPU的架构和CPU不太一样，采用这种方式可以对某些计算为主的任务加速几个数量级。对这一块我不太了解，也不太清楚现在CUDA计算、存储能力，还有稳定性等等做到什么样的程度了。这里就不加以评论 Map-Reduce： 发扬光大从Google的论文-MapReduce: Simplified data processing on large clusters开始的。Map-Reduce将程序的运行分成了Map和Reduce两个步骤，Map是一个读取、处理原始数据的过程，而Reduce是根据Map处理的内容，进行整合、再处理。Reduce可以认为又是一个Map，为下一级的Reduce过程作准备，这样数据的处理可以按这种方式进行迭代。 Map-Reduce的重点在下面的几处： 1）运行程序的方式，Map-Reduce一般是在以GFS（Google文件系统），或者HDFS等类似的系统上面进行的，这个系统一般有诸多的如磁盘负载平衡，数据冗余（replica），数据迁移（比如说集群中的某台硬盘坏了，这个硬盘里面的数据会用某种方式备份到其他的硬盘中去，而且保证每块硬盘的数据量都大致平衡）。不过这里先不谈数据的存储，主要谈谈任务的调度。 一般像这样的集群里面都有一百台以上的电脑，按每个电脑8个核计算，至少会有几百上千个CPU的资源。在运行每一个Map-Reduce的时候，用户会先填写需要多少的资源（CPU与内存），然后集群的负责人（可能被称为JobMaster），会去查看当前集群中的计算资源情况，看看能否成功的运行这个作业。如果不行的话，会排队。举一个Map-Reduce的例子： 对于一个很大的文件（由一堆的浮点数组成的），计算这个文件中Top1000的数是什么。那么程序的运行可能是下面的过程。 a. 先在N个CPU（可能在不同的电脑中的）上运行程序，每个CPU会负责数据的一部分，计算出Top1000的数值，将结果写入一个文件（共N份数据） b. 在M = N/16个CPU上运行程序，每个CPU会负责上面步骤的16个结果文件，计算出这些文件中Top1000的数值，然后将结果写入一个文件（共N / 16份数据） c. 在O = M/16个CPU上运行程序，同样每个CPU负责上面的16个结果文件。（共N / 256份数据） .. 按照这种方式迭代，直到求出真正的Top1000数值。 所以说，Map-Reduce的数据按每次迭代，是一个减少的过程，如果数据处理的时候有这样的特性，那就非常适合于用Map-Reduce去解决。 2）多个进程间的数据传递，对Map-Reduce而言，没有办法进行传统方式的进程间通信（比如说socket通信），进程间的通信纯粹是用文件去联系的，对于一个Map-Reduce任务，是多级组成的，每一级会起若干的进程，每个进程做的事情就是去读取上一级进程生成的数据，然后处理后写入磁盘让下一级进程进行读取。 这个特性使得Map-Reduce有着良好的容错性，当某一级的某一个进程出错了（比如说机器死机了，程序出异常了等等），JobMaster会重新调度这个进程到另外一个机器上，重新运行，如果是由于外部的问题（比如说机器死机了），一般这样的错误不会使得整个任务重复运行。不过真正如果是写程序出的逻辑问题，那程序也不能正常运行的，JobMaster会试着将失败的进程调度几次，如果都失败了，则任务就失败了。 但是用文件来同步机器间的通讯这个特性也有一个坏处，就是每当Map-Reduce的某一个步骤运行完后，需要重新调度下一级任务。如果是程序是一个重复迭代，直至收敛的过程，比如说KMeans算法、矩阵奇异值分解（SVD），则由于调度产生的开销会非常的大，网络传输不仅仅是发送需要的数据，还有一个读取文件、写入文件的磁盘IO过程，在迭代次数很多的时候（在大规模的SVD分解的时候，迭代的次数可能会达到上万次），这样的方式可能是无法忍受的。 目前Map-Reduce已经被很多的公司实现，Map-Reduce并不是一套标准，而是一种编程的方式，所以每个公司提供的API都有很大的区别，这会使得不能让程序比较通用。一般来说，如果想学Map-Reduce，可以在单机配置一个Hadoop。这算是一个非常标准的Map-Reduce过程。 MPI: 全称是Message Passing [...]]]></description>
			<content:encoded><![CDATA[<p><strong><span style="font-size: medium;">前言：</span></strong></p>
<p><strong> 云计算以及很多误解</strong></p>
<p>云计算这个概念被炒作得非常的火热，只要跟互联网沾边的公司，都喜欢用上云计算这个词。云计算其实不是一个那样广义的概念，云计算的定义并不是若干台机器用某种方式管理起来，然后用于存储或者计算这么简单，包括很多的云杀毒、云安全、云存储等等，都<strong><span style="text-decoration: underline;">不一定</span></strong>是真正的云计算。</p>
<p>上<a href="http://en.wikipedia.org/wiki/Cloud_computing" class="aga aga_56">wikipedia</a>可以看看相对来说比较完备的云计算定义，云计算一个很重要的特性是跟虚拟化相关的，像水、电一样为用户提供计算的资源。另外在key features这个章节上说明了很多云计算的特性，如果某一个系统只具备了里面的一个或者很少的几个特性，那称其为云计算就有点那么勉强了。</p>
<p>云计算一些很重要的特性包括</p>
<p>1）可扩展性，用户能够方便的增加、减少计算和存储的能力，而且有着足够的扩展性。按这个定义、一堆GPU或者CPU组成的网格可能就很难称为云计算了，这种超级计算机有着非常好的计算能力，但是对存储的支持相对较差，据内部人士透露，天河的存储能力就相当的差，做做计算还不错，但是数据大了就只有傻眼了）</p>
<p>2）成本相对低廉，云计算对终端用户而言，消费相对较低，对于公司而言，也能减少管理成本。按这个定义，某些很“高级”的服务器组成的集群就很难称为云计算了，之前听说广东公安局的身份证处理电脑的硬盘是单机320T的磁盘阵列，硬盘这种东西就是，买起来很便宜，但是硬盘架非常的贵，想在单机组成一个大的磁盘阵列，那可能就非常的高了。而且云计算的集群管理成本也不高。以一个极端的例子来说，一般一个大一点（100-200台电脑）的网吧都要配2-3个网管。但是我所在的公司几万台服务器，管理服务器的人就在20个人左右，相对管理成本很低。</p>
<p>3）稳定性，至少在程序运行的时候，错误处理能够做好，比如说N个节点计算，某个节点死机了，那程序是不是一定得重新运行？或者集群中某台电脑的硬盘坏掉了，那这些数据会不会就丢失了？按这个定义，普通的多点存储（简单的将数据备份到2块或者多块硬盘中去），以及那些某个节点出错了，计算任务就需要完全重跑的计算方式可能就不算云计算了（比如说MPI，这儿本章后面将会更详细一点提到）</p>
<p>由此看出，云计算是一个很庞大的系统，并非一般的开源项目（大的开源项目还是可以的，比如说Hadoop）可以完成的。就算能完成，也会有这样那样的问题，比如Hadoop集群就没有实现Service的常驻运行（只能跑job，也就是跑完就结束的那种）</p>
<p><strong>分布式的数据挖掘</strong></p>
<p>另一方面，数据挖掘也是一个很有意思、被很多人看重，也在很多领域上发挥大作用的一门学科，从个人而言，我对数据挖掘的兴趣非常的大。传统的计算机想要用数据挖掘，玩玩简单的算法可以，但是在工业界看来，总体来说是一个玩具。比如说weka，学习算法用它还行，但是想要对大规模的数据进行处理，是不太可能的。为了进行大规模的数据处理，分布式计算就很必要了。</p>
<p><span style="font-size: medium;"><strong>分布式计算分类：</strong></span></p>
<p>一般来说，现在比较常见的并行计算有下面的方式：OpenMP, CUDA，MPI，MapReduce。</p>
<p><strong>OpenMP：</strong></p>
<p>是对于多核的条件下，也就是一些超级计算机可以使用的方式，一个很重要的特性是共享存储，多个instance的关系是线程与线程的关系，也就限制了OpenMP主要是在单机（可能是超级计算机）中进行科学计算的任务。</p>
<p><strong>CUDA:</strong></p>
<p>这个概念是最近几年的事情，似乎ATI最近也搞了一个通用计算的内容，主要是用GPU并联起来进行计算，由于GPU的架构和CPU不太一样，采用这种方式可以对某些计算为主的任务加速几个数量级。对这一块我不太了解，也不太清楚现在CUDA计算、存储能力，还有稳定性等等做到什么样的程度了。这里就不加以评论</p>
<p><strong>Map-Reduce：</strong></p>
<p>发扬光大从Google的论文-MapReduce: Simplified data processing on large clusters开始的。Map-Reduce将程序的运行分成了Map和Reduce两个步骤，Map是一个读取、处理原始数据的过程，而Reduce是根据Map处理的内容，进行整合、再处理。Reduce可以认为又是一个Map，为下一级的Reduce过程作准备，这样数据的处理可以按这种方式进行迭代。</p>
<p><span style="text-decoration: underline;">Map-Reduce的重点在下面的几处：</span></p>
<p>1）运行程序的方式，Map-Reduce一般是在以GFS（Google文件系统），或者HDFS等类似的系统上面进行的，这个系统一般有诸多的如磁盘负载平衡，数据冗余（replica），数据迁移（比如说集群中的某台硬盘坏了，这个硬盘里面的数据会用某种方式备份到其他的硬盘中去，而且保证每块硬盘的数据量都大致平衡）。不过这里先不谈数据的存储，主要谈谈任务的调度。</p>
<p>一般像这样的集群里面都有一百台以上的电脑，按每个电脑8个核计算，至少会有几百上千个CPU的资源。在运行每一个Map-Reduce的时候，用户会先填写需要多少的资源（CPU与内存），然后集群的负责人（可能被称为JobMaster），会去查看当前集群中的计算资源情况，看看能否成功的运行这个作业。如果不行的话，会排队。举一个Map-Reduce的例子：</p>
<p>对于一个很大的文件（由一堆的浮点数组成的），计算这个文件中Top1000的数是什么。那么程序的运行可能是下面的过程。</p>
<p>a. 先在N个CPU（可能在不同的电脑中的）上运行程序，每个CPU会负责数据的一部分，计算出Top1000的数值，将结果写入一个文件（共N份数据）</p>
<p>b. 在M = N/16个CPU上运行程序，每个CPU会负责上面步骤的16个结果文件，计算出这些文件中Top1000的数值，然后将结果写入一个文件（共N / 16份数据）</p>
<p>c. 在O = M/16个CPU上运行程序，同样每个CPU负责上面的16个结果文件。（共N / 256份数据）</p>
<p>..</p>
<p>按照这种方式迭代，直到求出真正的Top1000数值。</p>
<p>所以说，Map-Reduce的数据按每次迭代，是一个减少的过程，如果数据处理的时候有这样的特性，那就非常适合于用Map-Reduce去解决。</p>
<p>2）多个进程间的数据传递，对Map-Reduce而言，没有办法进行传统方式的进程间通信（比如说socket通信），进程间的通信纯粹是用文件去联系的，对于一个Map-Reduce任务，是多级组成的，每一级会起若干的进程，每个进程做的事情就是去读取上一级进程生成的数据，然后处理后写入磁盘让下一级进程进行读取。</p>
<p>这个特性使得Map-Reduce有着良好的容错性，当某一级的某一个进程出错了（比如说机器死机了，程序出异常了等等），JobMaster会重新调度这个进程到另外一个机器上，重新运行，如果是由于外部的问题（比如说机器死机了），一般这样的错误不会使得整个任务重复运行。不过真正如果是写程序出的逻辑问题，那程序也不能正常运行的，JobMaster会试着将失败的进程调度几次，如果都失败了，则任务就失败了。</p>
<p>但是用文件来同步机器间的通讯这个特性也有一个坏处，就是每当Map-Reduce的某一个步骤运行完后，需要重新调度下一级任务。如果是程序是一个重复迭代，直至收敛的过程，比如说KMeans算法、矩阵奇异值分解（SVD），则由于调度产生的开销会非常的大，网络传输不仅仅是发送需要的数据，还有一个读取文件、写入文件的磁盘IO过程，在迭代次数很多的时候（在大规模的SVD分解的时候，迭代的次数可能会达到上万次），这样的方式可能是无法忍受的。</p>
<p>目前Map-Reduce已经被很多的公司实现，Map-Reduce并不是一套标准，而是一种编程的方式，所以每个公司提供的API都有很大的区别，这会使得不能让程序比较通用。一般来说，如果想学Map-Reduce，可以在单机配置一个Hadoop。这算是一个非常标准的Map-Reduce过程。</p>
<p><strong> MPI:</strong></p>
<p>全称是Message Passing Interface，也就是定义了一系列的消息传递接口，可以看看<a href="http://en.wikipedia.org/wiki/Message_Passing_Interface" class="aga aga_57">MPI的Wikipedia</a>，里面的内容从了解MPI来说比较好，这里说说重点，就不粘程序了。</p>
<p>MPI其实是一套标准，对C，C++，Fortran，Java，Python等都规定了一系列的接口，MPI的内部有一系列的函数，比如获取当前有多少进程MPI_Comm_size, 进程间同步MPI_Barrier等函数。对每种支持的语言，MPI都定了一个函数接口，也保证了不同的实现下，MPI的程序写出来都是一样的。MPI是一个在学术界和工业界都应用非常广泛的一套接口，目前MPI的实现非常多，开源的有OpenMPI和MPICH比较好，有些MPI实现来自一些大学的实验室，有些MPI的实现来自一流的公司（比如Microsoft就有自己的一套实现，还弄了一个C#版本的）。</p>
<p>MPI相对MapReduce来说，开发、调试也更接近单机，MPI的部署可以在单机上完成，调用的时候也可以制定多线程运行程序，如果有兴趣，可以下载一个OpenMPI或者MPICH，在自己的linux机器上进行部署，写写简单的代码是足够了。在单机保证逻辑正确的情况下，再上集群上面跑，就容易多了。</p>
<p>MPI的优点是，程序的调度是一次性的，就是比如开始申请了50个进程，那这50个进程就会一起跑，同生同死，在程序中指定的同步等操作，也会让这些进程进行同步，也可以在互相之间发送数据，通过MPI的封装，让发数据更操作变得非常的方便（MPI有100多个函数）。也就是从程序开始到结束，每个进程只会调度一次，如果有迭代的操作，就用下面的语句，加上必要的同步就行了：while (condition) { … }。对于需要迭代次数比较多的程序，MPI的运行时间普遍来说会比MapReduce强很多。</p>
<p>MPI相对MapReduce也有很多的缺点，开源的MPI或者一些商业的MPI都没有提供一个GFS系统，这个让大文件的存放，读取都成了一个问题，如果底层有一个GFS，再在上面搭一个MPI的系统，使用起来会非常的舒服。而且MPI的容错性一般不容易做，因为程序是同生同死的，某一个进程挂了，整个任务就挂了，除非在程序运行的时候，经常往磁盘中dump数据，不然容错性是完全没法保证的。</p>
<p>MPI据说还有一个缺点，不过现在也拿不到资料去证实，就是MPI的集群规模一般没法做大，如果做到几千台，进行数据传输、同步的开销就大了，而MapReduce的集群规模做到几万台电脑理论也是没有什么问题的。</p>
<p><span style="font-size: medium;"><strong>分布式计算的学习：</strong></span></p>
<p>分布式计算的学习主要可以参考一下下面的一些资料，首先是Google的几篇重量级的文章：MapReduce: Simplified data processing on large clusters，也是上文提到过的，还有一篇Google File System。然后就是wikipedia，用map-reduce，clound-computing等关键字搜索一下，可以看到很多有意思的内容。至于国内的教材，我也没有看太多，不太好评价，从我看到的一些来说，感觉讲得还是不太清楚的。</p>
<p>另外如上面提到的，分布式计算的两个最主要的分支：MapReduce和MPI，MapReduce复杂的地方来自底层的文件系统，想搞清楚这个文件系统很痛苦的，而MPI复杂的地方来自众多的函数，到目前为止，我熟练使用的函数就十来个，不过也可以实现很多基本的功能了。</p>
<p>另外学习MapReduce看Hadoop，学习MPI看OpenMPI和MPICH都可以，其他开源的SDK都很难和上面这几个相比。</p>
<p>从国内的公司而言，MPI和MapReduce的应用也很广，比如百度就是同时使用的Hadoop与MPI，学好了这两个东西，找个好工作还是比较容易的：）</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2010/12/an_introduce_to_parallel_computing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>贝叶斯、概率分布与机器学习</title>
		<link>http://thinkbot.info/2010/10/bayes-probability-distribution-machine-learning/</link>
		<comments>http://thinkbot.info/2010/10/bayes-probability-distribution-machine-learning/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 08:49:10 +0000</pubDate>
		<dc:creator>谭望达</dc:creator>
				<category><![CDATA[人工智能]]></category>
		<category><![CDATA[数据挖掘]]></category>
		<category><![CDATA[数理统计]]></category>
		<category><![CDATA[贝叶斯]]></category>

		<guid isPermaLink="false">http://thinkbot.info/2010/10/%e8%b4%9d%e5%8f%b6%e6%96%af%e3%80%81%e6%a6%82%e7%8e%87%e5%88%86%e5%b8%83%e4%b8%8e%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0/</guid>
		<description><![CDATA[本文由LeftNotEasy原创，可以转载，但请保留此行。如果有问题，请联系作者 wheeleast@gmail.com 一. 简单的说贝叶斯定理： 贝叶斯定理用数学的方法来解释生活中大家都知道的常识 形式最简单的定理往往是最好的定理，比如说中心极限定理，这样的定理往往会成为某一个领域的理论基础。机器学习的各种算法中使用的方法，最常见的就是贝叶斯定理。 贝叶斯定理的发现过程我没有找到相应的资料，不过我相信托马斯.贝叶斯(1702-1761)是通过生活中的一些小问题去发现这个对后世影响深远的定理的，而且我相信贝叶斯发现这个定理的时候，还不知道它居然有这么大的威力呢。下面我用一个小例子来推出贝叶斯定理： 已知：有N个苹果，和M个梨子，苹果为黄色的概率为20%，梨子为黄色的概率为80%，问，假如我在这堆水果中观察到了一个黄色的水果，问这个水果是梨子的概率是多少。 用数学的语言来表达，就是已知P(apple) = N / (N + M), P(pear) = M / (N + M), P(yellow&#124;apple) = 20%, P(yellow&#124;pear) = 80%, 求P(pear&#124;yellow). 要想得到这个答案，我们需要 1. 要求出全部水果中为黄色的水果数目。 2. 求出黄色的梨子数目 对于1) 我们可以得到 P(yellow) * (N + M), P(yellow) = p(apple) * P(yellow&#124;apple) + P(pear) * p(yellow&#124;pear) 对于2) 我们可以得到 P(yellow&#124;pear) * M [...]]]></description>
			<content:encoded><![CDATA[<p>本文由LeftNotEasy原创，可以转载，但请保留此行。如果有问题，请联系作者 <a href="mailto:wheeleast@gmail.com">wheeleast@gmail.com</a></p>
<h2><strong>一. 简单的说贝叶斯定理：</strong></h2>
<h3><strong>贝叶斯定理用数学的方法来解释生活中大家都知道的常识</strong></h3>
<p>形式最简单的定理往往是最好的定理，比如说中心极限定理，这样的定理往往会成为某一个领域的理论基础。机器学习的各种算法中使用的方法，最常见的就是贝叶斯定理。</p>
<p>贝叶斯定理的发现过程我没有找到相应的资料，不过我相信托马斯.贝叶斯(1702-1761)是通过生活中的一些小问题去发现这个对后世影响深远的定理的，而且我相信贝叶斯发现这个定理的时候，还不知道它居然有这么大的威力呢。下面我用一个小例子来推出贝叶斯定理：</p>
<p><strong>已知：有N个苹果，和M个梨子，苹果为黄色的概率为20%，梨子为黄色的概率为80%，问，假如我在这堆水果中观察到了一个黄色的水果，问这个水果是梨子的概率是多少。</strong></p>
<p>用数学的语言来表达，就是已知P(apple) = N / (N + M), P(pear) = M / (N + M), P(yellow|apple) = 20%, P(yellow|pear) = 80%, 求P(pear|yellow).</p>
<p>要想得到这个答案，我们需要 1. 要求出全部水果中为黄色的水果数目。 2. 求出黄色的梨子数目</p>
<p>对于1) 我们可以得到 P(yellow) * (N + M), P(yellow) = p(apple) * P(yellow|apple) + P(pear) * p(yellow|pear)</p>
<p>对于2) 我们可以得到 P(yellow|pear) * M</p>
<p>2) / 1) 可得：P(pear|yellow) = P(yellow|pear) * p(pear) / [P(apple) * P(yellow|apple) + P(pear) * P(yellow|pear)]</p>
<p>化简可得：P(pear|yellow) = P(yellow,pear) / P(yellow), 用简单的话来表示就是在已知是黄色的，能推出是梨子的概率P(pear|yellow)是黄色的梨子占全部水果的概率P(yellow,pear)除上水果颜色是黄色的概率P(yellow). 这个公式很简单吧。</p>
<p>我们将梨子代换为A，黄色代换为B公式可以写成：P(A|B) = P(A,B) / P(B), 可得：P(A,B) = P(A|B) * P(B).贝叶斯公式就这样推出来了。</p>
<p>本文的一个大概的思路：先讲一讲我概括出的一个基本的贝叶斯学习框架，然后再举几个简单的例子说明这些框架，最后再举出一个复杂一点的例子，也都是以贝叶斯机器学习框架中的模块来讲解</p>
<h2><strong>二. 贝叶斯机器学习框架</strong></h2>
<p>对于贝叶斯学习，我每本书都有每本书的观点和讲解的方式方法，有些讲得很生动，有些讲得很突兀，对于贝叶斯学习里面到底由几个模块组成的，我一直没有看到很官方的说法，我觉得要理解贝叶斯学习，下面几个模块是必须的：</p>
<h3><strong>1) 贝叶斯公式</strong></h3>
<p>机器学习问题中有一大类是分类问题，就是在给定观测数据D的情况下，求出其属于类别（也可以称为是假设h，h ∈ {h0, h1, h2…})的概率是多少, 也就是求出:</p>
<p>P(h|D), 可得：</p>
<p>P(h,D) = P(h|D) * P(D) = P(D|h) * P(h), 所以：P(h|D) = P(D|h) * P(h) / P(D), 对于一个数据集下面的所有数据，P(D)，恒定不变。所以可以认为P(D)为常数， 得到：P(h|D) ∝ P(D|h) * P(h)。我们往往不用知道P(h|D)的具体的值，而是知道例如P(h1|D)，P(h2|D)值的大小关系就是了。这个公式就是机器学习中的贝叶斯公 式，一般来说我们称P(h|D)为模型的后验概率，就是从数据来得到假设的概率，P(h)称为先验概率，就是假设空间里面的概率，P(D|h)是模型的 likelihood概率。</p>
<p>Likelihood（似然）这个概率比较容易让人迷惑，可以认为是已知假设的情况下，求出从假设推出数据的概率，在实际的机器学习过程中，往往加入了很多的假设，比如一个英文翻译法文的问题：</p>
<p>给出一个英文句子，问哪一个法文句子是最靠谱的，P(f=法文句子|e=英文句子) = P(e|f) * p(f), p(e|f)就是likelihood函数，P(e|f) 写成下面的更清晰一点：p(e|f∈{f1,f2…})可以认为，从输入的英文句子e，推出了很多种不同的法文句子f，p(e|f)就是从这些法文句子中的某一个推出原句子e的概率。</p>
<p><strong>本文之后的内容也将对文章中没有提到的一些内容，也是贝叶斯学习中容易疑惑、忽略、但是很重要的问题进行一些解释</strong>。</p>
<h3><strong>2) 先验分布估计，likelihood函数选择</strong></h3>
<p>贝叶斯方法中，等号右边有两个部分，先验概率与likelihood函数。先验概率是得到，在假设空间中，某一个假设出现的概率是多少，比如说在街上看到一个动物是长有毛的，问1. 这个动物是哈巴狗的概率是多少，2. 这个动物是爪哇虎的概率是多少, 见下图：</p>
<p><a class="highslide img_229" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/image_2.png" class="aga aga_81" onclick="return hs.expand(this)"><img title="clip_image002" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image002_519fa90f-bbfb-4a14-a5e7-dda69b39a927.gif" border="0" alt="clip_image002" width="244" height="222" /></a></p>
<p>虽然两个假设的likelihood函数都非常的接近于1（除非这个动物病了），但是由于爪哇虎已经灭绝了，所以爪哇虎的先验概率为0，所以P(爪哇虎|有毛的动物)的概率也为0。</p>
<h3><strong>先验概率分布估计</strong></h3>
<p>在观测的时候，对于变量是连续的情况下，往往需要一个先验分布来得到稀疏数据集中没有出现过的，给出的某一个假设，在假设空间中的概率。比如说有一个很大很大的均匀金属圆盘，问这个金属圆盘抛到空中掉下来，正面朝上的概率，这个实验的成本比较高（金属圆盘又大又重），所以只能进行有限次数的实验，可能出现的是，正面向上4次，反面向上1次，但是我们如果完全根据这个数据集去计算先验概率，可能会出现很大的偏差。不过由于我们已知圆盘是均匀的，我们可以根据这个知识，假设P(X=正面) = 0.5。</p>
<p>我们有的时候，已知了分布的类型，但是不知道分布的参数，还需要根据输入的数据，对分布的参数进行估计、甚至对分布还需要进行一些修正，以满足我们算法的需求：比如说我们已知某一个变量x的分布是在某一个连续区间均匀分布，我们观察了1000次该变量，从小到大排序结果是：1,1.12,1.5 … 199.6, 200, 那我们是否就可以估计变量的分布是从[1,200]均匀分布的？如果出现一个变量是0.995，那我们就能说P(0.995) = 0？如果出现一个200.15怎么办呢？所以我们这个时候可能需要对概率的分布进行一定的调整，可能在x&lt;1,x&gt;200的范围内的概率是一个下降的直线，整个概率密度函数可能是一个梯形的，或者对区域外的值可以给一个很小很小的概率。这个我在之后还将会举出一些例子来说明。</p>
<h3><strong>Likelihood函数选择</strong></h3>
<p>对于同一个模型，likelihood函数可能有不同的选择，对于这些选择，可能有些比较精确、但是会搜索非常大的空间，可能有些比较粗糙，但是速度会比较快，我们需要选择不同的likelihood函数来计算后验概率。对于这些Likelihood函数，可能还需要加上一些平滑等技巧来使得最大的降低数据中噪声、或者假设的缺陷对结果的影响。</p>
<p><strong>我所理解的用贝叶斯的方法来估计给定数据的假设的后验概率，就是通过prior * likelihood，变换到后验分布。是一个分布变换的过程。</strong></p>
<h3><strong>3) loss function(损失函数)</strong></h3>
<p><a class="highslide img_230" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/loss_func_4.gif" class="aga aga_82" onclick="return hs.expand(this)"><img title="clip_image003" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image003_18d12675-42b9-4303-8cf7-fd838f39ddc5.gif" border="0" alt="clip_image003" width="240" height="34" /></a><br />
x是输入的数据，y(x)是推测出的结果的模型，t是x对应的真实结果，L(t,y(x))就是loss function，E[L]表示使用模型y进行预测，使用L作为损失函数的情况下，模型的损失时多少。通常来说，衡量一个模型是否能够准确的得到结果，损失函数是最有效的一个办法，最常用、最简单的一种损失函数是：</p>
<p><a class="highslide img_231" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/loss_func_0_2.gif" class="aga aga_83" onclick="return hs.expand(this)"><img title="clip_image004" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image004_3ec06784-e439-47a7-aaa9-32a19c5af0cb.gif" border="0" alt="clip_image004" width="186" height="31" /></a></p>
<p>不过我一直不知道为什么这里用的平方，而不是直接用绝对值，有详细一点的解释吗？:-p</p>
<h3><strong>4) Model Selection(模型选择)</strong></h3>
<p>前文说到了对于likelihood函数可以有不同的选择，对于先验的概率也可以有不同的选择，不过假设我们一个构造完整的测试集和一个恰当的损失函数，最终的结果将会是确定的，量化的，我们很容易得到两个不同参数、方法的模型的优劣性。不过通常情况下，我们的测试集是不够完整，我们的损失函数也是不那么 的精确，所以对于在这个测试集上表现得非常完美的模型，我们常常可能还需要打一个问号，是否是训练集和测试集过于相像，模型又过于复杂。导致了over- fitting（后文将会详细介绍over-fitting的产生）？</p>
<p>Model Selection本质上来说是对模型的复杂度与模型的准确性做一个平衡，本文后面将有一些类似的例子。</p>
<h3><strong>Example 1：Sequential 概率估计</strong></h3>
<p>注：此例子来自PRML chapter 2.1.1</p>
<p>对于概率密度的估计，有很多的方法，其中一种方法叫做Sequential 概率估计。</p>
<p>这种方法是一个增量的学习过程，在每看到一个样本的时候都是把之前观测的数据作为先验概率，然后在得到新数据的后验概率后，再把当前的后验概率作为下一次预测时候的先验概率。</p>
<p>传统的二项式分布是：</p>
<p><a class="highslide img_232" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/binary_distribution_2.gif" class="aga aga_84" onclick="return hs.expand(this)"><img title="clip_image005" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image005_f0f0f57e-e1c4-4c5c-b42d-05e7486f8f43.gif" border="0" alt="clip_image005" width="240" height="53" /></a></p>
<p>由于传统的二项式分布的概率μ是完全根据先验概率而得到的，而这个先验分布之前也提到过，可能会由于实验次数不够而有很大的偏差，而且，<strong>我们无法得知μ的分布，只知道一个μ的期望</strong>，这样对于某些机器学习的方法是不利的。为了减少先验分布对μ的影响，获取μ的分布，我们加入了两个参数，a，b，表示X=0与X=1的出现的次数，这个取值将会改变μ的分布，beta分布的公式如下：</p>
<p><a class="highslide img_233" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/beta_distribution_2.gif" class="aga aga_85" onclick="return hs.expand(this)"><img title="clip_image006" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image006_c75ba9a3-5d19-4e6f-a7e5-8bac3278783e.gif" border="0" alt="clip_image006" width="240" height="44" /></a></p>
<p>对于不同a，b的取值，将会对μ的概率密度函数产生下面的影响：（图片来自PRML）</p>
<p><a class="highslide img_234" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/image_4.png" class="aga aga_86" onclick="return hs.expand(this)"><img title="clip_image008" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image008_7e1e1ab2-7c22-4e87-b0f6-35bb2137fbb8.gif" border="0" alt="clip_image008" width="544" height="379" /></a></p>
<p>在观测数据的过程中，我们可以随时的利用观测数据的结果，改变当前μ的先验分布。我们可以将Beta分布加入两个参数，m，l，表示观测到的X=0，X=1的次数。（之前的a，b是一个先验的次数，不是当前观测到的）</p>
<p>我们令：</p>
<p><a class="highslide img_235" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/a_b_m_l_2.gif" class="aga aga_87" onclick="return hs.expand(this)"><img title="clip_image009" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image009_230bab2e-1c54-4e0c-9fa6-61c9620afd98.gif" border="0" alt="clip_image009" width="80" height="50" /></a></p>
<p>a’，b’表示加入了观测结果的新的a，b 。带入原式，可以得到</p>
<p><a class="highslide img_236" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/beta_distribution_m_l_2.gif" class="aga aga_88" onclick="return hs.expand(this)"><img title="clip_image010" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image010_a4e609af-657c-462b-97b4-940b62e347cc.gif" border="0" alt="clip_image010" width="364" height="50" /></a></p>
<p>我们可以利用观测后的μ后验概率更新μ的先验概率，以进行下一次的观测，这样对不时能够得到新的数据，并且需要real-time给出结果的情况下很有用。不过Sequential方法有对数据一个i.i.d（独立同分布）的假设。要求每次处理的数据都是独立同分布的。</p>
<h3><strong>Example 2：拼写检查</strong></h3>
<p>这篇文章的中心思想来自：<a href="http://blog.youxu.info/spell-correct.html" class="aga aga_89">怎样写一个拼写检查器</a>，如果有必要，请参见原文，本例子主要谈谈先验分布对结果的影响。</p>
<p>直接给出拼写检查器的贝叶斯公式：</p>
<p><a class="highslide img_237" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/40542d95616e_FC7B/spell_checker_bayesian_2.gif" class="aga aga_90" onclick="return hs.expand(this)"><img title="clip_image011" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image011_5c13451a-81ef-475e-8792-f5ca4ab24e9f.gif" border="0" alt="clip_image011" width="177" height="25" /></a></p>
<p>P(c|w) 表示，单词w(wrong)正确的拼写为单词c(correct)的概率，P(w|c)表示likelihood函数，在这里我们就简单的认 为，两个单词的编辑距离就是它们之间的likelihood，P(c)表示，单词c在整体文档集合中的概率，也就是单词c的先验概率。</p>
<p>我们在做单词拼写检查的时候肯定会直观的考虑：如果用户输入的单词如果在字典中没有出现过，则应该将其修正为一个字典中出现了的，而且与用户输入最接近的词；如果用户输入的词在字典中出现过了，但是词频非常的小，则我们可以为用户推荐一个比较接近这个单词，但是词频比较高的词。</p>
<p>先验概率 P(c)的统计是一个很重要的内容，一般来说有两种可行的办法，一种是利用某些比较权威的词频字典，一种是在自己的语料库（也就是待进行拼写检查的语料）中进行统计。我建议是用后面的方法进行统计，这样词的先验概率才会与测试的环境比较匹配。比如说一个游戏垂直搜索网站需要对用户输入的信息进行拼写纠正，那么使用通用环境下统计出的先验概率就不太适用了。</p>
<h3><strong>Example 3：奥卡姆剃刀与Model Selection</strong></h3>
<p>给出下面的一个图：（来自Mackey的书）</p>
<p>问：大树背后有多少个箱子？</p>
<p><a class="highslide img_238" href="http://mindhacks.cn/wp-content/uploads/2009/02/i1.jpg" class="aga aga_91" onclick="return hs.expand(this)"><img title="clip_image013" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image013_8bdb6055-bff4-4647-b761-9e52b87ce6ca.jpg" border="0" alt="clip_image013" width="244" height="236" /></a></p>
<p>其实，答案肯定是有很多的，一个，两个，乃至N箱子都是有可能的（比如说后面有一连排的箱子，排成一条直线），我们只能看到第一个：</p>
<p><a class="highslide img_239" href="http://mindhacks.cn/wp-content/uploads/2009/02/i2.jpg" class="aga aga_92" onclick="return hs.expand(this)"><img title="clip_image015" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image015_36a48397-62ef-48cd-b787-cb043a39088d.jpg" border="0" alt="clip_image015" width="228" height="319" /></a></p>
<p>但是，最正确，也是最合理的解释，就是一个箱子，因为如果大树背后有两个乃至多个箱子，为什么从大树正面看起来，两边的高度一样，颜色也一样，这样是不是太巧合了。如果我们的模型根据这张图片，告诉我们大树背后最有可能有两个箱子，这样的模型的泛化能力是不是太差了。</p>
<p>所以说，本质上来说，奥卡姆剃刀，或者模型选择，也是人生活中的一种通常行为的数学表示，是一种化繁为简的过程。<strong><a href="http://blog.csdn.net/pongba/archive/2008/09/21/2958094.aspx" class="aga aga_93">数学之美番外篇：平凡而又神奇的贝叶斯方法</a></strong>这篇文章中说的，奥卡姆剃刀工作在likelihood上，对于模型的先验分布并没有什么影响。<strong>我这里不太同意这个说法</strong>：奥卡姆剃刀是剪掉了复杂的模型，复杂的模型也是不常见的、先验概率比较低的，最终的结果是选择了先验概率比较高的模型。</p>
<h3><strong>Example 4: 曲线拟合:</strong></h3>
<p>（该例子来自PRML)</p>
<p>问题：给定一些列的点，<strong>x</strong> = {x1,x2&#8230;xn}, <strong>t</strong> = {t1,t2 .. tn}, 要求用一个模型去拟合这个观测，能够使得给定一个新点x&#8217;, 能够给出一个t&#8217;.</p>
<p><a class="highslide img_240" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/f190c4ed40f4_BD30/image_2.png" class="aga aga_94" onclick="return hs.expand(this)"><img title="clip_image017" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image017_c9c9197f-6217-4504-8dd1-c61f6733c01d.gif" border="0" alt="clip_image017" width="404" height="297" /></a></p>
<p>已知给定的点是由y=2πx加上正态分布的噪声而得到的10个点，如上图。为了简单起见，我们用一个多项式去拟合这条曲线:</p>
<p><a class="highslide img_241" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/f190c4ed40f4_BD30/image_4.png" class="aga aga_95" onclick="return hs.expand(this)"><img title="clip_image019" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image019_f28d3ca2-323e-499f-a0ab-ea19e2663878.gif" border="0" alt="clip_image019" width="123" height="67" /></a></p>
<p>为了验证我们的公式是否正确，我们加入了一个loss function：</p>
<p><a class="highslide img_242" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/f190c4ed40f4_BD30/image_6.png" class="aga aga_96" onclick="return hs.expand(this)"><img title="clip_image021" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image021_2433b646-ab57-4272-a14f-e905493d2ffb.gif" border="0" alt="clip_image021" width="244" height="58" /></a></p>
<p>在loss function最小的情况下，我们绘制了不同维度下多项式生成的曲线：</p>
<p><a class="highslide img_243" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/f190c4ed40f4_BD30/image_8.png" class="aga aga_97" onclick="return hs.expand(this)"><img title="clip_image023" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image023_1f7d19bf-903d-4a21-958a-2a1fc7ef854f.gif" border="0" alt="clip_image023" width="498" height="368" /></a></p>
<p>在M值增高的情况下，曲线变得越来越陡峭，当M=9的时候，该曲线除了可以拟合输入样本点外，对新进来的样本点已经无法预测了。我们可以观测一下多项式的系数：</p>
<p><a class="highslide img_244" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/f190c4ed40f4_BD30/image_10.png" class="aga aga_98" onclick="return hs.expand(this)"><img title="clip_image025" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image025_c25b95e5-fc55-4111-b5f6-76ff4ea1d6f0.gif" border="0" alt="clip_image025" width="322" height="210" /></a></p>
<p>可以看出，当M（维度）增加的时候，系数也膨胀得很厉害，为了消除这个系数带来的影响，我们需要简化模型，我们为loss function加入一个惩罚因子：</p>
<p><a class="highslide img_245" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/f190c4ed40f4_BD30/image_12.png" class="aga aga_99" onclick="return hs.expand(this)"><img title="clip_image027" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image027_91c33737-adcb-474c-bc08-23f104b437b1.gif" border="0" alt="clip_image027" width="293" height="52" /></a></p>
<p>我们把w的L2距离乘上一个系数λ加入新的loss function中，这就是一个<strong>奥卡姆剃刀</strong>，把原本复杂的系数变为简单的系数（如果要更具体的量化的分析，请见PRML 1.1节）。如果我们要考虑如何选择最合适的维度，我们也可以把维度作为一个loss function的一部分，这就是Model Selection的一种。</p>
<p>但是这个问题还没有解决得很好，目前我们得到的模型只能预测出一个准确的值：输入一个新的x，给出一个t，但是不能描述t有什么样的概率密度函数。<strong>概率密度函数是很有用的</strong>。假如说我们的任务修正为，给出N个集合，每个集合里面有若干个点，表示一条曲线，给出一个新的点，问这个新的点最可能属于哪一条曲线。如果我们仅仅用新的点到这些曲线的距离作为一个衡量标准，那很难得到一个比较有说服力的结果。为了能够获取t值的一个分布，我们不妨假设t属于一个均值为y(x),方差为 1/β的一个高斯分布：</p>
<p><a class="highslide img_246" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image029_2.jpg" class="aga aga_100" onclick="return hs.expand(this)"><img title="clip_image029" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image029_thumb.jpg" border="0" alt="clip_image029" width="290" height="50" /></a></p>
<p>在之前的E(w)，我们加入了一个w的L2距离，这个看起来有一点突兀的感觉，为什么要加上一个这样的距离呢？为什么不是加入一个其他的东西。我们可以用一个贝叶斯的方法去替代它，得到一个更有说服力的结果。我们令p(w)为一个以0为均值，α为方差的高斯分布，这个分布为w在0点附近密度比较高，作为w的先验概率，这样在计算最大化后验概率的时候，w的绝对值越小，后验概率将会越大。</p>
<p><a class="highslide img_247" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image031_2.jpg" class="aga aga_101" onclick="return hs.expand(this)"><img title="clip_image031" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image031_thumb.jpg" border="0" alt="clip_image031" width="217" height="39" /></a></p>
<p>我们可以得到新的后验概率：</p>
<p><a class="highslide img_248" href="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image033_2.jpg" class="aga aga_102" onclick="return hs.expand(this)"><img title="clip_image033" src="http://images.cnblogs.com/cnblogs_com/LeftNotEasy/WindowsLiveWriter/511e0e6a2811_14078/clip_image033_thumb.jpg" border="0" alt="clip_image033" width="291" height="79" /></a></p>
<p>这个式子看起来是不是有点眼熟啊？我们令λ=α/β，可以得到类似于之前损失函数的一个结果了。我们不仅还是可以根据这个函数来计算最优的拟合函数，而且可以得到相应的一个概率分布函数。可以为机器学习的很多其他的任务打下基础。</p>
<p>这里还想再废话一句，其实很多机器学习里面的内容都与本处所说的曲线拟合算法类似，如果我们不用什么概率统计的知识，可以得到一个解决的方案，就像我们的第一个曲线拟合方案一样，而且还可以拟合得很好，不过唯一缺少的就是概率分布，有了概率分布可以做很多的事情。包括分类、回归等等都需要这些东西。从本质上来说，Beta分布和二项式分布，Dirichlet分布和多项式分布，曲线拟合中直接计算w和通过高斯分布估计w，都是类似的关系：Beta分布和 Dirichlet分布提供的是μ的先验分布。有了这个先验分布，我们可以去更好的做贝叶斯相关的事情。</p>
<h2><strong>参考资料：</strong></h2>
<p><strong><a href="http://blog.csdn.net/pongba/archive/2008/09/21/2958094.aspx" class="aga aga_103">数学之美番外篇：平凡而又神奇的贝叶斯方法</a>, Pongba</strong></p>
<p><strong>Pattern Recognition and Machine Learning, Bishop</strong></p>
<p><strong></strong><strong>一些Wikipedia上面的内容</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2010/10/bayes-probability-distribution-machine-learning/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>网页排名的计算，学习和优化</title>
		<link>http://thinkbot.info/2010/05/the-computing-learning-and-optimization-of-pagerank/</link>
		<comments>http://thinkbot.info/2010/05/the-computing-learning-and-optimization-of-pagerank/#comments</comments>
		<pubDate>Sat, 15 May 2010 12:52:28 +0000</pubDate>
		<dc:creator>Rocky</dc:creator>
				<category><![CDATA[人工智能]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[互联网]]></category>
		<category><![CDATA[搜索引擎]]></category>
		<category><![CDATA[数据挖掘]]></category>
		<category><![CDATA[机器学习]]></category>
		<category><![CDATA[神经网络]]></category>
		<category><![CDATA[网页排名]]></category>

		<guid isPermaLink="false">http://thinkbot.info/2010/05/%e7%bd%91%e9%a1%b5%e6%8e%92%e5%90%8d%e7%9a%84%e8%ae%a1%e7%ae%97%ef%bc%8c%e5%ad%a6%e4%b9%a0%e5%92%8c%e4%bc%98%e5%8c%96/</guid>
		<description><![CDATA[简介      网页排名（PageRank或PR）是搜索引擎用户体验的核心成分之一。之前Google的吴军博士曾经在他的《数学之美》系列文章中用一句很通俗的话总结了网页排名的核心思想：“在互联网上，如果一个网页被很多其它网页所链接，说明它受到普遍的承认和信赖，那么它的排名就高”。PR值代表了一个网页的重要程度。而它的重要程度又和与链接到它的网页的重要程度有关，所以网页排名的计算是一个迭代的过程。 PageRank值       虽然Google不是最早对网页进行排序，归类的公司，但是它的两个创始人Larry Page和Sergey Brin最早提出了现在被广泛用于各大搜索引擎的网页排名算法的原型（见参考文献2）。       下面我们在互联网这张大图上截取一小部分，如下图所示：      上图中共有四个节点（Page），其中周围的三个节点的PR值已知，且它们都有到中部节点的链接。现在我们需要计算中间那个网页的排名值。在计算之前，需要说明的是用户在互联网上浏览网页，点击链接的行为我们认为是随机事件。通常认为用户在一个网页选择点击链接继续浏览的概率是一定的，在Larry和Sergey（见参考文献1）的论文中这个概率取的是0.85，也就是说有0.15的概率用户选择留在当前页面不在继续浏览。而一旦用户选择跳转时，其选择跳转到特定页面的概率应当为：1/外部链接总数。  例如上图中左侧节点发生点击，链接到中心节点的概率应为0.25，因为它有4个外部链接。所以，可以用网民最终（直接或者间接）到达某个网页的概率作为该网页排名的基础，即PR值。很容易想到，上图中心节点的PR值应当为： 0.15+0.85(1/4+1/3+1/1) &#8212;-（1）       上面的答案看似不错，但是问题是往往我们需要对来自重要网页（PR值高的网页）的链接要看得重要一些，换句话说，通常认为好网站链接的也是好网站。看来我们需要考虑这些链接中哪些是来自好网站的了，我们需要重要程度高的网页其链接贡献的比重大一些。所以要引入已知节点本身的PR值（即其重要性），所以（1）式变成了： PR(?) = 0.15+0.85[0.4 * (1/4) + 0.3 * (1/3) + 0.5 * (1/1)] = 0.745        从这里也可以看到，贡献最大的还是上方的节点，一方面他PR值高，一方面它有且仅有一个到要求节点的链接。可以想象Google在首页链接了（且仅链接了）你的个人网站的效应;-)       你也许会问，这里周围链接网页的PR值已经知道了，但是实际上互联网上每天都有不计其数的新网页被搜索引擎的爬虫抓取到，不可能都预知其真实的PR值。没错，不过Larry和Sergey已经从理论上证明了，经过多次迭代，不论初始PR值如何选取，这种算法都保证了网页排名的估计值能收敛到他们的真实值。 学习优化       前面我们假设了用户浏览网页是随机行为，但实际上用户不可能在搜索结果里面随机点选链接，一个神志清醒的用户选择的一定是最满足他要求的结果，可以认为在某关键词下，搜索引擎提供的结果中，被用户选择的次数越多，那么那条结果就越重要，越要排在靠前的位置。所以接下来，我们需要设定一个反馈机制，来跟踪用户的点击行为，分析用户的意图，为以后的查询结果提供更准确的排名。在众多的学习机制中，具有非线性适应性信息处理能力的人工神经网络无疑是一个不错的选择。下面我们以多层感知器（一种多层前向神经网络）为例，看看在这个模型下如何优化网页排名。       下图是一个多层感知器结构示意图（这里只用到了三层），输入层是所有的查询词汇表，比如“苹果”，“公司”，“iPhone”等等，隐含层是某些词汇的集合，也就是用户键入的关键字组合，比如“苹果公司”，“苹果iPhone”。输出层是返回的URL列表。       这个网络是如何学习的呢？下面以搜索“苹果 公司”为例，当用户以关键词“苹果 公司”来搜索时，输入层的“苹果”和“公司”两个词被激活，试图作用于隐含层的“苹果公司”，当无数个用户一次又一次把“苹果”和“公司”两个词放一起进行查询的时候，隐含层的“苹果公司”这一项被激活。然后“苹果公司”这一项又会去激活输出层的URL列表，在输出层激活函数的作用下，这些URL会处于不同的激活程度。注意图中的粗线表示连接的强度很高。激活程度越高，就表示该URL和原始查询关键词的关联程度越高。而通过记录用户对最终结果的选择，上述网络会按照某些学习算法如著名的反向传播学习算法(backpropagation)，对激活程度和关联权值进行调节。从而使得该神经网络提供的结果越来越接近用户的真实需求。比如，大多数人在搜索“苹果 公司”之后，会选择位于美国加州的苹果股份有限公司的网站，而不是一家卖苹果的公司。于是从隐含层“苹果公司”到苹果公司URL（www.apple.com）的关联会加强。       当然，真实的训练算法和学习策略要远比这还要复杂得多，最终的网页排名可能是多个策略混合的结果。不过可以放心，这些算法的复杂性并不会影响到你使用搜索引擎的体验，毫无疑问，在你查询之前，这个网络已经被训练过无数次。查询引擎只需要从缓存的PageRank中读出来前若干条列表即可。搜索引擎会在记录了大量的用户选择的数据之后，定期或者不定期的对上述神经网络进行训练，对网页排名进行更新。       最后，关于网页排名的未来，我觉得它是和整个搜索引擎的革命分不开的。一方面是永恒的性能，要知道像BP这种训练神经网络的算法，都是非常耗时的消耗型算法。未来可能需要更先进的并行硬件，更庞大的集群和集群间高效稳定的通信机制。去年贺牛在（WWW09）上发表了一篇用GPU做信息检索的文章，很有趣。GPU现在用于各种科学计算和数据挖掘蔚然成风。另一方面，许多现在由计算机集群做的事情，未来可能交给芯片集群和计算网络去做，比如网页解析交给一堆FPGA去做，衍生出更多的搜索引擎硬件从而取代或者部分取代功耗高效率低的服务器集群。毕竟节能也是搜索引擎未来的一大主题。 参考文献 S Brin, L Page, [...]]]></description>
			<content:encoded><![CDATA[<h1>简介</h1>
<p>     网页排名（PageRank或PR）是搜索引擎用户体验的核心成分之一。之前Google的吴军博士曾经在他的《<a href="http://www.google.cn/ggblog/googlechinablog/2006/02/page-rank-google_1386.html" class="aga aga_111">数学之美</a>》系列文章中用一句很通俗的话总结了网页排名的核心思想：“<strong>在互联网上，如果一个网页被很多其它网页所链接，说明它受到普遍的承认和信赖，那么它的排名就高</strong>”。PR值代表了一个网页的重要程度。而它的重要程度又和与链接到它的网页的重要程度有关，所以网页排名的计算是一个迭代的过程。</p>
<h1>PageRank值</h1>
<p>      虽然Google不是最早对网页进行排序，归类的公司，但是它的两个创始人Larry Page和Sergey Brin最早提出了现在被广泛用于各大搜索引擎的网页排名算法的原型（见参考文献2）。</p>
<p>      下面我们在互联网这张大图上截取一小部分，如下图所示：</p>
<p><a class="highslide img_251" href="http://thinkbot.info/wp-content/uploads/2010/05/PRmap.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="PRmap" src="http://thinkbot.info/wp-content/uploads/2010/05/PRmap_thumb.png" border="0" alt="PRmap" width="324" height="207" /></a></p>
<p>     上图中共有四个节点（Page），其中周围的三个节点的PR值已知，且它们都有到中部节点的链接。现在我们需要计算中间那个网页的排名值。在计算之前，需要说明的是<strong>用户在互联网上浏览网页，点击链接的行为我们认为是随机事件</strong>。通常认为用户在一个网页选择点击链接继续浏览的概率是一定的，在Larry和Sergey（见参考文献1）的论文中这个概率取的是0.85，也就是说有0.15的概率用户选择留在当前页面不在继续浏览。而一旦用户选择跳转时，其选择跳转到特定页面的概率应当为：1/外部链接总数。  例如上图中左侧节点发生点击，链接到中心节点的概率应为0.25，因为它有4个外部链接。所以，可以用网民最终（直接或者间接）到达某个网页的概率作为该网页排名的基础，即PR值。很容易想到，上图中心节点的PR值应当为：</p>
<p><span style="font-size: small;">0.15+0.85(1/4+1/3+1/1) &#8212;-（1）</span></p>
<p>      上面的答案看似不错，但是问题是往往我们需要对来自重要网页（PR值高的网页）的链接要看得重要一些，换句话说，通常认为好网站链接的也是好网站。看来我们需要考虑这些链接中哪些是来自好网站的了，我们需要重要程度高的网页其链接贡献的比重大一些。所以要引入已知节点本身的PR值（即其重要性），所以（1）式变成了：</p>
<p><span style="font-size: small;">PR(?) = 0.15+0.85[0.4 * (1/4) + 0.3 * (1/3) + 0.5 * (1/1)] = 0.745</span></p>
<p>       从这里也可以看到，贡献最大的还是上方的节点，一方面他PR值高，一方面它有且仅有一个到要求节点的链接。可以想象Google在首页链接了（且仅链接了）你的个人网站的效应;-)</p>
<p>      你也许会问，这里周围链接网页的PR值已经知道了，但是实际上互联网上每天都有不计其数的新网页被搜索引擎的爬虫抓取到，不可能都预知其真实的PR值。没错，不过Larry和Sergey已经从理论上证明了，经过多次迭代，不论初始PR值如何选取，这种算法都保证了网页排名的估计值能收敛到他们的真实值。</p>
<h1>学习优化</h1>
<p>      前面我们假设了用户浏览网页是随机行为，但实际上用户不可能在搜索结果里面随机点选链接，一个神志清醒的用户选择的一定是最满足他要求的结果，可以认为在某关键词下，搜索引擎提供的结果中，被用户选择的次数越多，那么那条结果就越重要，越要排在靠前的位置。所以接下来，我们需要设定一个反馈机制，来跟踪用户的点击行为，分析用户的意图，为以后的查询结果提供更准确的排名。在众多的学习机制中，具有非线性适应性信息处理能力的人工神经网络无疑是一个不错的选择。下面我们以<a href="http://en.wikipedia.org/wiki/Multilayer_perceptron" class="aga aga_112">多层感知器</a>（一种多层前向神经网络）为例，看看在这个模型下如何优化网页排名。</p>
<p>      下图是一个多层感知器结构示意图（这里只用到了三层），输入层是所有的查询词汇表，比如“苹果”，“公司”，“iPhone”等等，隐含层是某些词汇的集合，也就是用户键入的关键字组合，比如“苹果公司”，“苹果iPhone”。输出层是返回的URL列表。</p>
<p><a class="highslide img_252" href="http://thinkbot.info/wp-content/uploads/2010/05/MLP_search.png"  onclick="return hs.expand(this)"><img style="display: block; float: none; margin-left: auto; margin-right: auto; border: 0px;" title="MLP_search" src="http://thinkbot.info/wp-content/uploads/2010/05/MLP_search_thumb.png" border="0" alt="MLP_search" width="484" height="308" /></a></p>
<p>      这个网络是如何学习的呢？下面以搜索“苹果 公司”为例，当用户以关键词“苹果 公司”来搜索时，输入层的“苹果”和“公司”两个词被激活，试图作用于隐含层的“苹果公司”，当无数个用户一次又一次把“苹果”和“公司”两个词放一起进行查询的时候，隐含层的“苹果公司”这一项被激活。然后“苹果公司”这一项又会去激活输出层的URL列表，在输出层激活函数的作用下，这些URL会处于不同的激活程度。注意图中的粗线表示连接的强度很高。激活程度越高，就表示该URL和原始查询关键词的关联程度越高。而通过记录用户对最终结果的选择，上述网络会按照某些学习算法如著名的反向传播学习算法(<a href="http://en.wikipedia.org/wiki/Backpropagation" class="aga aga_113">backpropagation</a>)，对激活程度和关联权值进行调节。从而使得该神经网络提供的结果越来越接近用户的真实需求。比如，大多数人在搜索“苹果 公司”之后，会选择位于美国加州的苹果股份有限公司的网站，而不是一家卖苹果的公司。于是从隐含层“苹果公司”到苹果公司URL（<a href="http://www.apple.com" class="aga aga_114">www.apple.com</a>）的关联会加强。</p>
<p>      当然，真实的训练算法和学习策略要远比这还要复杂得多，最终的网页排名可能是多个策略混合的结果。不过可以放心，这些算法的复杂性并不会影响到你使用搜索引擎的体验，毫无疑问，在你查询之前，这个网络已经被训练过无数次。查询引擎只需要从缓存的PageRank中读出来前若干条列表即可。搜索引擎会在记录了大量的用户选择的数据之后，定期或者不定期的对上述神经网络进行训练，对网页排名进行更新。</p>
<p>      最后，关于网页排名的未来，我觉得它是和整个<a href="http://thinkbot.info/2010/02/revolution-of-search/" >搜索引擎的革命</a>分不开的。一方面是永恒的性能，要知道像BP这种训练神经网络的算法，都是非常耗时的消耗型算法。未来可能需要更先进的并行硬件，更庞大的集群和集群间高效稳定的通信机制。去年<a href="http://jinruhe.com/blog" class="aga aga_115">贺牛</a>在（WWW09）上发表了一篇用GPU做信息检索的文章，很有趣。GPU现在用于各种科学计算和数据挖掘蔚然成风。另一方面，许多现在由计算机集群做的事情，未来可能交给芯片集群和计算网络去做，比如网页解析交给一堆FPGA去做，衍生出更多的搜索引擎硬件从而取代或者部分取代功耗高效率低的服务器集群。毕竟节能也是搜索引擎未来的一大主题。</p>
<h1>参考文献</h1>
<ol>
<li>S Brin, L Page, <em>The anatomy of a large-scale hypertextual Web search engine</em>, Computer networks and ISDN systems, 1998</li>
<li>Page, Lawrence and Brin, Sergey and Motwani, Rajeev and Winograd, Terry, <em>The PageRank Citation Ranking: Bringing Order to the Web.</em> Technical Report. Stanford InfoLab, 1999</li>
<li>吴军, 谈 Page Rank – Google 的民主表决式网页排名技术, 2006</li>
<li><a title="http://en.wikipedia.org/wiki/Multilayer_perceptron" href="http://en.wikipedia.org/wiki/Multilayer_perceptron" class="aga aga_116">http://en.wikipedia.org/wiki/Multilayer_perceptron</a></li>
<li><a title="http://en.wikipedia.org/wiki/Backpropagation" href="http://en.wikipedia.org/wiki/Backpropagation" class="aga aga_117">http://en.wikipedia.org/wiki/Backpropagation</a></li>
</ol>
<p><span style="text-decoration: underline;">Author: rocky AT thinkbot.info</span></p>
]]></content:encoded>
			<wfw:commentRss>http://thinkbot.info/2010/05/the-computing-learning-and-optimization-of-pagerank/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

