机器学习(一)之 2万多字的监督学习模型总结V1.0:K近邻、线性回归、岭回归、朴素贝叶斯模型、决策树、随机森林、梯度提升回归树、SVM、神经网络

0 本文介绍

2万多字符的监督学习模型总结 V1.0

​ 本文根据Andreas C.Muller的《Introduction to Machine Learning with Python》和西瓜书,整理了常见的监督学习模型。本文不讲解复杂的数学理论,涉及到了K近邻、线性模型、朴素贝叶斯分类器、决策树、随机森林、梯度提升回归树、SVM、MLP,以及监督学习模型的选择原则,全文2万多字,后续还会进一步补充

​ 在后面的博客中会记录机器学习数学推导、无监督学习等机器学习内容,Kaggle竞赛等竞赛。

相关笔记:
机器学习(一)之 2万多字的监督学习模型总结V1.0:K近邻、线性回归、岭回归、朴素贝叶斯模型、决策树、随机森林、梯度提升回归树、SVM、神经网络
机器学习(二)之无监督学习:数据变换、聚类分析
机器学习(三)之数据表示和特征工程:One-Hot编码、分箱处理、交互特征、多项式特征、单变量非线性变换、自动化特征选择
机器学习(四)之参数选择:交叉验证、网格搜索
机器学习(五)之评价指标:二分类指标、多分类指标、混淆矩阵、不确定性、ROC曲线、AUC、回归指标

1 K近邻

1.1 何为K近邻

​ KNN 算法可以说是最简单的机器学习算法,构建和预测都非常简单。构建模型只需要保存训练数据集即可。想要对新数据点做出预测,算法会在训练数据集中找到最近的数据点,也就是它的“最近邻”。

一个邻居:KNN算法最简单的就是一个最近邻,也就是与我们想要预测的数据点最近的训练数据点。预测结果就是这个训练数据点的已知输出。

K个邻居:在考虑多于一个邻居的情况时,我们用“投票法”(voting)来指定标签。也就是说,对于每个测试点,我们数一数多少个邻居属于类别0,多少个邻居属于类别1。然后将出现次数更多的类别(也就是k 个近邻中占多数的类别)作为预测结果。

1.2 构建K近邻—分类

​ 在scikit-learn中构建K近邻十分简单,只需要导入类并将其实例化即可。这时可以设定参数,比如邻居的个数。

from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors=optional number)
clf.fit(X_train, y_train)
clf.predict(X_test)
print("Test set accuracy: {:.2f}".format(clf.score(X_test, y_test)))

1.3 分析KNeighborsClassifier

​ 可以进行可视化,以查看决策边界(decision boundary),即算法对类别0 和类别1 的分界线。

模型复杂度和邻居的关系:

  • 使用单一邻居绘制的决策边界紧跟着训练数据
  • 随着邻居个数越来越多,决策边界也越来越平滑
  • 更平滑的边界对应更简单的模型,使用更少的邻居对应更高的模型复杂度,而使用更多的邻居对应更低的模型复杂度
  • 极端情况:邻居个数等于训练集中所有数据点的个数,那么每个测试点的邻居都完全相同(即所有训练点),所有预测结果也完全相同即训练集中出现次数最多的类别。

模型复杂度和泛化能力之间的关系:

img

​ 监督学习模型都是符合这张图的。仅考虑单一近邻时,训练集上的预测结果十分完美。但随着邻居个数的增多,模型变得更简单,训练集精度也随之下降。单一邻居时的测试集精度比使用更多邻居时要低,这表示单一近邻的模型过于复杂。与之相反,当考虑10 个邻居时,模型又过于简单,性能甚至变得更差。最佳性能在中间的某处。

1.4 构建K近邻—回归

​ 利用单一邻居的预测结果就是最近邻的目标值。在使用多个近邻时,预测结果为这些邻居的平均值

用于回归的k 近邻算法在scikit-learn 的KNeighborsRegressor 类中实现。其用法与KNeighborsClassifier 类似:

from sklearn.neighbors import KNeighborsRegressor
reg = KNeighborsRegressor(n_neighbors=3)
print("Test set R^2: {:.2f}".format(reg.score(X_test, y_test))

​ 对于回归问题,score是决定系数R2,是回归模型预测的优度度量,位0到1之间。R2等于1 对应完美预测,R^2 等于0 对应常数模型,即总是预测训练集响应(y_train)的平均值。

1.5 优点、缺点和参数

​ 通常,KNeighbors 分类器有2 个重要参数:邻居个数与数据点之间距离的度量方法。在实践中,使用较小的邻居个数(比如3 个或5 个)往往可以得到比较好的结果。scikit-learn默认使用欧式距离。

  • KNN的优点之一就是模型很容易理解,通常不需要过多调节就可以得到不错的性能

构建最近邻模型的速度通常很快,但如果训练集很大(特征数很多或者样本数很大),预测速度可能会比较慢。

  • 构建最近邻模型的速度通常很快,但如果训练集很大(特征数很多或者样本数大),预测速度可能会比较慢。
  • 对于有很多特征(几百或更多)的数据集往往效果不好,对于大多数特征的大多数取值都0的数据集(所谓的稀疏数据集)来说,这一算法的效果尤其不好。

Tips:虽然k 近邻算法很容易理解,但由于预测速度慢且不能处理具有很多特征的数据集,所以在实践中往往不会用到。而线性模型则没有这两个缺点。

2 线性模型

2.1 线性回归

​ 线性回归或者普通最小二乘法(ordinary least squares,OLS)

​ 均方误差(mean squared error)是预测值与真实值之差的平方和除以样本数。线性回归没有参数,这是一个优点,但也因此无法控制模型的复杂度。

Tips:

  1. 注意到了coef_ 和intercept_ 结尾处奇怪的下划线。scikit-learn总是将从训练数据中得出的值保存在以下划线结尾的属性中。这是为了将其与用户设置的参数区分开。
  2. 训练集和测试集上的分数非常接近(特别是都非常低时)。这说明可能存在欠拟合,而不是过拟合。
  3. 训练集和测试集之间的性能差异是过拟合的明显标志,因此我们应该试图找到一个可以控制复杂度的模型。

2.2 岭回归Ridge

  1. 预测公式与普通最小二乘法相同。(同)
  2. 对系数(w)的选择不仅要在训练数据上得到好的预测结果,而且还要拟合附加约束。(异)
  3. 我们还希望系数尽量小。换句话说,w 的所有元素都应接近于 0。直观上来看,这意味着每个特征对输出的影响应尽可能小(即斜率很小),同时仍给出很好的预测结果。这种约束是所谓正则化(regularization)的一个例子。
  4. 正则化是指对模型做显式约束,以避免过拟合。岭回归用到的这种被称为L2正则化
  5. Ridge 是一种约束更强的模型,所以更不容易过拟合。复杂度更小的模型意味着在训练集上的性能更差,但泛化性能更好。
  6. Ridge 模型在模型的简单性(系数都接近0)与训练集性能之间做出权衡。简单性和训练集性能二者对于模型的重要程度可以由用户通过设置alpha 参数来指定
  7. alpha 的最佳设定值取决于用到的具体数据集。增大alpha 会使得系数更加趋向于0,从而降低训练集性能,但可能会提高泛化性能
  8. 更大的alpha 表示约束更强的模型,所以我们预计大alpha 对应的coef_元素比小alpha 对应的coef_ 元素要小。
Ridge 惩罚了系数的L2 范数或w 的欧式长度。

将模型性能作为数据集大小的函数进行绘图,这样的图像叫作学习曲线??

2.3 Lasso回归

​ 除了Ridge,还有一种正则化的线性回归是Lasso。与岭回归相同,使用lasso 也是约束系数使其接近于0,但用到的方法不同,叫作L1 正则化

​ L1 正则化的结果是,使用lasso 时某些系数刚好为0。这说明某些特征被模型完全忽略。这可以看作是一种自动化的特征选择。某些系数刚好为0,这样模型更容易解释,也可以呈现模型最重要的特征。

​ Lasso 在训练集与测试集上的表现都很差。这表示存在欠拟合,为了降低欠拟合,我们尝试减小alpha。这么做的同时,我们还需要增加max_iter 的值(运行迭代的最大次数)。

​ alpha 值变小,我们可以拟合一个更复杂的模型,在训练集和测试集上的表现也更好。

​ 但如果把alpha 设得太小, 那么就会消除正则化的效果, 并出现过拟合, 得到与LinearRegression 类似的结果。

lasso 惩罚系数向量的L1 范数,换句话说,系数的绝对值之和。

Tips:

在实践中,在两个模型中一般首选岭回归。但如果特征很多,你认为只有其中几个是重要的,那么选择Lasso 可能更好。同样,如果你想要一个容易解释的模型,Lasso 可以给出更容易理解的模型,因为它只选择了一部分输入特征。scikit-learn 还提供了ElasticNet类,结合了Lasso 和Ridge 的惩罚项。在实践中,这种结合的效果最好,不过代价是要调节两个参数:一个用于L1 正则化,一个用于L2 正则化。

2.4 用于分类的线性模型—logistic/SVC

​ 对于用于回归的线性模型,输出ŷ 是特征的线性函数,是直线、平面或超平面(对于更高维的数据集)。

​ 对于用于分类的线性模型,决策边界是输入的线性函数。换句话说,(二元)线性分类器是利用直线、平面或超平面来分开两个类别的分类器。

学习线性模型有很多种算法。这些算法的区别在于以下两点:

• 系数和截距的特定组合对训练数据拟合好坏的度量方法;

• 是否使用正则化,以及使用哪种正则化方法。

​ 不同的算法使用不同的方法来度量“对训练集拟合好坏”。由于数学上的技术原因,不可能调节w 和b 使得算法产生的误分类数量最少。对于我们的目的,以及对于许多应用而言,上面第一点(称为损失函数)的选择并不重要。

​ 最常见的两种线性分类算法是Logistic 回归(logistic regression)线性支持向量机(linearsupport vector machine, 线性SVM)

​ 前者在linear_model.LogisticRegression 中实现,后者在svm.LinearSVC(SVC 代表支持向量分类器)中实现。

​ 两个模型都默认使用L2 正则化,就像Ridge 对回归所做的那样。

scikit-learn中的调用命令是:

from sklearn.linear_model import LogisticRegression

from sklearn.svm import LinearSVC

​ 对于LogisticRegression 和LinearSVC, 决定正则化强度的权衡参数叫作C。C 值越大,对应的正则化越弱。>换句话说,如果参数C 值较大,那么LogisticRegression 和LinearSVC 将尽可能将训练集拟合到最好(模型会更复杂),而如果C 值较小,那么模型更强调使系数向量(w)接近于0。

​ 参数C 的作用还有另一个有趣之处。较小的C 值(对应强正则化)可以让算法尽量适应“大多数”数据点,而较大的C 值(对应弱正则化)更强调每个数据点都分类正确的重要性。

Tips:

  • 若由于训练集和测试集的性能非常接近,所以模型很可能是欠拟合的。我们尝试增大C 来拟合一个更灵活的模型,但也更复杂。
  • 用于二分类的线性模型与用于回归的线性模型有许多相似之处。与用于回归的线性模型一样,模型的主要差别在于penalty 参数,这个参数会影响正则化,也会影响模型是使用所有可用特征还是只选择特征的一个子集。

2.5 用于多分类的线性模型

1、许多线性分类模型只适用于二分类问题,不能轻易推广到多类别问题(除了Logistic 回归)。将二分类算法推广到多分类算法的一种常见方法是“一对其余”(one-vs.-rest)方法

2、在“一对其余”方法中,对每个类别都学习一个二分类模型,将这个类别与所有其他类别尽量分开,这样就生成了与类别个数一样多的二分类模型。在测试点上运行所有二类分类器来进行预测。在对应类别上分数最高的分类器“胜出”,将这个类别标签返回作为预测结果。

3、多分类Logistic 回归背后的数学与“一对其余”方法稍有不同,但它也是对每个类别都有一个系数向量和一个截距,也使用了相同的预测方法。

2.6 优点、缺点、参数

  • 线性模型的主要参数是正则化参数,在回归模型中叫作alpha;在LinearSVC 和Logistic-Regression 分类模型中中叫作C。

  • alpha 值较大或C 值较小,说明模型比较简单。特别是对于回归模型而言,调节这些参数非常重要。通常在对数尺度上对C 和alpha 进行搜索。

  • 还需要确定的是用L1 正则化还是L2 正则化。

    • 如果你假定只有几个特征是真正重要的,那么你应该用L1 正则化,否则应默认使用L2 正则化。
    • 如果模型的可解释性很重要的话,使用L1 也会有帮助。由于L1 只用到几个特征,所以更容易解释哪些特征对模型是重要的,以及这些特征的作用。
  • 线性模型的训练速度非常快,预测速度也很块。这种模型可以推广到非常大的数据集,对稀疏数据也很有效。

疑问:

​ 如果特征数量大于样本数量,线性模型的表现通常都很好。它也常用于非常大的数据集,只是因为训练其他模型并不可行。但在更低维的空间中,其他模型的泛化性能可能更好。

3 朴素贝叶斯分类器

3.1 特点

  • 与线性模型非常相似的一种分类器,但它的训练速度往往更快。
  • 泛化能力要比线性分类器稍差。
  • 通过单独查看每个特征来学习参数,并从每个特征中收集简单的类别统计数据。这也是其高效的原因。

3.2 实现

scikit-learn 中有三种实现的分类器:GaussianNB、BernoulliNB、MultinomialNB

  • GaussianNB 可应用于任意连续数据,主要用于高维数据

  • BernoulliNB 假定输入数据为二分类数据,广泛用于稀疏计数数据

  • MultinomialNB 假定输入数据为计数数据(即每个特征代表某个对象的整数计数,比如一个单词在句子里出现的次数),广泛用于稀疏计数数据

BernoulliNB 和MultinomialNB 主要用于文本数据分类。

3.3 特征计算方式

  • BernoulliNB 分类器计算每个类别中每个特征不为0 的元素个数

  • MultinomialNB 计算每个类别中每个特征的平均值

  • GaussianNB 会保存每个类别中每个特征的平均值和标准差

  • 要想做出预测,需要将数据点与每个类别的统计数据进行比较,并将最匹配的类别作为预测结果。

  • MultinomialNB 和BernoulliNB 预测公式的形式都与线性模型完全相同,但是朴素贝叶斯模型coef_ 的含义与线性模型稍有不同,因为coef_不同于w。

3.4 优点、缺点和参数

参数:

  • MultinomialNB 和BernoulliNB 都只有一个参数alpha,用于控制模型复杂度。

  • alpha 的工作原理:算法向数据中添加alpha 这么多的虚拟数据点,这些点对所有特征都取正值。这可以将统计数据“平滑化”(smoothing)

  • 特点:alpha 越大,平滑化越强,模型复杂度就越低。算法性能对alpha 值的鲁棒性相对较好,也就是说,alpha 值对模型性能并不重要。但调整这个参数通常都会使精度略有提高。

  • GaussianNB 主要用于高维数据,而另外两种朴素贝叶斯模型则广泛用于稀疏计数数据,比如文本。

  • MultinomialNB 的性能通常要优于BernoulliNB,特别是在包含很多非零特征的数据集(即大型文档)上。

优缺点:

朴素贝叶斯模型的许多优点和缺点都与线性模型相同。

  • 训练和预测速度都很快,训练过程也很容易理解。
  • 对高维稀疏数据的效果很好,对参数的鲁棒性也相对较好。
  • 朴素贝叶斯模型是很好的基准模型,常用于非常大的数据集,在这些数据集上即使训练线性模型可能也要花费大量时间。

4 决策树

广泛用于分类和回归任务的模型。本质上,它从一层层的if/else 问题中进行学习,并得出结论。

4.1 构造决策树

顶节点(根节点)、叶节点

4.2 控制决策树的复杂度

​ 通常来说,构造决策树直到所有叶结点都是纯的叶结点,这会导致模型非常复杂,并且对训练数据高度过拟合。纯叶结点的存在说明这棵树在训练集上的精度是100%。

  • 防止过拟合有两种常见的策略:

  • 预剪枝(pre-pruning):及早停止树的生长

  • 后剪枝(post-pruning)或剪枝(pruning):先构造树,但随后删除或折叠信息量很少的结点

​ 预剪枝的限制条件可能包括限制树的最大深度、限制叶结点的最大数目,或者规定一个结点中数据点的最小数目来防止继续划分。

Tips:

​ scikit-learn 的决策树在DecisionTreeRegressor 类DecisionTreeClassifier 类中实现。

scikit-learn 只实现了预剪枝,没有实现后剪枝。

4.3 分析决策树

​ 可以利用tree 模块的export_graphviz 函数来将树可视化。这个函数会生成一个.dot 格式的文件,这是一种用于保存图形的文本文件格式。我们设置为结点添加颜色的选项,颜色表示每个结点中的多数类别,同时传入类别名称和特征名称,这样可以对树正确标记。

​ 树的可视化有助于深入理解算法是如何进行预测的,也是易于向非专家解释的机器学习算法的优秀示例。

4.4 树的特征重要性

​ 由于查看整个树可能非常费劲,所以可以利用一些有用的属性来总结树的工作原理。

​ 最常用的是特征重要性(feature importance),它为每个特征对树的决策的重要性进行排序。对于每个特征来说,它都是一个介于0 和1 之间的数字,其中0 表示“根本没用到”,1 表示“完美预测目标值”。特征重要性的求和始终为1:

​ 但是如果某个特征的feature_importance_ 很小,并不能说明这个特征没有提供任何信息。这只能说明该特征没有被树选中,可能是因为另一个特征也包含了同样的信息。

​ 与线性模型的系数不同,特征重要性始终为正数,也不能说明该特征对应哪个类别。

​ 对用于回归的决策树来说,所有内容都是与用于分类的决策树类似的,在DecisionTreeRegressor 中实现。回归树的用法和分析与分类树非常类似。但在将基于树的模型用于回归时DecisionTreeRegressor(以及其他所有基于树的回归模型)不能外推(extrapolate),也不能在训练数据范围之外进行预测。

4.5 优点、缺点和参数

参数:

​ 控制决策树模型复杂度的参数是预剪枝参数,它在树完全展开之前停止树的构造。通常来说,选择一种预剪枝策略(设置max_depth、max_leaf_nodes 或min_samples_leaf)足以防止过拟合。

两个优点:

  • 得到的模型很容易可视化,非专家也很容易理解(至少对于较小的树而言)
  • 算法完全不受数据缩放的影响。
    • 由于每个特征被单独处理,而且数据的划分也不依赖于缩放,因此决策树算法不需要特征预处理,比如归一化或标准化。特别是特征的尺度完全不一样时或者二元特征和连续特征同时存在时,决策树的效果很好

缺点:

​ 即使做了预剪枝,它也经常会过拟合,泛化性能很差。因此,在大多数应用中,往往使用集成学习来替代单棵决策树。

5 决策树集成

​ 集成(ensemble)是合并多个机器学习模型来构建更强大模型的方法。在机器学习文献中有许多模型都属于这一类,但已证明有两种集成模型对大量分类和回归的数据集都是有效的,二者都以决策树为基础,分别是随机森林(random forest)和梯度提升决策树(gradient boosted decision tree)。

5.1 随机森林

​ 决策树的一个主要缺点是经常对训练数据过拟合。随机森林是解决这个问题的一种方法。随机森林的名字来自于将随机性添加到树的构造过程中,以确保每棵树都各不相同

本质:

​ 许多决策树的集合,其中每棵树都和其他树略有不同。

思想:

​ 每棵树的预测可能都相对较好,但可能对部分数据过拟合。需要构造很多树,并且每棵树的预测都很好(对目标值做出可以接受的预测),并且预测结果应该与其他树不同,但都以不同的方式过拟合,那么我们可以对这些树的结果取平均值来降低过拟合。既能减少过拟合又能保持树的预测能力,这可以在数学上严格证明。

关键点:

​ 随机森林需要将随机性添加到树的构造过程中,以确保每棵树都各不相同。

随机化有两种方式:
  • 通过选择用于构造树的数据点(自助采样)
  • 通过选择每次划分测试的特征(设置max_features参数)

​ 由于使用了自助采样,随机森林中构造每棵决策树的数据集都是略有不同的。由于每个结点的特征选择,每棵树中的每次划分都是基于特征的不同子集。这两种方法共同保证随机森林中所有树都不相同

构造随机森林的过程

​ 首先需要知道什么是自助采样( bootstrap sample),从n_samples 个数据点中有放回地(即同一样本可以被多次抽取)重复随机抽取一个样本,共抽取n_samples 次。这样会创建一个与原数据集大小相同的数据集,但有些数据点会缺失(大约三分之一),有些会重复。比如我们想要创建列表[‘a’, ‘b’, ‘c’, ‘d’] 的自助采样。一种可能的自主采样是[‘b’, ‘d’, ‘d’, ‘c’],另一种可能的采样为[‘d’, ‘a’, ‘d’, ‘a’]。

  • 确定用于构造的树的个数

    • RandomForestRegressor 或 RandomForestClassifier 的 n_estimators 参数
    • 这些树在构造时彼此完全独立,算法对每棵树进行不同的随机选择,以确保树和树之间是有区别的
  • 自助采样,通过采样获得新的数据集

  • 基于这个新创建的数据集来构造决策树

    • 这里与决策树稍有不同,在每个结点处,算法随机选择特征的一个子集,并对其中一个特征寻找最佳测试,而不是对每个结点都寻找最佳测试。选择的特征个数由max_features 参数来控制。每个结点中特征子集的选择是相互独立的,这样树的每个结点可以使用特征的不同子集来做出决策。
  • 分析随机森林

参数:

  • 需要调节的重要参数有n_estimators 和max_features,可能还包括预剪枝选项(如max_depth)。

  • n_estimators 总是越大越好。对更多的树取平均可以降低过拟合,从而得到鲁棒性更好的集成。不过收益是递减的,而且树越多需要的内存也越多,训练时间也越长。常用的经验法则就是“在你的时间/ 内存允许的情况下尽量多”。

  • 如果我们设置max_features 等于n_features,那么每次划分都要考虑数据集的所有特征,在特征选择的过程中没有添加随机性(不过自助采样依然存在随机性)。

  • 如果设置max_features 等于1,那么在划分时将无法选择对哪个特征进行测试,只能对随机选择的某个特征搜索不同的阈值。

  • 因此,如果max_features 较大,那么随机森林中的树将会分相似,利用最独特的特征可以轻松拟合数据。如果max_features 较小,那么随机森林中的树将会差异很大,为了很好地拟合数据,每棵树的深度都要很大。

  • max_features 决定每棵树的随机性大小,较小的max_features 可以降低过拟合

  • 一般来说,好的经验就是使用默认值:对于分类,默认值是max_features=sqrt(n_features); 对于回归, 默认值是max_features=n_features。

  • 增大max_features 或max_leaf_nodes 有时也可以提高性能。它还可以大大降低用于训练和预测的时间和空间要求。

优缺点:

  • 用于回归和分类的随机森林是目前应用最广泛的机器学习方法之一。这种方法非常强大,通常不需要反复调节参数就可以给出很好的结果,也不需要对数据进行缩放。
  • 从本质上看,随机森林拥有决策树的所有优点,同时弥补了决策树的一些缺陷。
  • 如果你用的是多核处理器(几乎所有的现代化计算机都是),你可以用n_jobs 参数来调节使用的内核个数。
  • 但设置n_jobs 大于内核个数是没有用的。你可以设置n_jobs=-1 来使用计算机的所有内核。
  • 森林中的树越多,它对随机状态选择的鲁棒性就越好。
  • 如果你希望结果可以重现,固定random_state 是很重要的**。**
  • 对于维度非常高的稀疏数据(比如文本数据),随机森林的表现往往不是很好**。**对于这种数据,使用线性模型可能更合适。即使是非常大的数据集,随机森林的表现通常也很好。
  • 随机森林需要更大的内存,训练和预测的速度也比线性模型要慢。对一个应用来说,如果时间和内存很重要的话,那么换用线性模型可能更为明智。

应用:

​ 想要利用随机森林进行预测,算法首先对森林中的每棵树进行预测。

对于回归问题,我们可以对这些结果取平均值作为最终预测。

对于分类问题,则用到了“软投票”(soft voting)策略。也就是说,每个算法做出“软”预测,给出每个可能的输出标签的概率。对所有树的预测概率取平均值,然后将概率最大的类别作为预测结果。

5.2 梯度提升回归树(梯度提升机)

可用于回归、分类

​ 与随机森林方法不同,梯度提升采用连续的方式构造树,每棵树都试图纠正前一棵树的错误。默认情况下,梯度提升回归树中没有随机化,而是用到了强预剪枝。梯度提升树通常使用深度很小(1到5 之间)的树,这样模型占用的内存更少,预测速度也更快。

主要思想:

​ 合并许多简单的模型(在这个语境中叫作弱学习器),比如深度较小的树。每棵树只能对部分数据做出好的预测,因此,添加的树越来越多,可以不断迭代提高性能。

参数:4个

  • 预剪枝
  • n_estimators:集成中树的数量,n_estimators 值总是越大越好,但梯度提升不同,增大n_estimators 会导致模型更加复杂,模型有更多机会纠正训练集上的错误,进而可能导致过拟合。
  • learning_rate:学习率,用于控制每棵树纠正前一棵树的错误的强度。较高的学习率意味着每棵树都可以做出较强的修正,这样模型更为复杂。降低学习率仅稍稍提高了泛化性能。
  • 通常的做法是根据时间和内存的预算选择合适的n_estimators,然后对不同learning_rate 进行遍历。
  • max_depth(或max_leaf_nodes),用于降低每棵树的复杂度。梯度提升模型的max_depth 通常都设置得很小,一般不超过5。

优点和缺点:

  • 梯度提升树经常是机器学习竞赛的优胜者,并且广泛应用于业界。与随机森林相比,它通常对参数设置更为敏感,但如果参数设置正确的话,模型精度更高。
  • 梯度提升决策树是监督学习中最强大也最常用的模型之一
  • 主要缺点是需要仔细调参,而且训练时间可能会比较长
  • 与其他基于树的模型类似,这一算法不需要对数据进行缩放就可以表现得很好,而且也适用于二元特征与连续特征同时存在的数据集
  • 与其他基于树的模型相同,它也通常不适用于高维稀疏数据。

6 核支持向量机

kernelized support vector machine,简称SVM,是线性支持向量机的推广。可以推广到更复杂模型的扩展,这些模型无法被输入空间的超平面定义。

分类在SVC 中实现,回归在SVR 中实现。

6.1 线性模型与非线性特征

​ 线性模型在低维空间中可能非常受限,因为线和平面的灵活性有限。有一种方法可以让线性模型更加灵活,就是添加更多的特征——如,添加输入特征的交互项或多项式。

6.2 核技巧

​ 向数据表示中添加非线性特征,可以让线性模型变得更强大。但是,通常来说我们并不知道要添加哪些特征,而且添加许多特征的计算开销可能会很大。因此,我们可以通过一种巧妙的数学技巧,让我们可以在更高维空间中学习分类器,而不用实际计算可能非常大的新的数据表示。这种技巧叫作核技巧(kernel trick)——它的原理是直接计算扩展特征表示中数据点之间的距离(更准确地说是内积),而不用实际对扩展进行计算。通过核技巧,可以将数据映射到更高维空间中。

​ 两种常用的核技巧:一种是多项式核,在一定阶数内计算原始特征所有可能的多项式(比如feature1 ** 2 * feature2 ** 5);另一种是径向基函数(radial basis function,RBF)核,也叫高斯核。高斯核有点难以解释,因为它对应无限维的特征空间。一种对高斯核的解释是它考虑所有阶数的所有可能的多项式,但遵循指数映射的泰勒展开,所以阶数越高,特征的重要性越小。

6.3 对SVM的理解

​ 支持向量(support vector):位于类别之间边界上的那些点,这部分部分训练数据点对于定义决策边界来说很重要。

​ 想要对新样本点进行预测,需要测量它与每个支持向量之间的距离。分类决策是基于它与支持向量之间的距离以及在训练过程中学到的支持向量重要性(保存在SVC 的dual_coef_属性中)来做出的。

数据点之间的距离由高斯核给出:

img

6.4 SVM调参

  • gamma参数:控制高斯核的宽度,决定了点与点之间“靠近”是指多大的距离。gamma 较小,说明高斯核的半径较大,许多点都被看作比较靠近。小的gamma 值表示决策边界变化很慢,生成的是复杂度较低的模型,而大的gamma 值则会生成更为复杂的模型。
  • C参数:正则化参数,与线性模型中用到的类似。它限制每个点的重要性(或者更确切地说,每个点的dual_coef_)。与线性模型相同,C 值很小,说明模型非常受限,每个数据点的影响范围都有限。
  • 增大C 或gamma 可以拟合出更为复杂的模型,两个参数的设定通常是强烈相关的,应该同时调节。分类时默认情况下,C=1,gamma=1/n_features
  • 核SVM 的重要参数是正则化参数C、核的选择以及与核相关的参数。
  • scikit-learn中有很多核函数

6.5 数据预处理

​ 虽然SVM 的表现通常都很好,但它对参数的设定和数据的缩放非常敏感。它要求所有特征有相似的变化范围。解决这个问题的一种方法就是对每个特征进行缩放,使其大致都位于同一范围。常用的缩放方法就是将所有特征缩放到0 和1 之间。使用MinMaxScaler 预处理方法来做到。当然也可以手工完成。

# 计算训练集中每个特征的最小值
min_on_training = X_train.min(axis=0)
# 计算训练集中每个特征的范围(最大值-最小值)
range_on_training = (X_train - min_on_training).max(axis=0)
# 减去最小值,然后除以范围
# 这样每个特征都是min=0和max=1
X_train_scaled = (X_train - min_on_training)/range_on_training
# 利用训练集的最小值和范围对测试集做相同的变换
X_test_scaled = (X_test - min_on_training) / range_on_training

6.6 优点、缺点

  • 核支持向量机是非常强大的模型,在各种数据集上的表现都很好。SVM 允许决策边界很复杂,即使数据只有几个特征。它在低维数据和高维数据(即很少特征和很多特征)上的表现都很好。
  • 对样本个数的缩放表现不好。
  • 预处理数据和调参都需要非常小心。如今很多应用中用的都是基于树的模型,比如随机森林或梯度提升(需要很少的预处理,甚至不需要预处理)
  • SVM 模型很难检查,可能很难理解为什么会这么预测,而且也难以将模型向非专家进行解释。
  • 当所有特征的测量单位相似(比如都是像素密度)而且范围也差不多时,使用SVM一般可以取得较好的效果。

7 神经网络

多层感知机(multilayer perceptron,MLP):可用于分类和回归,可以作为研究更复杂的深度学习方法的起点。MLP 也被称为(普通)前馈神经网络,有时也简称为神经网络。

7.1 简单神经网络模型

​ MLP 可以被视为广义的线性模型执行多层处理后得到结论。

线性回归的预测公式:
img

将该公式可视化为:

img

​ 上图中,左边的每个结点代表一个输入特征,连线代表学到的系数,右边的结点代表输出,是输入的加权求和。

​ 在MLP 中,多次重复这个计算加权求和的过程,首先计算代表中间过程的隐单元(hidden unit),然后再计算这些隐单元的加权求和并得到最终结果如下,即单隐层的多层感知机。

img

​ 这个模型需要学习更多的系数(也叫作权重):在每个输入与每个隐单元(隐单元组成了隐层)之间有一个系数,在每个隐单元与输出之间也有一个系数。

从数学的角度看,计算一系列加权求和与只计算一个加权求和是完全相同的,那么如何让这个模型真正比线性模型更为强大?

答案就是:在计算完每个隐单元的加权求和之后,对结果再应用一个非线性函数——通常是校正非线性(rectifying nonlinearity,也叫校正线性单元或ReLu)、正切双曲(tangens hyperbolicus,tanh)。然后将这个非线性函数的结果用于加权求和,计算得到输出ŷ。

​ ReLu 截断小于0 的值,而tanh 在输入值较小时接近-1,在输入值较大时接近+1。有了这两种非线性函数,神经网络可以学习比线性模型复杂得多的函数。

img

​ 对于上述单隐层的多层感知机,使用tanh 非线性计算回归问题的ŷ 的完整公式如下:

img

​ where,w 是输入x 与隐层h 之间的权重,v 是隐层h 与输出ŷ 之间的权重。权重w 和v 要从数据中学习得到,x 是输入特征,ŷ 是计算得到的输出,h 是计算的中间结果。

  • 需要用户设置的一个重要参数是隐层中的结点个数。对于非常小或非常简单的数据集,这个值可以小到10;对于非常复杂的数据,这个值可以大10 000。同时也可以添加多个隐含层,深层的网络也就是这样一层一层添加的(此部分属于深度学习的内容)。

7.2 神经网络构建和调参

​ 使用如下命令可以从scikit-learn框架中调用MLP分类器。

from sklearn.neural_network import MLPClassifier 
# optional表示可选参数,
mlp = MLPClassifier(solver='optional', activation='optional',
                    random_state=0,hidden_layer_sizes=size_num)
mlp.fit(X_train, y_train)

​ 控制神经网络复杂度的方法有很多种,例如:隐层的个数、每个隐层中的单元个数与正则化(alpha)等等。

隐层个数、单元个数:默认情况下,MLP使用100个隐结点,这对于这个小型数据集来说已经相当多了。可以减少隐结点数量,从而降低模型复杂度。神经网络学到的决策边界完全是非线性的,但相对平滑。如果想得到更加平滑的决策边界,可以添加更多的隐单元、添加多个隐层或者使用tanh非线性函数。

非线性函数:如果单隐层模型使用ReLU函数,那么决策函数可看作是由若干个个直线段组成的。使用tanh非线性函数可得到更加平滑的决策边界。

正则化(alpha)参数:我们还可以利L2惩罚使权重趋向0,从而控制神经网络的复杂度,类似于岭回归和线性分类器。MLPClassifier 中调节L2 惩罚的参数是alpha(与线性回归模型中的相同),它的默认值很小(弱正则化)。增大alpha 参数(调参时变化范围要相当大,如从0.0001 到1),以此向权重添加更强的正则化,以降低模型复杂度来得到更好的泛化性能。

随机化的权重:另外一个需要注意的地方就是,在开始学习之前其权重是随机设置的,这种随机初始化会影响学到的模型。即使使用完全相同的参数,如果随机种子不同的话,我们也可能得到非常不一样的模型。如果网络很大,并且复杂度选择合理的话,那么这应该不会对精度有太大影响,但对于较小的网络应该特别注意这一点。另外,权重可以通过优化算法训练得到,如遗传算法、模拟退火等。

​ 神经网络也要求所有输入特征的变化范围相似,最理想的情况是均值0、方差为1。我们必须对数据进行缩放以满足这些要求。使用 StandardScaler 可以自动完成,当然也可以手工完成。

# 计算训练集中每个特征的平均值
mean_on_train = X_train.mean(axis=0)
# 计算训练集中每个特征的标准差
std_on_train = X_train.std(axis=0)
# 减去平均值,然后乘以标准差的倒数
# 如此运算之后,mean=0,std=1
X_train_scaled = (X_train - mean_on_train) / std_on_train
# 对测试集做相同的变换(使用训练集的平均值和标准差)
X_test_scaled = (X_test - mean_on_train) / std_on_train

常见的库:

  • scikit-learn:MLPClassifier 和MLPRegressor,只包含神经网络潜在应用的一部分
  • keras:既可以用tensor-flow 也可以用theano。
  • lasagna:基于theano 库构建的
  • tensor-flow:谷歌的深度学习框架

​ 这些库提供了更为灵活的接口,可以用来构建神经网络并跟踪深度学习研究的快速发展。所有流行的深度学习库也都允许使用高性能的图形处理单元(GPU),而scikit-learn 不支持GPU。使用GPU 可以将计算速度加快10 到100倍。

神经网络调参的常用方法:

  • 神经网络调参本身也是一门艺术。调节神经网络模型和训练模型的方法有很多种。
  • 神经网络调参的常用方法是,首先创建一个大到足以过拟合的网络,确保这个网络可以对任务进行学习。知道训练数据可以被学习之后,要么缩小网络,要么增大alpha 来增强正则化,这可以提高泛化性能。
  • 在我们的实验中,主要关注模型的定义:层数、每层的结点个数、正则化和非线性。这些内容定义了我们想要学习的模型。

选择如何学习模型或用来学习参数的算法:

​ 这一点的选择是由solver 参数设定的。solver 有三个选项:‘adam’,‘lbfgs’,‘sgd’

  • ‘adam’:默认选项,在大多数情况下效果都很好,但对数据的缩放相当敏感(因此,始终将数据缩放为均值为0、方差为1 是很重要的)。
  • ‘lbfgs’:其鲁棒性相当好,但在大型模型或大型数据集上的时间会比较长。
  • ‘sgd’ :更高级的一个选项,许多深度学习研究人员都会用到。'sgd’选项还有许多其他参数需要调节,以便获得最佳结果。

​ 可以在用户指南中找到所有这些参数及其定义。建议初学者用’adam’ 和’lbfgs’

7.3 优点、缺点

  • 分析困难:虽然可以分析神经网络学到了什么,但这通常比分析线性模型或基于树的模型更为复杂。要想观察模型学到了什么,一种方法是查看模型的权重(权重可视化),见scikit-learn示例库。
  • 能够获取大量数据中包含的信息,并构建无比复杂的模型。
  • 给定足够的计算时间和数据,并且仔细调节参数,神经网络通常可以打败其他机器学习算法(无论是分类任务还是回归任务)。
  • 神经网络——特别是功能强大的大型神经网络——通常需要很长的训练时间
  • 需要仔细地预处理数。与SVM 类似,神经网络在“均匀”数据上的性能最好,其中“均匀”是指所有特征都具有相似的含义,。如果数据包含不同种类的特征,那么基于树的模型可能表现得更好。

8 监督学习模型的选择原则

最近邻:

​ 适用于小型数据集,是很好的基准模型,很容易解释。对稀疏数据集不好。

线性模型:

​ 非常可靠的首选算法,适用于非常大的数据集,也适用于高维数据。需要缩放。

朴素贝叶斯:

​ 只适用于分类问题。比线性模型速度还快,适用于非常大的数据集和高维数据。精度通常要低于线性模型。

决策树:

​ 速度很快,不需要数据缩放,可以可视化,很容易解释。

随机森林:

​ 几乎总是比单棵决策树的表现要好,鲁棒性很好,非常强大。不需要数据缩放。不适用于高维稀疏数据。

梯度提升决策树:

​ 精度通常比随机森林略高。与随机森林相比,训练速度更慢,但预测速度更快,需要的内存也更少。比随机森林需要更多的参数调节。

支持向量机:

​ 对于特征含义相似的中等大小的数据集很强大。需要数据缩放,对参数敏感。

神经网络:

​ 可以构建非常复杂的模型,特别是对于大型数据集而言。对数据缩放敏感,对参数选取敏感。大型网络需要很长的训练时间。

Tips:

含不同种类的特征,那么基于树的模型可能表现得更好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章