sklearn之随机森林算法类库介绍

转载自:http://blog.sina.com.cn/s/blog_62970c250102xg6b.html
Bagging与随机森林算法原理一文中介绍了随机森林(Random Forest,RF)算法的原理。本文将介绍scikit-learn中随机森林算法类库的使用和调参,以及和GBDT调参的异同点。

1. scikit-learn随机森林类库概述
在scikit-learn中,RandomForestClassifier用于分类,RandomForestRegressor用于回归。RF的变种Extra Trees算法也存在, ExtraTreesClassifier用于分类,ExtraTreesRegressor用于回归。由于RF和Extra Trees的区别较小,调参方法也基本相同,因此本文只介绍RF的调参。
和GBDT的调参类似,RF的参数也包括两部分,第一部分是Bagging框架的参数,第二部分是CART决策树的参数。下面我们就对这些参数进行详细地介绍。

2.  随机森林框架参数
首先介绍RF的Bagging框架的参数。我们将会对比RF和GBDT的异同点。在scikit-learn(sklearn)GBDT算法类库介绍一文中介绍了GBDT框架的参数。GBDT框架的参数比较多,重要的有最大迭代器个数,步长和子采样比例,调参比较费力。但是RF则相对简单,这是因为Bagging框架中的各个弱学习器之间没有依赖关系,这降低了调参的难度。换句话说,要达到同样的调参效果,RF调参的时间要少于GBDT。
下面我们来看看RF的Bagging框架的重要参数,由于RandomForestClassifier和RandomForestRegressor参数绝大部分相同,因此放在一起来介绍。
参数 RandomForestClassifier RandomForestRegressor
n_estimators 弱学习器的最大迭代次数,或者说最大的弱学习器个数。一般来说n_estimators太小,容易欠拟合,而n_estimators太大,导致计算量也会非常大,并且n_estimators达到一定数量后,再增大n_estimators获得的模型提升会很小,所以一般选择一个适中的数值。默认值是100。
oob_score 是否采用袋外样本来评估模型的好坏。默认值是False,推荐设置为True,因为袋外分数反应了一个模型拟合后的泛化能力。
criterion CART决策树划分节点时对特征的评价标准。RandomForestClassifier类的可选择项有基尼系数”gini”和信息增益”entropy”,默认值是基尼系数”gini”。 RandomForestRegressor类的可选择项有均方差”mse”和绝对值差”mae”,默认值是均方差”mse”,一般来说选择默认值就可以了。
从上表可以看出,RF框架的重要参数比较少,需要关注的主要是n_estimators,即RF最大的决策树个数。

3. 随机森林决策树参数
接下来介绍RF的决策树参数,它的参数和GBDT基本相同。
  1) 划分时考虑的最大特征数max_features:可以使用多种类型值,默认是”None”,意味着划分时考虑所有的特征数;如果是”log2”,意味着划分时最多考虑log2N(以2为底N的对数)个特征;如果是”sqrt”或者”auto”,意味着划分时最多考虑N的平方根个特征;如果是整数,代表考虑的特征绝对数;如果是浮点数,代表考虑特征数的百分比,即考虑(百分比xN)取整后的特征数。其中N是样本总特征数。一般来说,如果样本特征数不多,比如小于50,使用默认值”None”就可以了,如果特征数非常多,则可以灵活地使用上述其它取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。
  2) 决策树的最大深度max_depth:默认可以不输入,如果不输入,则不会限制决策树的深度。一般来说,数据少或者特征少的时候可以不用管这个值。如果训练集样本量大,特征多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取10-100之间。
  3) 内部节点再划分所需最小样本数min_samples_split:这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会再进行划分,默认值是2。如果样本量不大,不需要管这个值;如果样本数量级非常大,则推荐增大这个值。
  4) 叶子节点最少样本数min_samples_leaf:这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于该值,则会和兄弟节点一起被剪枝。 默认值是1,可以输入最少样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本数量级非常大,则推荐增大这个值。
  5) 叶子节点最小的样本权重和min_weight_fraction_leaf:这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认值是0,就是不考虑样本权重。一般来说,如果较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要考虑这个参数了。
  6) 最大叶子节点数max_leaf_nodes:通过限制最大叶子节点数,可以防止过拟合,默认值是”None”,即不限制最大的叶子节点数。如果增加了限制,算法会创建在最大叶子节点数内最优的决策树。如果特征不多,可以不用考虑这个值,但是如果特征多的话,需要加以限制,具体的值可以通过交叉验证得到。
  7) 节点划分最小不纯度min_impurity_split:这个值限制了决策树的增长,如果某节点的不纯度(基尼系数,均方差)小于这个阈值,则该节点不再生成子节点,也就是说,该节点将成为叶子节点 。一般不推荐改动默认值1e-7。

决策树参数中最重要的包括最大特征数max_features, 最大深度max_depth, 内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf。

4. 使用Mnist数据集测试scikit-learn的RandomForestClassifier
代码如下所示:
—————————————————————————————————
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from time import time
import numpy as np
import mnist
import roc

if __name__ == “__main__”:
    # 读取Mnist数据集, 测试随机森林(Random Forest)的分类模型
    mnistSet = mnist.loadLecunMnistSet()
    train_X, train_Y, test_X, test_Y = mnistSet[0], mnistSet[1], mnistSet[2], mnistSet[3]

    m, n = np.shape(train_X)
    idx = range(m)
    np.random.shuffle(idx)

    print “\n**********测试RandomForestClassifier类**********”
    t = time()
    model = RandomForestClassifier(max_features=90, n_estimators=1300, max_depth=30, min_samples_split=4,
                                   min_samples_leaf=1)
    # 拟合训练数据集
    model.fit(train_X, train_Y)
    # 预测训练集
    train_Y_hat = model.predict(train_X[idx])
    print “训练集精确度: “, accuracy_score(train_Y[idx], train_Y_hat)
    # 预测测试集
    test_Y_hat = model.predict(test_X)
    print “测试集精确度: “, accuracy_score(test_Y, test_Y_hat)
    print “总耗时:”, time() - t, “秒”
    # 绘制ROC曲线
    n_class = len(np.unique(train_Y))
    roc.drawROC(n_class, test_Y, test_Y_hat)
—————————————————————————————————

5. 使用CCPP数据集测试scikit-learn的RandomForestRegressor
代码如下所示:
—————————————————————————————————
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
from time import time
import numpy as np
import pandas as pd

if __name__ == “__main__”:
    # 读取CCPP数据集, 测试随机森林(Random Forest)的回归模型
    data = pd.read_excel(“data/CCPP/Folds5x2_pp.xlsx”)
    # AT:温度, V:压力, AP:湿度, RH:压强, PE:输出电力
    # 样本特征X
    X = data[[‘AT’, ‘V’, ‘AP’, ‘RH’]]
    # 数据归一化
    X = StandardScaler().fit_transform(X)
    # 样本输出Y
    Y = data[[‘PE’]]
    # 划分训练集和测试集,将数据集的70%划入训练集,30%划入测试集
    train_X, test_X, train_Y, test_Y = train_test_split(X, Y, test_size=0.3, random_state=1)

    m, n = np.shape(train_X)
    idx = range(m)
    np.random.shuffle(idx)

    print “\n**********测试RandomForestRegressor类**********”
    t = time()
    model = RandomForestRegressor(oob_score=True, n_estimators=700, max_depth=30, min_samples_split=4,
                                  min_samples_leaf=1)
    # 拟合训练数据集
    model.fit(train_X, train_Y.values.ravel())
    print “袋外分数:”, model.oob_score_
    # 预测测试集
    test_Y_pred = model.predict(test_X)
    print “测试集MSE:”, mean_squared_error(test_Y, test_Y_pred)
    print “测试集RMSE:”, np.sqrt(mean_squared_error(test_Y, test_Y_pred))
    print “总耗时:”, time() - t, “秒”
—————————————————————————————————

猜你喜欢

转载自blog.csdn.net/zztingfeng/article/details/80584680
今日推荐