让我们写代码吧!
前面例子中评估房价的程序,你打算怎么写呢?往下看之前,先思考一下吧。
如果你对机器学习一无所知,很有可能你会尝试写出一些基本规则来评估房价,如下:
def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price = 0
# In my area, the average house costs house costs $200 per sqft
price_per_sqft = 200
if neighborhood == "hipsterton":
# but some areas cost a bit more
price_per_sqft = 400
elif neighborhood == "skid row":
# and some areas cost less
price_per_sqft = 100
# start with a base price estimate based on how big the place is
price = price_per_sqft * sqft
# now adjust our estimate based on the number of bedrooms
if num_of_bedrooms == 0:
# Studio apartments are cheap
price = price - 20000
else:
# places with more bedrooms are usually
# more valuable
price = price + (num_of_bedrooms * 1000)
return price
假如你像这样瞎忙几个小时,也许会取得一点成效,但是你的程序永不会完美,而且当价格变化时很难维护。
如果能让计算机找出实现上述函数功能的办法,这样岂不更好?只要返回的房价数字正确,谁会在乎函数具体干了些什么呢?
def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price =
return price
这样可以将你最初的程序(全是疯狂的if else语句)简化成类似如下的样子:
def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price = 0
# a little pinch of this
price += num_of_bedrooms * .841231951398213
# and a big pinch of that
price += sqft * 1231.1231231
# maybe a handful of this
price += neighborhood * 2.3242341421
# and finally, just a little extra salt for good measure
price += 201.23432095
return price
请注意那些用粗体标注的神奇数字——.841231951398213, 1231.1231231,2.3242341421,和201.23432095。它们称为权重。如果我们能找出对每栋房子都适用的完美权重,我们的函数就能预测所有的房价!
找出最佳权重的一种笨办法如下所示:
找出最佳权重的一种笨办法如下所示:
步骤1:
首先将每个权重设为1.0:
def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price = 0
# a little pinch of this
price += num_of_bedrooms * 1.0
# and a big pinch of that
price += sqft * 1.0
# maybe a handful of this
price += neighborhood * 1.0
# and finally, just a little extra salt for good measure
price += 1.0
return price
步骤2:
将每栋房产带入你的函数运算,检验估算值与正确价格的偏离程度:
运用你的程序预测房屋价格.
例如:上表中第一套房产实际成交价为25万美元,你的函数估价为17.8万,这一套房产你就差了7.2万。
再将你的数据集中的每套房产估价偏离值平方后求和。假设数据集中有500套房产交易,估价偏离值平方求和总计为86,123,373美元。这就反映了你的函数现在的“正确”程度。
现在,将总计值除以500,得到每套房产的估价偏离平均值。将这个平均误差值称为你函数的代价。
如果你能调整权重使得这个代价变为0,你的函数就完美了。它意味着,根据输入的数据,你的程序对每一笔房产交易的估价都是分毫不差。而这就是我们的目标——尝试不同的权重值以使代价尽可能的低。
再将你的数据集中的每套房产估价偏离值平方后求和。假设数据集中有500套房产交易,估价偏离值平方求和总计为86,123,373美元。这就反映了你的函数现在的“正确”程度。
现在,将总计值除以500,得到每套房产的估价偏离平均值。将这个平均误差值称为你函数的代价。
如果你能调整权重使得这个代价变为0,你的函数就完美了。它意味着,根据输入的数据,你的程序对每一笔房产交易的估价都是分毫不差。而这就是我们的目标——尝试不同的权重值以使代价尽可能的低。
步骤3:
不断重复步骤2,尝试所有可能的权重值组合。哪一个组合使得代价最接近于0,它就是你要使用的,你只要找到了这样的组合,问题就得到了解决!
思想扰动时间:
这太简单了,对吧?想一想刚才你做了些什么。你取得了一些数据,将它们输入至三个通用的简单步骤中,最后你得到了一个可以对你所在区域的房屋进行估价的函数。房价网,要当心咯!
但是下面的事实可能会扰乱你的思想:
1.过去40年来,很多领域(如语言学/翻译学)的研究表明,这种通用的“搅动数据汤”(我编造的词)式的学习算法已经胜过了需要利用真人明确规则的方法。机器学习的“笨”办法最终打败了人类专家。
2.你最后写出的函数真是笨,它甚至不知道什么是“面积”和“卧室数”。它知道的只是搅动,改变数字来得到正确的答案。
3.很可能你都不知道为何一组特殊的权重值能起效。所以你只是写出了一个你实际上并不理解却能证明的函数。
4.试想一下,你的程序里没有类似“面积”和“卧室数”这样的参数,而是接受了一组数字。假设每个数字代表了你车顶安装的摄像头捕捉的画面中的一个像素,再将预测的输出不称为“价格”而是叫做“方向盘转动度数”,这样你就得到了一个程序可以自动操纵你的汽车了!
太疯狂了,对吧?
但是下面的事实可能会扰乱你的思想:
1.过去40年来,很多领域(如语言学/翻译学)的研究表明,这种通用的“搅动数据汤”(我编造的词)式的学习算法已经胜过了需要利用真人明确规则的方法。机器学习的“笨”办法最终打败了人类专家。
2.你最后写出的函数真是笨,它甚至不知道什么是“面积”和“卧室数”。它知道的只是搅动,改变数字来得到正确的答案。
3.很可能你都不知道为何一组特殊的权重值能起效。所以你只是写出了一个你实际上并不理解却能证明的函数。
4.试想一下,你的程序里没有类似“面积”和“卧室数”这样的参数,而是接受了一组数字。假设每个数字代表了你车顶安装的摄像头捕捉的画面中的一个像素,再将预测的输出不称为“价格”而是叫做“方向盘转动度数”,这样你就得到了一个程序可以自动操纵你的汽车了!
太疯狂了,对吧?
步骤3中的“尝试每个数字”是怎么回事?
好吧,当然你不可能尝试所有可能的权重值来找到效果最好的组合。那可真要花很长时间,因为要尝试的数字可能无穷无尽。
为避免这种情况,数学家们找到了很多聪明的办法来快速找到优秀的权重值,而不需要尝试过多。下面是其中一种:
首先,写出一个简单的等式表示前述步骤2:
为避免这种情况,数学家们找到了很多聪明的办法来快速找到优秀的权重值,而不需要尝试过多。下面是其中一种:
首先,写出一个简单的等式表示前述步骤2:
这是你的代价函数.
接着,让我们将这同一个等式用机器学习的数学术语(现在你可以忽略它们)进行重写:
θ表示当前的权重值。 J(θ) 意为“当前权重值对应的代价”。
这个等式表示我们的估价程序在当前权重值下偏离程度的大小。
如果将所有赋给卧室数和面积的可能权重值以图形形式显示,我们会得到类似下图的图表:
代价函数的图形像一只碗。纵轴表示代价。
图中蓝色的最低点就是代价最低的地方——即我们的程序偏离最小。最高点意味着偏离最大。所以,如果我们能找到一组权重值带领我们到达图中的最低点,我们就找到了答案!
因此,我们只需要调整权重值使我们在图上能向着最低点“走下坡路”。如果对于权重的细小调节能一直使我们保持向最低点移动,那么最终我们不用尝试太多权重值就能到达那里。
如果你还记得一点微积分的话,你也许记得如果你对一个函数求导,结果会告诉你函数在任一点的斜率。换句话说,对于图上给定一点,它告诉我们那条路是下坡路。我们可以利用这一点朝底部进发。
所以,如果我们对代价函数关于每一个权重求偏导,那么我们就可以从每一个权重中减去该值。这样可以让我们更加接近山底。一直这样做,最终我们将到达底部,得到权重的最优值。(读不懂?不用担心,接着往下读)。
这种找出最佳权重的办法被称为批量梯度下降,上面是对它的高度概括。如果想搞懂细节,不要害怕,继续深入下去吧。
当你使用机器学习算法库来解决实际问题,所有这些都已经为你准备好了。但明白一些具体细节总是有用的。
如果你还记得一点微积分的话,你也许记得如果你对一个函数求导,结果会告诉你函数在任一点的斜率。换句话说,对于图上给定一点,它告诉我们那条路是下坡路。我们可以利用这一点朝底部进发。
所以,如果我们对代价函数关于每一个权重求偏导,那么我们就可以从每一个权重中减去该值。这样可以让我们更加接近山底。一直这样做,最终我们将到达底部,得到权重的最优值。(读不懂?不用担心,接着往下读)。
这种找出最佳权重的办法被称为批量梯度下降,上面是对它的高度概括。如果想搞懂细节,不要害怕,继续深入下去吧。
当你使用机器学习算法库来解决实际问题,所有这些都已经为你准备好了。但明白一些具体细节总是有用的。
还有什么你随便就略过了?
上面我描述的三步算法被称为多元线性回归。你估算等式是在求一条能够拟合所有房价数据点的直线。然后,你再根据房价在你的直线上可能出现的位置用这个等式来估算从未见过的房屋的价格。这个想法威力强大,可以用它来解决“实际”问题。
但是,我为你展示的这种方法可能在简单的情况下有效,它不会在所有情况下都有用。原因之一是因为房价不会一直那么简单地跟随一条连续直线。
但是,幸运的是,有很多办法来处理这种情况。对于非线性数据,很多其他类型的机器学习算法可以处理(如神经网络或有核向量机)。还有很多方法运用线性回归更灵活,想到了用更复杂的线条来拟合。在所有的情况中,寻找最优权重值这一基本思路依然适用。
还有,我忽略了过拟合的概念。很容易碰上这样一组权重值,它们对于你原始数据集中的房价都能完美预测,但对于原始数据集之外的任何新房屋都预测不准。这种情况的解决之道也有不少(如正则化以及使用交叉验证数据集)。学会如何处理这一问题对于顺利应用机器学习至关重要。
换言之,基本概念非常简单,要想运用机器学习得到有用的结果还需要一些技巧和经验。但是,这是每个开发者都能学会的技巧。
但是,我为你展示的这种方法可能在简单的情况下有效,它不会在所有情况下都有用。原因之一是因为房价不会一直那么简单地跟随一条连续直线。
但是,幸运的是,有很多办法来处理这种情况。对于非线性数据,很多其他类型的机器学习算法可以处理(如神经网络或有核向量机)。还有很多方法运用线性回归更灵活,想到了用更复杂的线条来拟合。在所有的情况中,寻找最优权重值这一基本思路依然适用。
还有,我忽略了过拟合的概念。很容易碰上这样一组权重值,它们对于你原始数据集中的房价都能完美预测,但对于原始数据集之外的任何新房屋都预测不准。这种情况的解决之道也有不少(如正则化以及使用交叉验证数据集)。学会如何处理这一问题对于顺利应用机器学习至关重要。
换言之,基本概念非常简单,要想运用机器学习得到有用的结果还需要一些技巧和经验。但是,这是每个开发者都能学会的技巧。
机器学习法力无边吗?
一旦你开始明白机器学习技术很容易应用于解决貌似很困难的问题(如手写识别),你心中会有一种感觉,只要有足够的数据,你就能够用机器学习解决任何问题。只需要将数据输入进去,就能看到计算机变戏法一样找出拟合数据的等式。
但是很重要的一点你要记住,机器学习只能对用你占有的数据实际可解的问题才适用。
例如,如果你建立了一个模型来根据每套房屋内盆栽数量来预测房价,它就永远不会成功。房屋内盆栽数量和房价之间没有任何的关系。所以,无论它怎么去尝试,计算机也推导不出两者之间的关系。
但是很重要的一点你要记住,机器学习只能对用你占有的数据实际可解的问题才适用。
例如,如果你建立了一个模型来根据每套房屋内盆栽数量来预测房价,它就永远不会成功。房屋内盆栽数量和房价之间没有任何的关系。所以,无论它怎么去尝试,计算机也推导不出两者之间的关系。
怎样深入学习机器学习
我认为,当前机器学习的最大问题是它主要活跃于学术界和商业研究组织中。对于圈外想要有个大体了解而不是想成为专家的人们,简单易懂的学习资料不多。但是这一情况每一天都在改善。
吴恩达教授(Andrew Ng)在Coursera上的机器学习免费课程非常不错。我强烈建议由此入门。任何拥有计算机科学学位、还能记住一点点数学的人应该都能理解。
另外,你还可以下载安装SciKit-Learn,用它来试验成千上万的机器学习算法。它是一个python框架,对于所有的标准算法都有“黑盒”版本。
吴恩达教授(Andrew Ng)在Coursera上的机器学习免费课程非常不错。我强烈建议由此入门。任何拥有计算机科学学位、还能记住一点点数学的人应该都能理解。
另外,你还可以下载安装SciKit-Learn,用它来试验成千上万的机器学习算法。它是一个python框架,对于所有的标准算法都有“黑盒”版本。
(译完,谢谢!)