机器学习系列专栏
选自 Python-Machine-Learning-Book On GitHub
作者:Sebastian Raschka
翻译&整理 By Sam
这篇是《教你用Scikit-Learn来做分类器》的结尾了,整个系列有3篇文章,每一篇文章专攻一个难点,方便大家利用碎片化的时间来给自己充电?!
上篇:
上篇传说门:Machine Learning-教你用Scikit-Learn来做分类器(上)
中篇:
上篇传说门:Machine Learning-教你用Scikit-Learn来做分类器(中)
下篇:(新增)
PS:代码已单独保存:可在公众号后台输入“sklearn”进行获取ipynb文件
机器学习决策树模型
关于决策树模型的定义解释这边就不说明了,该算法的框架表述还是比较清晰的,从根节点开始不断得分治,递归,生长,直至得到最后的结果。根节点代表整个训练样本集,通过在每个节点对某个属性的测试验证,算法递归得将数据集分成更小的数据集.某一节点对应的子树对应着原数据集中满足某一属性测试的部分数据集.这个递归过程一直进行下去,直到某一节点对应的子树对应的数据集都属于同一个类为止。
图:决策数模型过程
基于训练集中的特征,决策树模型提出了一系列问题来推测样本的类别。虽然上图中做出的每个决策都是根据离散变量,但也可以用于连续型变量,比如,对于Iris中sepal width这一取值为实数的特征,我们可以问“sepal width是否大于2.8cm?”
训练决策树模型时,我们从根节点出发,使用信息增益(information gain, IG)最大的特征对数据分割。然后迭代此过程。显然,决策树的生成是一个递归过程,在决策树基本算法中,有三种情形会导致递归返回:
(1)当前节点包含的样本全属于同一类别,无需划分;
(2)当前属性集为空,或是所有样本在所有属性上取值相同,无法划分;
(3)当前节点包含的样本集合为空,不能划分。
每一个节点的样本都属于同一个类,同时这也可能导致树的深度很大,节点很多,很容易引起过拟合。因此,剪枝操作是必不可少的,来控制树深度。
最大化信息增益-获得最大的提升度
关于对信息、熵、信息增益是信息论里的概念,是对数据处理的量化,这几个概念主要是在决策树里用到的概念,因为在利用特征来分类的时候会对特征选取顺序的选择,这几个概念比较抽象。
信息增益( ID3算法 )定义:
以某特征划分数据集前后的熵的差值。熵表示样本集合的不确定性,熵越大,样本的不确定性就越大。因此可以使用划分前后集合熵的差值来衡量使用当前特征对于样本集合D划分效果的好坏。
此外,还有信息增益比( C4.5算法 ),基尼指数等算法,大家可以去阅读一下参考文献3的文章。
建立决策树
上面讲了这么多原理,还是要放一些code来给大家学习一下。决策树通过将特征空间分割为矩形,所以其决策界很复杂。但是要知道过大的树深度会导致过拟合,所以决策界并不是越复杂越好。我们调用sklearn,使用熵作为度量,训练一颗最大深度为3的决策树,代码如下:
1from sklearn.tree import DecisionTreeClassifier
2tree = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=0)
3tree.fit(X_train, y_train)
4X_combined = np.vstack((X_train, X_test))
5y_combined = np.hstack((y_train, y_test))
6plot_decision_regions(X_combined, y_combined,
7 classifier=tree, test_idx=range(105, 150))
8plt.xlabel('petal length [cm]')
9plt.ylabel('petal width [cm]')
10plt.legend(loc='upper left')
11plt.tight_layout()
12plt.show()
output:
可以看出,这个决策树将数据划分成了三类,不同的颜色代表着一类,此外,sklearn的一大优点是可以将训练好的决策树模型输出,保存在.dot文件。
1from sklearn.tree import export_graphviz
2export_graphviz(tree, out_file='tree.dot', feature_names=['petal length', 'petal width'])
通过随机森林将“弱者”与“强者”模型集成
随机森林一直是广受欢迎的模型,优点很多:优秀的分类表现、扩展性和使用简单。随机森林的思想也不复杂,一个随机森林模型就是多颗决策树的集成。集成学习(ensemble learning)的观点是将多个弱分类器结合来构建一个强分类器,它的泛化误差小且不易过拟合。
随机森林算法大致分为4个步骤:
直接调用sklearn来看一下随机森林吧。
1from sklearn.ensemble import RandomForestClassifier
2forest = RandomForestClassifier(criterion='entropy',
3 n_estimators=10,
4 random_state=1,
5 n_jobs=2)
6forest.fit(X_train, y_train)
7plot_decision_regions(X_combined, y_combined,
8 classifier=forest, test_idx=range(105, 150))
9plt.xlabel('petal length [cm]')
10plt.ylabel('petal width [cm]')
11plt.legend(loc='upper left')
12plt.tight_layout()
13plt.show()
output:
K近邻分类模型(一个懒惰的算法)
本系列最后一个监督学习算法是k紧邻算法(k-nearest neighbor classifier, KNN), 这个算法很有意思,因为他背后的思想和本章其他算法完全不同。
KNN是懒惰学习的一个典型示例。之所以称为“懒惰”并不是由于此类算法看起来很简单,而是在训练模型过程中这类算法并不去学习一个判别式函数(损失函数)而是要记住整个训练集。
这里引入一个概念:参数模型VS变参模型
机器学习算法可以被分为两大类:参数模型和变参模型。
对于参数模型,在训练过程中我们要学习一个函数,重点是估计函数的参数,然后对于新数据集,我们直接用学习到的函数对齐分类。典型的参数模型包括感知机、逻辑斯蒂回归和线性SVM。
对于变参模型,其参数个数不是固定的,它的参数个数随着训练集增大而增多!很多书中变参(nonparametric)被翻译为无参模型,一定要记住,不是没有参数,而是参数个数是变量!变参模型的两个典型示例是决策树/随机森林和核SVM。
KNN属于变参模型的一个子类:基于实例的学习(instance-based learning)。基于实例的学习的模型在训练过程中要做的是记住整个训练集,而懒惰学习是基于实例的学习的特例,在整个学习过程中不涉及损失函数的概念。
KNN算法本身非常简单,步骤如下:
对每一个测试样本,基于事先选择的距离度量,KNN算法在训练集中找到距离最近(最相似)的k个样本,然后将k个样本的类别的投票结果作为测试样本的类别。
像KNN这种基于内存的方法一大优点是:一旦训练集增加了新数据,模型能立刻改变。另一方面,缺点是分类时的最坏计算复杂度随着训练集增大而线性增加,除非特征维度非常低并且算法用诸如KD-树等数据结构实现。此外,我们要一直保存着训练集,不像参数模型训练好模型后,可以丢弃训练集。因此,存储空间也成为了KNN处理大数据的一个瓶颈。
下面我们调用sklearn训练一个KNN模型:
1from sklearn.neighbors import KNeighborsClassifier
2knn = KNeighborsClassifier(n_neighbors=5, p=2, metric='minkowski')
3knn.fit(X_train_std, y_train)
4plot_decision_regions(X_combined_std, y_combined,
5 classifier=knn, test_idx=range(105, 150))
6plt.xlabel('petal length [standardized]')
7plt.ylabel('petal width [standardized]')
8plt.legend(loc='upper left')
9plt.tight_layout()
10plt.show()
output:
参考文献
1)信息熵(Entropy)、信息增益(Information Gain)
https://www.cnblogs.com/liyuxia713/archive/2012/11/02/2749375.html
2)[机器学习]信息&熵&信息增益
https://www.cnblogs.com/fantasy01/p/4581803.html
3)决策树--信息增益,信息增益比,Geni指数的理解
https://www.cnblogs.com/muzixi/p/6566803.html
—End—