1.机器学习:是什么?
机器学习是这样一种概念,即存在某些能够从数据集中获取有趣信息的通用算法,它的实现无需为单个特定问题量身定制无法迁移到其它情景的代码。与从头到尾敲代码不同,你要做的是把数据输入通用算法,然后它会基于这些数据建立其自身的逻辑。
拿分类算法举例,它能将数据归入不同组别。一种能够识别手书的数字的分类算法,亦可在不改任何一行代码的情况下用于垃圾邮件筛选。同一个算法,输入不同的训练数据,继而产生了不同的分类逻辑。
2.机器学习:怎么做?
我们大致可将机器学习算法划入两类:监督式学习与非监督式学习。它们之间的差别很简单,但极其重要。
监督式学习
假设你是一个事业蒸蒸日上的地产中介,雇佣了一批刚入行的员工。此时你会面对这样一个问题:你可以单凭第一眼印象就对房屋的估值做到心中有谱,可是你的雇员缺乏这样的经验,对如何进行房屋估值心里没底。
为了协助雇员们的业务工作(也许同时为了给你自己放个假),你决定编写一个app。这个小程序可以根据业务所在区房屋的大小、社区情况和同类房屋的售价等因素进行估值。
于是,你逐条录入三个月内的市内房屋售卖记录。对于每一笔交易,你记下卧室数量、房屋面积、社区环境的细节,当然也包括最重要的成交价:
这是我们的「训练数据」。
我们希望程序能使用这些训练数据来预估你的业务所在区中另一房屋的价格:
我们要使用训练数据来预测其它房屋的售价。
这就是监督式学习。在训练数据中,你已经知道每套房屋的售价,换句话说,你已经知道问题的答案,可以从答案反推出解决问题的逻辑。
为了完成你的app,你向机器学习算法输入关于每套房屋的训练数据,算法则试图找出哪种数学机制可以满足这些数字间的推导计算。
这就好比,虽然知道数学考试中算式的答案,但所有的计算符号都消失不见了:
哦!一个调皮的学生把标准答案中算式的计算符号都抹去了!
在这种情况下,你能够复原算式的本来面目吗?你知道自己必须做点什么,将每一个算式中等号左边的数字进行某种运算,得到等号右边的答案。
在监督式学习中,你放手让计算机自己去找到数据的内部关系。一旦你理解特定问题集背后所运行的数学机制,就能回答任何其它同类型的问题!
监督式学习假设你是一个事业蒸蒸日上的地产中介,雇佣了一批刚入行的员工。此时你会面对这样一个问题:你可以单凭第一眼印象就对房屋的估值做到心中有谱,可是你的雇员缺乏这样的经验,对如何进行房屋估值心里没底。
为了协助雇员们的业务工作(也许同时为了给你自己放个假),你决定编写一个app。这个小程序可以根据业务所在区房屋的大小、社区情况和同类房屋的售价等因素进行估值。
于是,你逐条录入三个月内的市内房屋售卖记录。对于每一笔交易,你记下卧室数量、房屋面积、社区环境的细节,当然也包括最重要的成交价:
这是我们的「训练数据」。
我们希望程序能使用这些训练数据来预估你的业务所在区中另一房屋
的价格:
我们要使用训练数据来预测其它房屋的售价。
这就是监督式学习。在训练数据中,你已经知道每套房屋的售价,换句话说,你已经知道问题的答案,可以从答案反推出解决问题的逻辑。为了完成你的app,你向机器学习算法输入关于每套房屋的训练数据,算法则试图找出哪种数学机制可以满足这些数字间的推导计算。
这就好比,虽然知道数学考试中算式的答案,但所有的计算符号都消失不见了:
哦!一个调皮的学生把标准答案中算式的计算符号都抹去了!
在这种情况下,你能够复原算式的本来面目吗?你知道自己必须做点什么,将每一个算式中等号左边的数字进行某种运算,得到等号右边的答案。
在监督式学习中,你放手让计算机自己去找到数据的内部关系。一旦你理解特定问题集背后所运行的数学机制,就能回答任何其它同类型的问题!
非监督式学习
回到原先地产中介的例子,在你无从得知每套房屋的售价时又当如何呢?实际上,即便你只知道每套房屋的大小和所在地等信息,仍然可以做一些很酷的事。这就是非监督式学习。
即使你没有打算预测未知变量的数值(如价格),仍可用机器学习来做一些有趣的事。
这有点像有人交给你一张纸,上面记着一组数字,然后告诉你:「我实在是不明白这些数字意味着什么。也许你能帮我找找这里面是否存在某种模式或组合等信息。祝你好运!」
那么你能拿这数据做些什么呢?首先,你可以找到一个在数据中自动确定不同细分市场的算法。也许你会发现,在本地高校附近社区购房的买家们实际上倾向于带有很多卧室的小房型,但是在郊区购房的买家们更青睐房屋总面积非常大的三居室。了解不同种类的客户可以指导你的市场工作。
另一件挺酷的事是你可以让程序自动查找离群点——迥然异于其余房屋的部分。这些在某些方面显得鹤立鸡群的房屋可能是巨型豪宅,考虑到其佣金回报率更高,此时你便可以考虑派遣手下最精英的销售人员集中处理那些区域的生意。
下文将集中介绍监督式学习,但这不意味着非监督式学习相比之下没那么有用或者有趣。实际上,由于非监督式学习中的数据并不需要有正确答案标记,相应算法不断得到改进,它现在变得越来越重要。
3.机器「学习」的定义
人类的大脑能够着手尝试处理绝大部分的情景问题,学会如何在根本没有任何明确指令的情况下解决相应问题。如果你长时间从事房屋买卖,自然会对一套房屋的合理价格、最佳的市场营销手段、具备购房意愿的客户种类等问题形成一种类似本能的「感觉」。强人工智能研究的目标就是能够在计算机上实现这种能力。
但现在的机器学习算法还没达到如此高的水准,只能在非常具体和有限的问题上得以应用。此时,也许当前对「学习」更恰当的定义是「使用一些实例数据解决一个特定问题,即找出满足问题要求的方程式」。不幸的是,「让机器使用一些实例数据解决一个特定问题,即找出满足问题要求的方程式」这样的名字可不太平易近人,于是我们最后还是继续用「机器学习」这个术语。
4.开始写程序那么,你要如何着手编写上例中房屋估值的程序呢?在具体展开这个主题之前请思考片刻。
逐条制定规则
如果你对机器学习一无所知,那么很可能会直接试着先写一些基本的房屋估值规则,譬如下面的代码:
def estimate_house_sales_price(num_of_bedrooms,sqft, neighborhood):
price=0
#In my area,the average house costs$200per 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 cheapprice=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.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 第二步: 将每一套房屋的数据都通过你的函数运行一遍,之后比较其计算结果与对应真实房价之间的差距: 用你的函数预测每套房屋的价格。 例如第一套房屋的真实售价是25万美元,而你的函数计算所得价格是17万8千美元,那么你对这套房屋的估值就比实际少了7万2千美元。 接下来把数据集中每一套房屋的真实价格和函数预测价格之间的差距值求平方,再全部相加。假设数据集中有500套房屋的销售信息,按照之前步骤计算实际与预测房价的差距值平方总和为86,123,373美元,这就是目前你的函数与理想状态(差距值平方总和为零)相差的距离。 现在把这个总和除以500,得到一个衡量单套房屋价格预测值和真实值之间差距的平均值。这个平均误差值被称为相应函数成本。 如果存在权重值可以使得你的函数成本为零,那么这个函数就堪称完美了。这也就意味着你的函数能够根据输入数据完美准确地预测每一套房屋的价格。所以我们的目标就是通过尝试不同的权重值把成本值尽可能地调整到最低。 第三步: 尝试使用每一种可能的权重值组合,一遍一遍重复第二步。能够将成本值降到最低(最接近零)的权重值组合就是你需要的结果。一旦找到这样的权重值,你就解决了这个问题! 5.脑力激荡时间 看上去是不是挺简单的?回顾一下刚才的流程吧:你取得一些数据、通过一套简单的三步操作不断输入数据、最后得到一个可以猜到所在区域单套房屋价格的函数。注意了,这就是Zillow(美国一家提供各类房地产信息查询服务的网站) 但是接下来有几个事实恐怕会让你感到奇怪: 1.很多领域(比如语言学和翻译)的研究在过去40年中都表现出这 样的特点:与其让人类自己尝试明晰和编写所有规则,那些「烹制数字佳肴」(上文里我造出的词组)的机器学习通用算法表现更佳。这看上去「笨拙的」机器学习方法最终打败了人类专家。 2.最终函数看上去的确笨拙。它甚至都不知道「平方英尺」或者「卧 室」是什么东西,而只知道在大量备选数字中来回挑拣,最后找到正确答案。 3.很有可能的是,你根本不明白为什么一组特定的权重值可以解决 你的问题。所以,实际上,你编写了一个自己都不怎么理解,但实证有用的函数。 4.实际上,你的预测函数其实只是读取一连串的数字,而并不在乎 这些参数的标识到底是不是叫做「平方英尺」和「卧室数量」。假设你在自己的车上安装了行车记录仪,它捕捉的图像中每一点像素的亮度对应着你手头数据中的每一个数字。现在函数输出的不再是标识为「价格」的数值,而是「方向盘转向的角度」的预测值。你这不就又有了一个具有自动驾驶功能的函数了嘛! 听上去有些不可思议吧? 权重值组合,怎么找? 好了,一味地尝试计算所有可能存在的权重值组合当然并不能帮你找到最佳答案,实际上反倒是毫无止境的无用功——因为你根本无法穷举所有可能的数字。 为了避免这种情况,数学家发明了很多聪明办法来快速找到优良的权重值,并不需要过多的尝试。下面我们来介绍一种方法: 首先,把上文中第二步所涉及的计算用一个简单的方程式写下来: 这就是你的成本函数。(译者注:等式右边分母是500乘以2,这个2是为了之后的计算方便。)我们使用一些机器学习相关的数学符号(读者可以忽略这些)将这个方程式改写一下: θ是指你现在选取的权重值。J(θ)是指「你现在选取的权重值所带来的成本」。 这个方程式代表在设定当前的权重值时我们的估价函数与理想状态相差的距离。 如果我们将成本函数作图,坐标系中的另外两根轴对应卧室数量和平方英尺的权重值取值范围,得到的图像如下所示: 成本函数的图形看上去像一个碗。垂直的坐标轴代表成本值。 图形中的最低点位于蓝色区域,这也就是成本值最小的位置,意味着我们的估价函数与理想状态相差的距离最小。当然了,图形中的最高点意味着相应函数与理想状态相差的距离最大。所以只要能找到对应图形中最低点的权重值,也就等于找到了最终答案! 于是我们需要做的就是调整权重值,使其对应的点在图形中不断下降。只要一直保持权重值向最低点方向进行小步调整,我们最终会到达最低点,而且这个过程并不需要一一尝试众多权重值。 如果你曾修过微积分课,那么也许会记得对函数求导等同于求该函数图像在某一点的切线的斜率值。也就是说,求导的结果表明函数图像在指定点的走向是上还是下,我们可以使用这个信息来找到函数值的下降路径。 所以,只要先计算成本函数关于每个权重值的导数(即函数的偏导数),然后把求得的值从原权重值中减去,之后的新权重值意味着我们离函数图形的最低点又近了一步。重复这个过程,最后将到达图形最低点,至此终于找到可能是最佳选择的权重值。(如果你还是不太理解,不要紧,请继续读下去。) 以上是对一种被称为批量梯度下降方法的高度概括,该方法的目的是为函数找到最佳权重值。如果你对更深入的细节感兴趣,也可另行深挖:http://t.cn/RGjl7V8。 当你使用机器学习程序库来解决一个具体实际问题时,很多工作都是自动完成的,但好好理解其内部机理仍十分有用。 你需要知道的更多方面 以上描述的三步算法叫做多变量线性回归。你估算出一个线性方程式(在坐标系中的图形是一条直线)来匹配你所有的房价数据(在坐标系中的图形是一系列的点)。然后你只需观察新房源在坐标系中所对应的点在线性方程式的什么位置上,就可以得到其预测价格了。这是个极有力的想法,能帮助我们解决很多实际问题。 虽然我给出的方案适用于许多简单的项目,但它并不是万能的。原因之一是:房价的分布往往没有这般简单,不总是符合连续的线性关系。 幸运的是,有大量的方法可以用来处理这个问题。很多机器学习算法是专门针对非线性数据的,例如神经网络,以及使用核函数方法的支持向量机。此外,我们也可以更为巧妙地使用线性回归方法,使其匹配复杂性更高的直线图形。然而,不论我们怎么做,找到最佳的权重值这一基本思路是始终不变的。 同时,我也忽视了关于过度拟合的问题。事实是我们不难找到一组导致如下糟糕情况的权重值:它能使函数完全正确地预测原始训练数据集当中的房价,但对于任何不属于原始训练数据集的新房源只会做出无效预测。好在我们也有办法应对这个麻烦,比如正则化,以及使用交叉验证的数据集。学会如何处理此类问题对于机器学习的成功应用而言是相当关键的一环。 换句话说,虽然相关的基本概念较简单,但应用机器学习并得到可用的结果需要相当的技巧与经验。值得庆幸的是,任何一个开发人员都有机会学习和掌握机器学习的技能! 机器学习是一种魔术吗? 当你见识到机器学习技术是如何将看上去相当困难的问题轻易化解(例如辨识笔迹),你也许会开始幻想,只要自己手里有足够的数据,所有问题都能用机器学习来解决,问题的答案几近唾手可得。只需输入数据,然后坐等电脑变魔术一般地找到适用于数据的方程式就行了。 但是请记住这一点:机器学习可用的前提是——你手头的数据确确实实能解决目标问题。 举个例子,如果你的房价预测模型是建立在每套房屋内盆栽植物的种类这样的信息基础之上,那这模型永远都是无用的。每套房屋内的盆栽植物和其房价之间本就没什么关系,所以无论模型如何尝试预测,计算机也完全没有办法推导出这两个变量之间的确切关系。 你只能对真正存在的数据关系进行建模。 请记住,如果人类专家无法用一组数据解决问题,那么将其转而输入电脑往往也不会奏效。相对的,请先聚焦于那些人类可以手动解决的问题,这样一来,电脑的速度优势得以呈现时,你就会觉得棒棒哒。 6.机器学习:如何学到更多? 在我看来,目前机器学习的最大问题是它几乎只存在于学术界和商业研究团队之中。对于那些想要在广泛意义上了解机器学习,没打算成为此领域专家的人而言,从这些渠道取得的材料绝大部分都远远谈不上深入浅出。然而,这种情况正在逐步改善。 吴恩达(Andrew Ng)在Coursera平台上开设的免费机器学习课程相当棒,极力推荐大家从这门课开始。这门课对任何具备计算机科学专业知识的人来说都应该能轻易上手,即便你现在所记得的数学知识也许已经不多了。 此外,你可以下载安装SciKit-Learn,尝试运行无数的机器学习算法。该工具是一个python语言框架,内含所有标准算法的「黑盒」版本。下载本文