机器学习的本质就是借助数学模型理解数据。当我们给模型装上可以适应观测数据的可调参数时,“学习”就开始了;此时的程序被认为具有从数据中“学习”的能力。一旦模型可以拟合旧的观测数据,那么它们就可以预测并解释新的观测数据。
目前在学习一个卷积神经网络模型,模型的构建和我自己最初想象的不一样。使用的tensorflow搭建网络,在数据输入之前就已经构建好了模型,即构建好图。在阅读代码的过程中,tensorflow的思想与以前的编程思想确实不大一样,这里采用的是数据流图。先定义数据之间的操作,数据以张量的形式进行流过各种操作,期间会有很多数据维度的变换,这也实现了异步并行运算。
机器学习是如何学习的呢?对于我这个菜鸟来说,仍然没有弄明白。看了一段时间的代码之后,对于现在的卷积网络,我认为是先初始化模型,这里只是搭建模型的框架,比如输入输出值的大小,网络具有多少层。很多参数的初始化都是通过正态分布随机取数得到参数。之后输出真实数据,通过使用优化器来优化模型的参数,可能就是上述所说的“学习”。
有监督学习是指对数据的若干特征与若干标签(类型)之间的关联性进行建模的过程;只要模型被确定,就可以应用到新的未知数据上。这类学习过程可以进一步分为分类(classification)任务与回归(regression)任务。在分类任务中,标签都是离散值;而在回归任务中,标签都是连续值。
无监督学习是指对不带任何标签的数据特征进行建模,通常被看成是一种“让数据自己介绍自己”的过程。这类模型包括聚类(clustering)任务和降维(dimensionality reduction)任务。聚类算法可以将数据分成不同的组别,而降维算法追求用更简洁的方式表现数据。
半监督学习(semi-supervised learning)方法,介于有监督学习与无监督学习之间。半监督学习方法通常可以在数据标签不完整时使用。
分类:预测离散标签
我们看到的是二维数据,也就是说每个数据点都有两个特征,在平面上用数据点的(x, y)位置表示。另外,我们的数据点还用一种颜色表示一个类型标签,一共有两种类型,分别用两种颜色表示(蓝色、红色)
假设平面上有一条 可以将两种类型分开的直线,直线的两侧分别是一种类型。那么,我们的模型其实就是“一条可以分类的直线”,而模型参数其实就是直线位置与方向的数值。这些模型参数的最优解都可以通过学习数据获得(也就是机器学习的“学习”),这个过程通常被称为训练模型
拿一组新数据,把这个模型的直线画在上面,然后根据这个模型为新数据分配标签。这个阶段通常被称为预测
这就是机器学习中最基本的分类思想,这个“分类”指的是数据具有离散的类型标签。
机器学习方法的真正用途是要解决大型高维度数据集的分类问题;
以常见的分类任务——垃圾邮件自动识别为例。在这类任务中,我们通常会获得以下特征与标签。
• 特征1、特征2……特征n → 垃圾邮件关键词与短语出现的频次归一化向量(“Viagra” “Nigerian prince”等)。
• 标签 →“ 垃圾邮件”或“普通邮件”。
在训练数据集中,这些标签可能是人们通过观察少量邮件样本得到的,而剩下的大量邮件都需要通过模型来判断标签。一个训练有素的分类算法只要具备足够好的特征(通常是成千上万个词或短语),就能非常高效地进行分类。
回归:预测连续标签
我们有一个二维数据,每个数据点有两个特征。数据点的颜色表 示每个点的连续标签
用简单线性回归模型作出假设,如果我们把标签看成是第三个维度,那么就可以将数据拟合成一个平面方程——这就是著名的在二维平面上线性拟合问题的高阶情形。
类似的任务有计算通过天文望远镜观测到的星系的距离——在这类任务中,可能会用到以下特征与标签。
• 特征1、特征2……特征n → 具有若干波长或颜色的星系的亮度。
• 标签 → 星系的距离或红移(redshift)。
少量星系的距离可以通过直接观察(通常成本也非常高)进行测量。之后,我们就可以利用适当的回归模型估计其他星系的距离,而不需要为整个星系集合使用昂贵的观察设备。在天文学领域中,这种问题通常被称为“测光红移”(photometric redshift)。
聚类:为无标签数据添加标签
无监督学习的普遍应用之一就是“聚类”——数据被聚类算法自动分成若干离散的组别。
一个聚类模型会根据输入数据的固有结构判断数据点之间的相关性。通过最快、最直观的k-means 聚类算法,就可以发现所示的类簇(cluster)
降维:推断无标签数据的结构
降维是另一种无监督算法示例,需要从数据集本身的结构推断标签和其他信息。
降维比之前看到的示例要抽象一些,降维其实就是在保证高维数据质量的条件下从中抽取出一个低维数据集。
例如,我们可能需要对一个包含100或1000个特征的数据集内部的关联性进行可视化。要对一个1000维的数据进行可视化是个巨大的挑战,一种解决办法就是通过降维技术,让我们可以在更容易处理的二维或三维空间中对数据进行可视化。
一些重要的降维算法,包括主成分分析和各种流形学习算法,如Isomap 算法、局部线性嵌入算法。
降维的任务是要找到一个可以保留数据本质特征的低维矩阵来表示高维数据。降维通常用于辅助数据可视化的工作,毕竟用二维数据画图比用四维甚至更高维的数据画图更方便!
有监督学习
可以训练带标签的数据以预测新数据标签的模型。
分类
可以预测两个或多个离散分类标签的模型。
回归
可以预测连续标签的模型。
无监督学习
识别无标签数据结构的模型。
聚类
检测、识别数据显著组别的模型。
降维
从高维数据中检测、识别低维数据结构的模型。
Scikit-Learn(http://scikit-learn.org)是最流行的程序包之一,它为各种常用机器学习算法提供了高效版本。Scikit-Learn不仅因其干净、统一、管道命令式的API 而独具特色,而且它的在线文档又实用、又完整。这种统一性的好处是,只要你掌握了Scikit-Learn 一种模型的基本用法和语法,就可 以非常平滑地过渡到新的模型或算法上。
数据表
基本的数据表就是二维网格数据,其中的每一行表示数据集中的每个样本,而列表示构成每个样本的相关特征。
特征矩阵
这个表格布局通过二维数组或矩阵的形式将信息清晰地表达出来,所以我们通常把这类矩阵称为特征矩阵(features matrix)。特征矩阵通常被简记为变量X。它是维度为[n_samples, n_features] 的二维矩阵, 通常可以用NumPy 数组或Pandas 的DataFrame 来表示,不过Scikit-Learn 也支持SciPy 的稀疏矩阵。
样本(即每一行)通常是指数据集中的每个对象。例如,样本可能是一朵花、一个人、一篇文档、一幅图像,或者一首歌、一部影片、一个天体,甚至是任何可以通过一组量化方法进行测量的实体。
特征(即每一列)通常是指每个样本都具有的某种量化观测值。一般情况下,特征都是实数,但有时也可能是布尔类型或者离散值。
目标数组
目标数组一般是一维数组,其长度就是样本总数n_samples,通常都用一维的NumPy 数组或Pandas 的Series 表示。目标数组可以是连续的数值类型,也可以是离散的类型/标签。
虽然有些Scikit-Learn 的评估器可以处理具有多目标值的二维[n_samples, n_targets] 目标数组,但此处基本上只涉及常见的一维目标数组问题。
如何区分目标数组的特征与特征矩阵中的特征列,一直是个问题。目标数组的特征通常 是我们希望从数据中预测的量化结果;借用统计学的术语,y 就是因变量。以前面的示例数据为例,我们需要通过其他测量值来建立模型,预测花的品种(species),而这里的species 列就可以看成是目标数组。
统一性
所有对象使用共同接口连接一组方法和统一的文档。
内省
所有参数值都是公共属性。
限制对象层级
只有算法可以用 Python 类表示。数据集都用标准数据类型(NumPy 数组、Pandas、DataFrame、SciPy 稀疏矩阵)表示,参数名称用标准的Python 字符串。
函数组合
许多机器学习任务都可以用一串基本算法实现,Scikit-Learn 尽力支持这种可能。
明智的默认值
当模型需要用户设置参数时,Scikit-Learn 预先定义适当的默认值。
(1) 通过从Scikit-Learn 中导入适当的评估器类,选择模型类。
(2) 用合适的数值对模型类进行实例化,配置模型超参数(hyperparameter)。
(3) 整理数据,通过前面介绍的方法获取特征矩阵和目标数组。
(4) 调用模型实例的fit() 方法对数据进行拟合。
(5) 对新数据应用模型:
在有监督学习模型中,通常使用predict() 方法预测新数据的标签;
在无监督学习模型中,通常使用transform() 或predict() 方法转换或推断数据的性质。
有监督机器学习模型的基本步骤:
(1) 选择模型类;
(2) 选择模型超参数;
(3) 用模型拟合训练数据;
(4) 用模型预测新数据的标签。
模型选择和超参数选择——可能是有效使用各种机器学习工具和技术的最重要阶段。
模型验证(model validation)其实很简单,就是在选择模型和超参数之后,通过对训练数据进行学习,对比模型对已知数据的预测值与实际值的差异。
留出集
留出集可以更好地评估模型性能,也就是说,先从训练模型 的数据中留出一部分,然后用这部分留出来的数据来检验模型性能。在Scikit-Learn 里面用train_test_split 工具就可以实现。
交叉检验
用留出集进行模型验证一个缺点,就是模型失去了一部分训练机会。有一半数据都没有为模型训练做出贡献。这显然不是最优解,而且可能还会出现问题——尤其是在训练数据集规模比较小的时候。
解决这个问题的方法是交叉检验,也就是做一组拟合,让数据的每个子集既是训练集,又是验证集。
关键问题是:假如模型效果不好,应该如何改善?答案可能有以下几种。
• 用更复杂/ 更灵活的模型。
• 用更简单/ 更确定的模型。
• 采集更多的训练样本。
• 为每个样本采集更多的特征。
问题的答案往往与直觉相悖。换一种更复杂的模型有时可能产生更差的结果,增加更多的训练样本也未必能改善性能!改善模型能力的高低,是区分机器学习实践者成功与否的标志。
“最优模型”的问题基本可以看成是找出偏差与方差平衡点的问题。
• 对于高偏差模型,模型在验证集的表现与在训练集的表现类似。
• 对于高方差模型,模型在验证集的表现远远不如在训练集的表现。
验证曲线,具有以下特征
• 训练得分肯定高于验证得分。一般情况下,模型拟合自己接触过的数据,比拟合没接触过的数据效果要好。
• 使用复杂度较低的模型(高偏差)时,训练数据往往欠拟合,说明模型对训练数据和新数据都缺乏预测能力。
• 而使用复杂度较高的模型(高方差)时,训练数据往往过拟合,说明模型对训练数据预测能力很强,但是对新数据的预测能力很差。
• 当使用复杂度适中的模型时,验证曲线得分最高。说明在该模型复杂度条件下,偏差与方差达到均衡状态。
究竟多项式的次数是多少,才能在偏差(欠拟合)与方差(过拟合)间达到平衡?
我们可以通过可视化验证曲线来回答这个问题——利用Scikit-Learn 的validation_curve函数就可以非常简单地实现。只要提供模型、数据、参数名称和验证范围信息,函数就会自动计算验证范围内的训练得分和验证得分
影响模型复杂度的另一个重要因素是最优模型往往受到训练数据量的影响。例如,生成前面5倍的数据(200 个点)
反映训练集规模的训练得分/ 验证得分曲线被称为学习曲线(learning curve)
学习曲线的特征包括以下三点:
特定复杂度的模型对较小的数据集容易过拟合:此时训练得分较高,验证得分较低。
特定复杂度的模型对较大的数据集容易欠拟合:随着数据的增大,训练得分会不断降低,而验证得分会不断升高。
模型的验证集得分永远不会高于训练集得分:两条曲线一直在靠近,但永远不会交叉。
学习曲线最重要的特征是,随着训练样本数量的增加,分数会收敛到定值。因此,一旦你的数据多到使模型得分已经收敛,那么增加更多的训练样本也无济于事!改善模型性能的唯一方法就是换模型(通常也是换成更复杂的模型)。
from sklearn.learning_curve import learning_curve
首先探索了模型验证与超参数优化的概念,重点介绍了偏差与方差均衡的概念,以及如何将这个概念应用在模型拟合过程中。尤其值得注意的是,我们发现通过验证集或交叉检验方法调整参数至关重要,这样做可以避免较复杂/ 灵活模型引起的过拟合问题。
接下来将介绍一些常用模型的具体细节、可用的优化方法,以及自由参数(free parameter)对模型复杂度的影响。