“All models are wrong, but some are useful.”程序员
— George Box算法
机器学习(Machine Learning)最大的魅力在于改变了开发者的思考方式,开发者不须要再费力地给程序编写固定的逻辑指令,而是让程序对大量的未知数据进行分析思考,而后学会如何去处理未知的输入,如何对结果进行预测,如何采起动做服务器
y
值x
值,一个复杂的机器学习系统可能须要成千上万个特征labeled examples: {features, label}: (x, y)
,如这封被用户主动标记为垃圾邮件的邮件。无标签样本只有特征没有标签 unlabeled examples: {features, ?}: (x, ?)
。咱们的目的就是经过大量的有标签样本去训练模型,让它可以对任何无标签的样本进行标签的预测在统计学中,线性回归(Linear Regression)是对 标量响应(因变量) 和 一到多个解释变量(自变量) 之间的关系进行建模的一种线性方法,只有一个解释变量时被称为简单线性回归,有多个解释变量时被称为 multiple 线性回归,预测多个相关因变量时被称为 multivariate 线性回归
网络
在统计学中,肯定函数中的参数时一般采用 “最小二乘法”,这是最多见最简单的尽量减少偏差的拟合方法。在机器学习中,这个关系模型的表示也差很少:app
要想推理(预测)一个新的每分钟虫鸣数 对应的温度
,只须要把
带入这个模型便可
这个预测模型只有每分钟虫鸣数一个特征,而一个复杂的模型每每有多个特征和对应的权重,如:
建立或训练模型的过程就是寻找最好的权重和误差值的过程(肯定最好的 和
的过程),而在监督式学习中,机器学习算法经过“考察大量样本以便尝试寻找一个最小化损失的模型”来构建模型,这个过程也被称为经验式风险最小化(empirical risk minimization)
损失就是指对糟糕预测的惩罚,是表示模型在一个样本上预测的糟糕程度,是个数值,若是模型的预测是完美的,那么损失就是零,不然损失就很大,咱们能够建立一个数学函数(损失函数)去有意义地汇总各个损失
机器学习
如何快速高效地肯定最好(如使 MSE 最小)的 和
的值呢?最简单的办法就是先胡乱猜一个
和
的值,计算一下损失,而后调整一下
和
的值,计算损失,比较一下这两次损失再决定如何调整
和
的值(若是损失变小了说明调整的方向对了,继续按照当前方向调整就好了,若是损失变大了就要考虑改变调整的方向了),理论上不断地迭代试错下去就能找到最好的
和
的值
函数
泛化(Generalization)指对新的前所未见的数据进行正确预测的能力。上面的模型过拟合(overfit)了训练数据的特性,一个过拟合的模型虽然在训练过程当中损失很低可是在预测新数据时却表现糟糕,那怎么判断一个模型对新的数据能不能作出很好地预测呢?这就涉及到正则化的问题了。过拟合之因此会出现问题是由于它为了追求训练时的完美让模型变得异常复杂,而机器学习应该在拟合数据的同时尽量地保证简单,应该符合奥卡姆剃刀定律,为了方便验证模型的泛化能力,能够将数据集分红专门用来训练的训练集和专门用来测试的测试集,在测试集上表现良好每每能代表在新的数据集也能表现良好,前提是测试集足够大且不会反复用相同测试集做假
泛化过程通常须要知足三项基本假设:工具
实际上,有些状况下可能会违反其中一些假设,如广告推荐模型可能依赖于用户以前看过的广告,这违反了第一条假设,而一旦违反任意一项假设,就表示咱们已经失去了重要的理论支持,就必须得时刻注意各项指标了
既然测试集应该足够大,那多大好呢?怎么合理地把数据集分红训练集和测试集呢?训练集和测试集应该相互独立,但 训练集的规模越大模型的学习效果就越好,测试集规模越大咱们咱们对评估指标的信心就越足,若是数据集的规模自己就很大就简单多了,但若是数据集规模很是小,就要先进行像交叉验证(cross-validation)之类的复杂操做了
测试集应该知足两个条件:学习
永远不要对测试集进行训练,若是你发现模型在测试集上预测的准确度特别高,甚至比在训练集上的还高,先不要兴奋,你极可能把一些测试数据用于训练了,得从新检查一下训练集是否是包含了一些训练集的数据
在训练集上训练模型,在测试集上评估模型,再根据评估的结果调整模型,如此循环下去直到能选择一个在测试集上表现最好的模型。这样的流程有点问题,咱们可能无形中对测试数据的特性进行了过拟合,因此为了不出现这种状况,咱们从数据集中再单独划分出一些数据做为验证集,这样迭代评估的时候只在验证集上评估便可,测试集只用来确认结果,要确保在测试集上得出的结果基本符合在验证集上得出的结果,若是不符合就说明对验证集进行了过拟合
测试
咱们彷佛忘了一个最基本的问题,那就是如何从原始数据中抽象出供模型使用的特征值,而从各类各样的数据源中提取数据,而后再根据这些数据建立特征向量的过程被称为特征工程(feature engineering)。像房屋的卧室数量这样的简单数值信息直接复制到特征向量就能够了,可是像房屋的所属街道这样的字符串信息怎么映射到特征向量呢?最简单的方式就是采用 one-hot 独热编码,如一共有 N 个街道,那就建立一个 N 位的编码,而后按照字典的方式将全部街道映射到这个这个编码上(第 i 个街道那一位置 1,其它位置 0),若是 N 特别大,能够采用稀疏表示法(sparse representation)压缩。那究竟什么样的特征才算好的特征呢?首先,它应该具备非零值且至少出现不少次,若是一个特征出现次数极少或只出现一次,就能够考虑在预处理时就把它过滤掉了。其次,它应该具备清晰明确的意义,以便咱们在检查和调试时特征被正确的处理。第三,特征值不该随时间而发生变化。最后,特征值不该采用不理性的离群值。要作这么多工做的缘由是为了把噪音降到最低,机器学习就像一个黑盒子,把数据都丢进去,却不检查数据,就盼着能得到好的结果,这从目前来看很不合适也不现实,因此在把数据交给机器学习模型以前,咱们只能凭借本身的经验对特征进行抽象和过滤等处理,甚至还要监控特征随着时间变化的状况。
不少时候浮点特征值的范围会很大(如 100 到 900),为了让梯度降低法更快地收敛,同时为了不数据溢出致使的 NaN 问题,能够把它缩放到标准范围(如 0 到 1 或 -1 到 +1),最简单的缩放策略就是线性的缩放,不过还有一种缩放策略是先计算每一个值的 Z score,缩放后的值为 (原始值 - 平均值) / 标准差
,这样的话大多数缩放后的值都会介于 -3 和 +3 之间了。
有时咱们须要处理一下极端离群值(extreme outlier):
良好的机器学习依赖于良好的数据
到目前为止,咱们研究的都是线性问题,线性学习器不但简单并且能够很容易扩展到大型数据集,可是若是要建模的问题很复杂怎么办?
在研究泛化问题时咱们重点关注了过拟合的问题,若是咱们过于追求在训练集上的损失极低,就可能会出现过拟合训练集而带来的问题:
咱们要平衡这两个因素,让损失和复杂度都尽量地低,也就是说,要确保正确的训练数据,又不过分信赖训练数据。那如何定义模型复杂度呢?最简单的就是选择较小的权重,也就是说即便参数小到能够忽略咱们依然能够获取正确的训练样本,从数学上来讲通常使用 正则化,也称为岭正则化,在这种正则化策略中,咱们对权重的平方和进行惩罚,若是熟悉贝叶斯先验几率就知道这是一种先验几率,在咱们知道训练样本以前就猜到权重应该是以 0 为中心呈正态分布的,并且数值不会太大。以数学的方式表示上面的公式为
能够看到第一项下降损失的过程取决于训练数据,而第二项简化模型则与数据无关,这两项经过 实现了平衡,
的选取取决于你和实际状况,若是有大量训练数据且训练数据与测试数据看起来一致,知足独立同分布,你可能不须要多少正则化,不然可能须要大量正则化和交叉验证,
(lambda)也被称为正则化率(regularization rate),若是 lambda 值太高,模型会很是简单,但会面临数据欠拟合的风险,模型将没法充分了解训练数据以进行有用的预测,若是 lambda 值太低,模型会比较复杂,会面临数据过拟合的风险,模型会过多解读训练数据的特殊性从而很难泛化到新的数据。将 lambda 值设为 0 可完全取消正则化,此时训练的惟一目的就是最小化损失,可是会使过拟合的风险达到最高。
正则化鼓励 non-informative 特征的权重趋向于 0,可是当这类特征刚好与标签相关时,会致使模型学到一个中等的权重,此时,模型错误地给了 non-informative 特征一些本应该给 informative 特征的信任。
正则化对大权重的惩罚比小权重更严厉,所以,即便一个权重降低得比另外一个快,
正则化也会强制使较大权重的那个降低得比较小的更快。
正则化与学习速率息息相关,很容易让人困惑
正则化虽然可使权重变小,但不能使他们正好为 0,
正则化虽然可使权重为 0,这样能够直接忽略某些特征进而减小内存消耗,可是它会将咱们的凸优化问题变成非非凸优化问题(NP 困难),因此
正则化并不实用。而
正则化具备凸优化的优点,能够进行有效计算。
会下降权重的平方,
会下降权重的绝对值,
的导数是 2 乘以权重,
的导数是与权重无关的常量 k,也就是说
每次移除权重的 x%,一般不会减到 0,
每次从权重中减去固定的常数,若是减法使权重从 +0.1 变成 -0.2,因为惩罚的是绝对值,因此权重会变成 0
不少问题都须要把 几率估计 做为输出,好比图片中的动物是猫的几率是多少、狗晚上吵醒人的几率是多少,既然是几率,那么几率值确定是 0 到 1 之间,那咱们以前学到的线性模型的输出能强制限制到 0 到 1 之间么?很显然不太现实,那咱们就要想出一种不一样的损失函数和预测方法使几率值很天然的处于 0 到 1 之间,咱们将这种想法称为逻辑回归(Logistic Regression)。逻辑回归的几率就很是有用了,甚至能够被看作实际几率去作有用的预测,用这个几率乘以想要预测的项就能够获得预期值。它在二元分类(binary classification)中也很是有用,如一封邮件是垃圾邮件的几率是多少,一枚硬币朝上的几率是多少。那逻辑回归模型是怎样保证输出老是介于 0 到 1 之间呢?咱们来看一下 S 型函数(sigmoid function):
其中 表示包含不少有标签样本的数据集,
表示有标签样本中的标签,
表示预测的值
在逻辑回归模型中正则化变得更加剧要,若是没有正则化,那么逻辑回归的渐进性将在高维上让损失趋向于 0 ,若是未指定正则化函数,模型将变得彻底过拟合,所以逻辑回归模型一般使用 正则化或早停法下降模型的复杂度
机器学习模型解决的最多见的问题就是分类问题,如邮件是正常邮件仍是垃圾邮件,图片中的物体是什么,咱们可使用逻辑回归做为分类的基础,给 几率输出 应用 固定的阈值(threshold)就好了,如一封邮件为垃圾邮件的几率超过了 0.8,咱们就认为它是垃圾邮件,0.8 就是分类的阈值(分类阈值 classification threshold 也被称为断定阈值 decision threshold),一旦选定了分类阈值,那咱们怎么评估这个阈值下模型的质量呢?最传统的方式就是用准确率(accuracy)这个指标,也就是预测正确数除以总数。可是准确率有时会成为不好或者误导性的指标,好比当不一样错误的类型代价不同时,当分类不平衡(正例或负例极少)时(一个广告的点击率是千分之一万分之一甚至更低,那么一个模型预测一个广告不被点击的的准确率是 99.999% 没有任何意义),此时区分不一样错误的类型可能会有所帮助:
也就是说,TP 和 TN 都是正确的预测,而 FP 是指模型错误地将负类别预测成正类别,FN 更是严重错误地将正类别预测成负类别
如今假如出现了 100 次狼来了事件,有 1 次狼真的来了小男孩喊狼来了,有 1 次狼没来却喊狼来了,有 8 次狼来了却没喊,有 90 次 狼没来也没喊,那么小男孩的准确率高达 ,从 91% 的准确率来看这个小男孩还挺好,可是事实是这样的吗?在 91 次狼没来中小男孩有 90 次没喊狼来了,可是,在 9 次狼真的来了的时候小男孩却只有 1 次喊狼来了,这是多么可怕啊!若是是肿瘤诊断模型,9 个恶性肿瘤中只有 1 个被发现是恶性肿瘤,那后果将更加的可怕
所以咱们须要一些新的指标来评估,如精确率(precision),也就是小男孩喊狼来了的状况中有多少次是对的,。另外一方面,召回率(recall)是指在全部尝试进入村子的狼中咱们发现了多少头,即正确被识别为正例的比例,
。有趣的是这些指标每每是此消彼长的,如为了把召回率作得好只要有风吹草动就喊狼来了,这会下降分类阈值,为了精确率高只有在确认狼真的来了才喊狼来了,这会提升分类阈值,所以只有这两方面都作得好才能评价模型的优劣。通常来讲,提升分类阈值会减小假正例,从而提升精确率
你可能会说,那我把全部可能的分类阈值都试一下看那个阈值下模型的表现更好不就好了么?事实上确实有这样的,叫 ROC 曲线
真正例率 TPR(True Positive Rate)为 ,和召回率同样
假正例率 FPR(False Positive Rate)为
将不一样阈值下的 TPR 和 FPR 值的点连成一条曲线就是 ROC 曲线:
当问题复杂到没法用线性回归解决怎么办?即便是利用特征交叉也没法解决非线性的问题呢?这个时候咱们但愿经过某种方式,让模型本身学习非线性的规律,而不用咱们手动为它设置参数。这一愿景能够经过深度神经网络(Deep Neural Networks)实现,它在复杂数据问题上作得特别好,例如图片数据,视频数据,音频数据等。先来看一下线性模型的表示,如 :
训练神经网络最经常使用的训练算法就是反向传播算法(Backpropagation),它使梯度降低用于多层神经网络成为可能,反向传播依赖梯度这个概念,事物必须是可微的,这样咱们才能进行学习
须要注意的是,可能会出现梯度消失(Vanishing Gradients)的状况,若是网络太过深刻,信噪比随着模型的深刻变差,学习可能变得特别慢,这个时候 ReLU 或其余策略可能比较有用。若是网络中的权重太大,那么较低层的梯度会涉及许多大项的乘积,可能就会出现梯度爆炸(Exploding Gradients)的状况,此时梯度太大根本没法收敛,Batch 标准化或者下降学习速率会比较有用。若是加权和都低于 0,那么 ReLU 单元会卡住,对网络输出没有任何贡献,梯度就没法反向传播,永远没法返回存在 ReLU 层的位置,就会出现死亡 ReLU 单元(Dead ReLU Units)的状况,此时使用不一样的初始化或下降学习速率会有所帮助
训练神经网络时还有一个颇有用的技巧,正则化的另外一种形式,叫作丢弃(Dropout),就是针对几率 P 取一个节点,而后从网络的一个梯度步长中把它移除。在其余梯度步长中重复此过程,并随机取不一样的节点进行丢弃,丢弃的越多,正则化的效果就越强
到目前为止,咱们讨论的分类问题都是二元分类问题,如邮件是否是垃圾邮件,肿瘤是恶性的仍是良性的,咱们也知道了,利用逻辑回归和能够很好地解决二元分类问题,可是生活中不少分类问题是多类别(multi-class)的,如图片中的东西是苹果仍是梨仍是小狗仍是其余的东西,这朵花是什么花。那咱们怎么把二元分类拓展到多类别分类呢?one-vs.-all 提供了利用二元分类的方式,若是有 N 个可能解,one-vs.-all 就包含 N 个单独的二元分类器,也就是说每一个可能的结果都对应一个二元分类器,在训练的时候,模型会运行一系列二元分类器,对每一个分类器进行训练以回答单独的分类问题,如给定一张狗狗的图片,可能会训练五种不一样的识别器:
当类别不多时还能够接受,但类别不少时,效率就会变得异常低下,所以咱们可使用深度神经网络建立一个明显更高效的 one-vs.-all 模型,其中每一个输出节点表明不一样的类型:
当类别不少时,Softmax 的代价会变得很大,因此除了 Full Softmax 还有一种策略叫 Candidate sampling,对全部正例标签计算几率,但只对负例标签的随机样本计算几率,如咱们想肯定图片是小猎犬仍是寻血猎犬,咱们就没必要为每一个非狗样本提供几率了
Softmax 假设每一个样本只能有一个类别,若是一个样本同时属于多个类别,那么你就不能用 Softmax,你只能依赖多个逻辑回归
如今咱们思考一个问题,咱们在读一本书的时候,或者在思考的时候,脑海里总有一个声音跟你说话,这个声音很像你本身的声音,但又不是你的声音,若是你看过西部世界,或者对心理学有过了解,你可能知道有一种理论叫作二分心智。二分心智通常被看作是人类意识的起源,而人们对于意识这种东西并非真正的了解,可是人类却总想扮演上帝的角色,想要赋予一我的造的机器意识。上个世纪人们开动本身的想象力,想象着赋予机器意识的那一天,各类科幻电影更是把这种想象表达的淋漓尽致,然而到如今人们才冷静下来,发现人工智能还有很长很长一段路要走,与其建立人工智能不如利用已有的知识水平为人工智能铺路,不如将已有的人工智能成果(机器学习)应用于现实生活中,Google 的 AI 向善就是很好地方式,利用 AI 技术能够预测洪水,能够用于医疗,能够预测疾病,能够帮助聋哑人跟正常人沟通等等等等
机器学习做为实现 AI 的主要手段,涉及到的知识和领域很是多,而 Google 提供的 TensorFlow 平台让普通人建立或训练机器学习模型成为可能,做为普通人,你没法提出革命性的人工智能理论,甚至没法理解不少数学知识,可是有了 TensorFlow 平台,有了一些训练好的模型,你就能够建立本身想要的,能帮助你本身或者帮助他人解决问题的模型