在数据挖掘的过程中,我们经常会遇到一些问题,比如:
如何选择各种分类器,到底选择哪个分类算法,是 SVM,决策树,还是 KNN?如何优化分类器
的参数,以便得到更好的分类准确率?
这两个问题,是数据挖掘核心的问题。
本篇文章主要围绕着解决以下3个问题,分别是:

  1. 创建各种分类器,包括已经掌握的 SVM、决策树、KNN 分类器,以及随机森林分类器;
  2. 掌握 GridSearchCV 工具,优化算法模型的参数;
  3. 使用 Pipeline 管道机制进行流水线作业。因为在做分类之前,我们还需要一些准备过程,比
    如数据规范化,或者数据降维等

构建随机森林分类器

在算法篇中,前面的文章介绍了数据挖掘十大经典算法。实际工作中,经常会用到随机森林。
随机森林的英文是 Random Forest,英文简写是 RF。它实际上是一个包含多个决策树的分类
器,每一个子分类器都是一棵 CART 分类回归树。所以随机森林既可以做分类,又可以做回归。
当它做分类的时候,输出结果是每个子分类器的分类结果中最多的那个。你可以理解是每个分类
器都做投票,取投票最多的那个结果。当它做回归的时候,输出结果是每棵 CART 树的回归结果
的平均值。
在 sklearn 中,我们使用 RandomForestClassifier() 构造随机森林模型,函数里有一些常用的构
造参数:

n_estimators 随机森林里决策树的个数,默认是10
criterion 决策树分裂的标准,默认是基尼系数(CART算法),也可以选择entropy(ID3算法)
max_depth 决策树的最大深度,默认是None,也就是不限制决策树的深度,也可以设置一个整数,限制决策树的最大深度
n_jobs 拟合和预测的时候CPU的核数,默认是1,也可以是整数,如果是-1则代表CPU的核数

构造好分类器后,就可以使用 fit 函数拟合,使用 predict 函数预测。

使用 GridSearchCV 工具对模型参数进行调优

在做分类算法的时候,我们需要经常调节网络参数(对应上面的构造参数),目的是得到更好的分类结果。实际上一个分类算法有很多参数,取值范围也比较广,那么该如何调优呢?
Python 给我们提供了一个很好用的工具 GridSearchCV,它是 Python 的参数自动搜索模块。我们只要告诉它想要调优的参数有哪些以及参数的取值范围,它就会把所有的情况都跑一遍,然后告诉我们哪个参数是最优的,结果如何。
使用 GridSearchCV 模块需要先引用工具包,方法如下:

1
from sklearn.model_selection import GridSearchCV

然后我们使用 GridSearchCV(estimator, param_grid, cv=None, scoring=None) 构造参数的自动搜索模块,这里有一些主要的参数需要说明下:

estimator 代表我们想要的分类器,比如随机森林、决策树、SVM、KNN等
param_grid 代表我们想要优化的参数及取值,输入的是字典或者列表的形式
cv 交叉验证的折数,默认为None,代表使用三折交叉验证。也可以为整数,代表的是交叉验证的折数
scoring 准确度的评价准则,默认为None,也就是需要使用score函数。也可以设置具体的评价标准,比如accuracy,F1等

这里举一个简单的例子,我们用 sklearn 自带的 IRIS 数据集,采用随机森林对 IRIS 数据分类。假设我们想知道 n_estimators 在 1-10 的范围内取哪个值的分类结果最好,可以编写代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris
rf = RandomForestClassifier()
parameters={"n_estimators":range(1,11)}
iris = load_iris()
print(iris.keys())
clf = GridSearchCV(estimator=rf,param_grid=parameters)
clf.fit(iris.data,iris.target)
print("最优分数:%.4f"%clf.best_score_)
print("最优参数:",clf.best_params_)
最优分数:0.9600
最优参数: {'n_estimators': 5}

可以当我们采用随机森林作为分类器的时候,最优准确率是 0.9600,当 n_estimators=5 的时候,是最优参数,也就是随机森林一共有 5 个子决策树。

使用 Pipeline 管道机制进行流水线作业

做分类的时候往往都是有步骤的,比如先对数据进行规范化处理,你也可以用 PCA 方法(一种常用的降维方法)对数据降维,最后使用分类器分类。
Python 有一种 Pipeline 管道机制。管道机制就是让我们把每一步都按顺序列下来,从而创建Pipeline 流水线作业。每一步都采用 (‘名称’, 步骤) 的方式来表示。
我们需要先采用 StandardScaler 方法对数据规范化,即采用数据规范化为均值为 0,方差为 1的正态分布,然后采用 PCA 方法对数据进行降维,最后采用随机森林进行分类。

代码如下:

1
2
3
4
5
6
from sklearn.model_selection import GridSearchCV
pipeline = Pipeline([
('scaler', StandardScaler()),
('pca', PCA()),
('randomforestclassifier', RandomForestClassifier())
])

那么我们现在采用 Pipeline 管道机制,用随机森林对 IRIS 数据集做一下分类。先用StandardScaler 方法对数据规范化,然后采用随机森林分类器,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
rf = RandomForestClassifier()
parameters= {"n_estimators":range(1,11)}
iris = load_iris()
print(iris.keys())
pipeline = Pipeline([
('scaler',StandardScaler()),
('randomforestclassifier',rf)
])
clf = GridSearchCV(estimator=pipeline,param_grid=parameters)
clf.fit(iris.data,iris.target)
print("最优分数:%.4f"%clf.best_score_)
print("最优参数:",clf.best_params_)
运行结果:
最优分数: 0.9667
最优参数: {'randomforestclassifier__n_estimators': 9}

可以看到是否采用数据规范化对结果还是有一些影响的,有了 GridSearchCV 和 Pipeline 这两个工具之后,我们在使用分类器的时候就会方便很多 。