欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

集成学习

程序员文章站 2022-07-09 19:58:34
...

装袋法

使用sklearn库实现的决策树装袋法提升分类效果,其中X和Y分别是鸢尾花(iris)数据集中的自变量(花的特征)和因变量(花的类别)

from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn import datasets
#加载iris数据集
iris = datasets.load_iris()
X = iris.data
Y = iris.target
#分类器及交叉验证
seed = 42
kfold = KFold(n_splits=10, random_state=seed)
cart = DecisionTreeClassifier(criterion='gini',max_depth=2)
cart = cart.fit(X, Y)
result = cross_val_score(cart, X, Y, cv=kfold)
print("CART树结果:",result.mean())
model = BaggingClassifier(base_estimator=cart, n_estimators=100, random_state=seed)
result = cross_val_score(model, X, Y, cv=kfold)
print("装袋法提升后结果:",result.mean())

其中,cart为决策树分类器,model为sklearn库中自带的装袋法分类器,两种算法的效果验证均采用k折交叉验证的方法,BaggingClassifier方法中的n_estimators表示创建100个分类模型。运行之后的结果如下。

CART树结果: 0.9333333333333333
装袋法提升后结果: 0.9466666666666667

xgboost

下面是在Python环境下使用XGBoost模块进行回归的调用示例,首先用pandas构造一个最简单的数据集df,其中x的值为[1,2,3],y的值为[10,20,30],并构建训练集矩阵T_train_xbg。代码如下。

import pandas as pd
import xgboost as xgb
df = pd.DataFrame({'x':[1,2,3], 'y':[10,20,30]})
X_train = df.drop('y',axis=1)
Y_train = df['y']
T_train_xgb = xgb.DMatrix(X_train, Y_train)
params = {"objective": "reg:linear", "booster":"gblinear"}
gbm = xgb.train(dtrain=T_train_xgb,params=params)
Y_pred = gbm.predict(xgb.DMatrix(pd.DataFrame({'x':[4,5]})))
print(Y_pred)
[32.79174 38.75454]

随机森林和决策树对比

随机森林是专为决策树分类器设计的集成方式,是装袋法的一种拓展。随机森林与装袋法采取相同的样本抽取方式。装袋法中的决策树每次从所有属性中选取一个最优的属性作为其分支属性,而随机森林算法每次从所有属性中随机抽取F个属性,然后从这F个属性中选取一个最优的属性作为其分支属性,这样就使得整个模型的随机性更强,从而使模型的泛化能力更强。而对于参数F的选取,决定了模型的随机性,若样本属性共有M个,F=1意味着随机选择一个属性来作为分支属性,F=属性总数时就变成了装袋法集成方式,通常F的取值为小于log2(M+1)的最大整数。而随机森林算法使用的弱分类决策树通常为CART算法。
随机森林算法思路简单、易实现,却有着比较好的分类效果。
使用sklearn库中的随机森林算法和决策树算法进行效果对比,数据集由生成器随机生成,示例代码如下。

from sklearn.model_selection import cross_val_score
from sklearn.datasets import make_blobs
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.tree import DecisionTreeClassifier
from matplotlib import pyplot, pyplot as plt
X, y = make_blobs(n_samples=1000, n_features=6, centers=50,random_state=0)
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.show()
clf = DecisionTreeClassifier(max_depth=None, min_samples_split=2,random_state=0)
scores = cross_val_score(clf, X, y)
print("DecisionTreeClassifier result:",scores.mean())
clf = RandomForestClassifier(n_estimators=10, max_depth=None,min_samples_split=2, random_state=0)
scores = cross_val_score(clf, X, y)
print("RandomForestClassifier result:",scores.mean())

首先,使用sklearn中自带的取类数据生成器(make_blobs)随机生成测试样本,make_blobs方法中n_samples表示生成的样本数量;n_features表示每个样本的特征数量;centers表示类别数量;random_state表示随机种子。在这里,生成了1000个样本,每个样本特征数为6个,总共有50个类别,可视化后结果如图

集成学习

其中,决策树分类器参数最大深度不做限制(max_depth为None),而min_sample_split限制为2表示叶子节点最少是2个。随机森林模型初始化参数中的n_estimators表示弱学习器的最大迭代次数,或者说最大的弱学习器的个数。如果设置的值太小,模型容易欠拟合;如果太大,计算量会较大,并且超过一定的数量后,模型提升很小,所以一般结合样本数量选择一个适中的数值,默认值为100。运行代码之后输出结果如下。

DecisionTreeClassifier result: 0.9558730158730159
RandomForestClassifier result: 0.9928571428571429

从模型结果看,随机森林的结果较好,其原因是在随机森林中,集成模型中构建树的时候,样本由训练集有放回抽样得到。此外,在构建树的过程中,节点分割时,选择的分割点不是所有属性中的最佳分割点,而是属性的一个随机子集中的最佳分割点。由于这种随机性,相对于单个非随机树,随机森林的偏差通常会有所增大,但是由于取了平均,其方差也会减小,通常能够补偿偏差的增加,从而产生一个总体上更好的模型。
在sklearn库中还可以构造一个极限随机森林(Extra Trees Classifier),并使用相同的数据集进行测试,代码如下。

clf2 = ExtraTreesClassifier(n_estimators=10, max_depth=None,
min_samples_split=2, random_state=0)
scores = cross_val_score(clf2, X, y)
print("ExtraTreesClassifier result:",scores.mean())
ExtraTreesClassifier result: 0.998095238095238

从结果可以看到其效果较随机森林更好,原因是在极限随机树中,计算分割点方法中的随机性进一步增强。相较于随机森林,其阈值是针对每个候选特征随机生成的,并且选择最佳阈值作为分割规则,这样能够减少一点模型的方差,总体上效果更好。