精华内容
下载资源
问答
  • 随机森林调参

    2021-02-28 16:34:44
  • 前两天写了个scikit-learn初步学习,今天没事又照着写了个RF模型的,刚开始还不懂这个python列表推导式,想了想还是挺好用的。然后用了GridSearchCv这个参数优化类,遍历多种参数组合(也就是暴搜最优参数组合),通过...

    前两天写了个scikit-learn初步学习,今天没事又照着写了个RF模型的,刚开始还不懂这个python列表推导式,想了想还是挺好用的。

    然后用了GridSearchCv这个参数优化类,遍历多种参数组合(也就是暴搜最优参数组合),通过交叉验证确定最佳效果参数。

    所以优化完可能对训练数据拟合更差,泛化能力更强?

    最后还有把数据划分为训练集和测试集。

    最后说一下用的数据还是scikit-learn初步学习里面的 但是加了标签,也就是在数据第一行添加上f1,f2,f3,f4,f5,f6,f7,f8,result。

    #coding=utf-8

    import pandas as pd

    import numpy as np

    from sklearn.ensemble import RandomForestClassifier

    from sklearn.grid_search import GridSearchCV

    from sklearn import cross_validation,metrics

    import matplotlib.pylab as plt

    from sklearn.externals import joblib

    from sklearn.cross_validation import train_test_split

    train = pd.read_csv("C:\Users\Administrator\Desktop\hh_practice.csv")

    # for row in train:

    # print row

    # print 8888

    # print train.head(10)

    # print train['result'][:10]

    print '类别输出'

    target = "result"

    print train['result'].value_counts()

    print '样本的特征'

    print train.columns

    # print train[5:6]

    #将特征和类型分开

    x_col = [x for x in train.columns if x != 'result']

    X = train[x_col]

    # print X

    Y = train['result']

    rf_model = RandomForestClassifier();

    rf_model.fit(X,Y)

    expected = Y

    # predicted = rf_model.predict(X)

    # #预测结果

    # print(metrics.classification_report(expected,predicted))

    # print(metrics.confusion_matrix(expected,predicted))

    y_predprob = rf_model.predict_proba(X)

    print y_predprob

    #参数调整范围

    param_test1= {'n_estimators':range(10,100,10)}

    gsearch1= GridSearchCV(estimator = RandomForestClassifier(min_samples_split=100,

    min_samples_leaf=20,max_depth=8,max_features='sqrt' ,random_state=10),

    param_grid =param_test1, scoring='roc_auc',cv=5)

    gsearch1.fit(X,Y)

    print '第一次调整参数'

    print gsearch1.grid_scores_

    print gsearch1.best_params_

    print gsearch1.best_score_

    param_test2= {'max_depth':range(3,14,2), 'min_samples_split':range(50,201,20)}

    gsearch2= GridSearchCV(estimator = RandomForestClassifier(n_estimators= 70,

    min_samples_leaf=20 ,oob_score=True,random_state=10),

    param_grid = param_test2,scoring='roc_auc',iid=False, cv=5)

    gsearch2.fit(X,Y)

    print '第二次参数优化'

    print gsearch2.grid_scores_

    print gsearch2.best_params_

    print gsearch2.best_score_

    param_test3= {'min_samples_split':range(80,150,20), 'min_samples_leaf':range(10,60,10)}

    gsearch3= GridSearchCV(estimator = RandomForestClassifier(n_estimators= 70,max_depth=7,min_samples_split=50,

    oob_score=True, random_state=10),

    param_grid = param_test3,scoring='roc_auc',iid=False, cv=5)

    gsearch3.fit(X,Y)

    print '第三次参数优化'

    print gsearch3.grid_scores_

    print gsearch2.best_params_

    print gsearch2.best_score_

    param_test4= {'max_features':range(3,8,2)}

    gsearch4= GridSearchCV(estimator = RandomForestClassifier(n_estimators= 70,max_depth=7, min_samples_split=50,

    min_samples_leaf=20 ,oob_score=True, random_state=10),

    param_grid = param_test4,scoring='roc_auc',iid=False, cv=5)

    gsearch4.fit(X,Y)

    print '第四次参数优化'

    print gsearch4.grid_scores_

    print gsearch4.best_params_

    print gsearch4.best_score_

    #使用默认参数

    rf_model = RandomForestClassifier();

    rf_model.fit(X,Y)

    expected = Y

    predicted = rf_model.predict(X)

    #预测结果

    print(metrics.classification_report(expected,predicted))

    print(metrics.confusion_matrix(expected,predicted))

    #使用优化后的参数

    new_rf_model = RandomForestClassifier(n_estimators=70,min_samples_split=50,max_depth=7,max_features=3);

    new_rf_model.fit(X,Y)

    expected = Y

    predicted = new_rf_model.predict(X)

    #预测结果

    print(metrics.classification_report(expected,predicted))

    print(metrics.confusion_matrix(expected,predicted))

    #持久化模型 此处的要注意一定要设置compress=3,不然就会很多npy后缀的文件,是numpy存储文件的格

    # 式.这个参数貌似是压缩的

    joblib.dump(new_rf_model,r"C:\Users\Administrator\Desktop\temhhhh\rf.model",compress=3)

    #载入模型 joblib.load(path)

    #将数据划分为训练集和测试集

    X_train,X_test,Y_train,Y_test = train_test_split(X,Y,test_size=0.5,random_state=66)

    print 'X的训练数据'

    print X_train

    print 'Y的训练数据'

    print Y_train

    print 'X的测试集'

    print X_test

    print 'Y的测试集'

    print Y_test

    hh_rf = RandomForestClassifier()

    hh_rf.fit(X_train,Y_train)

    train_expected = Y_train

    train_predicted=hh_rf.predict(X_train)

    print '训练效果'

    print(metrics.classification_report(train_expected,train_predicted))

    print(metrics.confusion_matrix(train_expected,train_predicted))

    test_expected = Y_test

    test_predicted=hh_rf.predict(X_test)

    print '预测效果'

    print(metrics.classification_report(test_expected,test_predicted))

    print(metrics.confusion_matrix(test_expected,test_predicted))

    展开全文
  • 在Bagging与随机森林算法原理小...重点讲述scikit-learn中RF的调参注意事项,以及和GBDT调参的异同点。1. scikit-learn随机森林类库概述在scikit-learn中,RF的分类类是RandomForestClassifier,回归类是RandomFore...

    在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结。本文就从实践的角度对RF做一个总结。重点讲述scikit-learn中RF的调参注意事项,以及和GBDT调参的异同点。

    1. scikit-learn随机森林类库概述

    在scikit-learn中,RF的分类类是RandomForestClassifier,回归类是RandomForestRegressor。当然RF的变种Extra Trees也有, 分类类ExtraTreesClassifier,回归类ExtraTreesRegressor。由于RF和Extra Trees的区别较小,调参方法基本相同,本文只关注于RF的调参。

    和GBDT的调参类似,RF需要调参的参数也包括两部分,第一部分是Bagging框架的参数,第二部分是CART决策树的参数。下面我们就对这些参数做一个介绍。

    2.  RF框架参数

    首先我们关注于RF的Bagging框架的参数。这里可以和GBDT对比来学习。在scikit-learn 梯度提升树(GBDT)调参小结中我们对GBDT的框架参数做了介绍。GBDT的框架参数比较多,重要的有最大迭代器个数,步长和子采样比例,调参起来比较费力。但是RF则比较简单,这是因为bagging框架里的各个弱学习器之间是没有依赖关系的,这减小的调参的难度。换句话说,达到同样的调参效果,RF调参时间要比GBDT少一些。

    下面我来看看RF重要的Bagging框架的参数,由于RandomForestClassifier和RandomForestRegressor参数绝大部分相同,这里会将它们一起讲,不同点会指出。

    1) n_estimators: 也就是最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,计算量会太大,并且n_estimators到一定的数量后,再增大n_estimators获得的模型提升会很小,所以一般选择一个适中的数值。默认是100。

    2) oob_score :即是否采用袋外样本来评估模型的好坏。默认识False。个人推荐设置为True,因为袋外分数反应了一个模型拟合后的泛化能力。

    3) criterion:即CART树做划分时对特征的评价标准。分类模型和回归模型的损失函数是不一样的。分类RF对应的CART分类树默认是基尼系数gini,另一个可选择的标准是信息增益。回归RF对应的CART回归树默认是均方差mse,另一个可以选择的标准是绝对值差mae。一般来说选择默认的标准就已经很好的。

    从上面可以看出, RF重要的框架参数比较少,主要需要关注的是 n_estimators,即RF最大的决策树个数。

    3.  RF决策树参数

    下面我们再来看RF的决策树参数,它要调参的参数基本和GBDT相同,如下:

    1) RF划分时考虑的最大特征数max_features: 可以使用很多种类型的值,默认是"auto",意味着划分时最多考虑$\sqrt{N}$个特征;如果是"log2"意味着划分时最多考虑$log_2N$个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑$\sqrt{N}$个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。一般我们用默认的"auto"就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。

    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.RF调参实例

    这里仍然使用GBDT调参时同样的数据集来做RF调参的实例,数据的下载地址在这。本例我们采用袋外分数来评估我们模型的好坏。

    完整代码参见我的github:https://github.com/ljpzzz/machinelearning/blob/master/ensemble-learning/random_forest_classifier.ipynb

    首先,我们载入需要的类库:

    importpandas as pdimportnumpy as npfrom sklearn.ensemble importRandomForestClassifierfrom sklearn.grid_search importGridSearchCVfrom sklearn importcross_validation, metricsimportmatplotlib.pylab as plt%matplotlib inline

    接着,我们把解压的数据用下面的代码载入,顺便看看数据的类别分布。

    train = pd.read_csv('train_modified.csv')

    target='Disbursed' #Disbursed的值就是二元分类的输出

    IDcol = 'ID'train['Disbursed'].value_counts()

    可以看到类别输出如下,也就是类别0的占大多数。

    0    19680

    1      320

    Name: Disbursed, dtype: int64

    接着我们选择好样本特征和类别输出。

    x_columns = [x for x in train.columns if x not in[target, IDcol]]

    X=train[x_columns]

    y= train['Disbursed']

    不管任何参数,都用默认的,我们拟合下数据看看:

    rf0 = RandomForestClassifier(oob_score=True, random_state=10)

    rf0.fit(X,y)printrf0.oob_score_

    y_predprob= rf0.predict_proba(X)[:,1]print "AUC Score (Train): %f" % metrics.roc_auc_score(y, y_predprob)

    输出如下,可见袋外分数已经很高,而且AUC分数也很高。相对于GBDT的默认参数输出,RF的默认参数拟合效果对本例要好一些。

    0.98005

    AUC Score (Train): 0.999833

    我们首先对n_estimators进行网格搜索:

    param_test1 = {'n_estimators':range(10,71,10)}

    gsearch1= GridSearchCV(estimator = RandomForestClassifier(min_samples_split=100,

    min_samples_leaf=20,max_depth=8,max_features='sqrt' ,random_state=10),

    param_grid= param_test1, scoring='roc_auc',cv=5)

    gsearch1.fit(X,y)

    gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_

    输出结果如下:

    ([mean: 0.80681, std: 0.02236, params: {'n_estimators': 10},

    mean: 0.81600, std: 0.03275, params: {'n_estimators': 20},

    mean: 0.81818, std: 0.03136, params: {'n_estimators': 30},

    mean: 0.81838, std: 0.03118, params: {'n_estimators': 40},

    mean: 0.82034, std: 0.03001, params: {'n_estimators': 50},

    mean: 0.82113, std: 0.02966, params: {'n_estimators': 60},

    mean: 0.81992, std: 0.02836, params: {'n_estimators': 70}],

    {'n_estimators': 60},

    0.8211334476626017)

    这样我们得到了最佳的弱学习器迭代次数,接着我们对决策树最大深度max_depth和内部节点再划分所需最小样本数min_samples_split进行网格搜索。

    param_test2 = {'max_depth':range(3,14,2), 'min_samples_split':range(50,201,20)}

    gsearch2= GridSearchCV(estimator = RandomForestClassifier(n_estimators= 60,

    min_samples_leaf=20,max_features='sqrt' ,oob_score=True, random_state=10),

    param_grid= param_test2, scoring='roc_auc',iid=False, cv=5)

    gsearch2.fit(X,y)

    gsearch2.grid_scores_, gsearch2.best_params_, gsearch2.best_score_

    输出如下:

    ([mean: 0.79379, std: 0.02347, params: {'min_samples_split': 50, 'max_depth': 3},

    mean: 0.79339, std: 0.02410, params: {'min_samples_split': 70, 'max_depth': 3},

    mean: 0.79350, std: 0.02462, params: {'min_samples_split': 90, 'max_depth': 3},

    mean: 0.79367, std: 0.02493, params: {'min_samples_split': 110, 'max_depth': 3},

    mean: 0.79387, std: 0.02521, params: {'min_samples_split': 130, 'max_depth': 3},

    mean: 0.79373, std: 0.02524, params: {'min_samples_split': 150, 'max_depth': 3},

    mean: 0.79378, std: 0.02532, params: {'min_samples_split': 170, 'max_depth': 3},

    mean: 0.79349, std: 0.02542, params: {'min_samples_split': 190, 'max_depth': 3},

    mean: 0.80960, std: 0.02602, params: {'min_samples_split': 50, 'max_depth': 5},

    mean: 0.80920, std: 0.02629, params: {'min_samples_split': 70, 'max_depth': 5},

    mean: 0.80888, std: 0.02522, params: {'min_samples_split': 90, 'max_depth': 5},

    mean: 0.80923, std: 0.02777, params: {'min_samples_split': 110, 'max_depth': 5},

    mean: 0.80823, std: 0.02634, params: {'min_samples_split': 130, 'max_depth': 5},

    mean: 0.80801, std: 0.02637, params: {'min_samples_split': 150, 'max_depth': 5},

    mean: 0.80792, std: 0.02685, params: {'min_samples_split': 170, 'max_depth': 5},

    mean: 0.80771, std: 0.02587, params: {'min_samples_split': 190, 'max_depth': 5},

    mean: 0.81688, std: 0.02996, params: {'min_samples_split': 50, 'max_depth': 7},

    mean: 0.81872, std: 0.02584, params: {'min_samples_split': 70, 'max_depth': 7},

    mean: 0.81501, std: 0.02857, params: {'min_samples_split': 90, 'max_depth': 7},

    mean: 0.81476, std: 0.02552, params: {'min_samples_split': 110, 'max_depth': 7},

    mean: 0.81557, std: 0.02791, params: {'min_samples_split': 130, 'max_depth': 7},

    mean: 0.81459, std: 0.02905, params: {'min_samples_split': 150, 'max_depth': 7},

    mean: 0.81601, std: 0.02808, params: {'min_samples_split': 170, 'max_depth': 7},

    mean: 0.81704, std: 0.02757, params: {'min_samples_split': 190, 'max_depth': 7},

    mean: 0.82090, std: 0.02665, params: {'min_samples_split': 50, 'max_depth': 9},

    mean: 0.81908, std: 0.02527, params: {'min_samples_split': 70, 'max_depth': 9},

    mean: 0.82036, std: 0.02422, params: {'min_samples_split': 90, 'max_depth': 9},

    mean: 0.81889, std: 0.02927, params: {'min_samples_split': 110, 'max_depth': 9},

    mean: 0.81991, std: 0.02868, params: {'min_samples_split': 130, 'max_depth': 9},

    mean: 0.81788, std: 0.02436, params: {'min_samples_split': 150, 'max_depth': 9},

    mean: 0.81898, std: 0.02588, params: {'min_samples_split': 170, 'max_depth': 9},

    mean: 0.81746, std: 0.02716, params: {'min_samples_split': 190, 'max_depth': 9},

    mean: 0.82395, std: 0.02454, params: {'min_samples_split': 50, 'max_depth': 11},

    mean: 0.82380, std: 0.02258, params: {'min_samples_split': 70, 'max_depth': 11},

    mean: 0.81953, std: 0.02552, params: {'min_samples_split': 90, 'max_depth': 11},

    mean: 0.82254, std: 0.02366, params: {'min_samples_split': 110, 'max_depth': 11},

    mean: 0.81950, std: 0.02768, params: {'min_samples_split': 130, 'max_depth': 11},

    mean: 0.81887, std: 0.02636, params: {'min_samples_split': 150, 'max_depth': 11},

    mean: 0.81910, std: 0.02734, params: {'min_samples_split': 170, 'max_depth': 11},

    mean: 0.81564, std: 0.02622, params: {'min_samples_split': 190, 'max_depth': 11},

    mean: 0.82291, std: 0.02092, params: {'min_samples_split': 50, 'max_depth': 13},

    mean: 0.82177, std: 0.02513, params: {'min_samples_split': 70, 'max_depth': 13},

    mean: 0.82415, std: 0.02480, params: {'min_samples_split': 90, 'max_depth': 13},

    mean: 0.82420, std: 0.02417, params: {'min_samples_split': 110, 'max_depth': 13},

    mean: 0.82209, std: 0.02481, params: {'min_samples_split': 130, 'max_depth': 13},

    mean: 0.81852, std: 0.02227, params: {'min_samples_split': 150, 'max_depth': 13},

    mean: 0.81955, std: 0.02885, params: {'min_samples_split': 170, 'max_depth': 13},

    mean: 0.82092, std: 0.02600, params: {'min_samples_split': 190, 'max_depth': 13}],

    {'max_depth': 13, 'min_samples_split': 110},

    0.8242016800050813)

    我们看看我们现在模型的袋外分数:

    rf1 = RandomForestClassifier(n_estimators= 60, max_depth=13, min_samples_split=110,

    min_samples_leaf=20,max_features='sqrt' ,oob_score=True, random_state=10)

    rf1.fit(X,y)print rf1.oob_score_

    输出结果为:

    0.984

    可见此时我们的袋外分数有一定的提高。也就是时候模型的泛化能力增强了。

    对于内部节点再划分所需最小样本数min_samples_split,我们暂时不能一起定下来,因为这个还和决策树其他的参数存在关联。下面我们再对内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf一起调参。

    param_test3 = {'min_samples_split':range(80,150,20), 'min_samples_leaf':range(10,60,10)}

    gsearch3= GridSearchCV(estimator = RandomForestClassifier(n_estimators= 60, max_depth=13,

    max_features='sqrt' ,oob_score=True, random_state=10),

    param_grid= param_test3, scoring='roc_auc',iid=False, cv=5)

    gsearch3.fit(X,y)

    gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_

    输出如下:

    ([mean: 0.82093, std: 0.02287, params: {'min_samples_split': 80, 'min_samples_leaf': 10},

    mean: 0.81913, std: 0.02141, params: {'min_samples_split': 100, 'min_samples_leaf': 10},

    mean: 0.82048, std: 0.02328, params: {'min_samples_split': 120, 'min_samples_leaf': 10},

    mean: 0.81798, std: 0.02099, params: {'min_samples_split': 140, 'min_samples_leaf': 10},

    mean: 0.82094, std: 0.02535, params: {'min_samples_split': 80, 'min_samples_leaf': 20},

    mean: 0.82097, std: 0.02327, params: {'min_samples_split': 100, 'min_samples_leaf': 20},

    mean: 0.82487, std: 0.02110, params: {'min_samples_split': 120, 'min_samples_leaf': 20},

    mean: 0.82169, std: 0.02406, params: {'min_samples_split': 140, 'min_samples_leaf': 20},

    mean: 0.82352, std: 0.02271, params: {'min_samples_split': 80, 'min_samples_leaf': 30},

    mean: 0.82164, std: 0.02381, params: {'min_samples_split': 100, 'min_samples_leaf': 30},

    mean: 0.82070, std: 0.02528, params: {'min_samples_split': 120, 'min_samples_leaf': 30},

    mean: 0.82141, std: 0.02508, params: {'min_samples_split': 140, 'min_samples_leaf': 30},

    mean: 0.82278, std: 0.02294, params: {'min_samples_split': 80, 'min_samples_leaf': 40},

    mean: 0.82141, std: 0.02547, params: {'min_samples_split': 100, 'min_samples_leaf': 40},

    mean: 0.82043, std: 0.02724, params: {'min_samples_split': 120, 'min_samples_leaf': 40},

    mean: 0.82162, std: 0.02348, params: {'min_samples_split': 140, 'min_samples_leaf': 40},

    mean: 0.82225, std: 0.02431, params: {'min_samples_split': 80, 'min_samples_leaf': 50},

    mean: 0.82225, std: 0.02431, params: {'min_samples_split': 100, 'min_samples_leaf': 50},

    mean: 0.81890, std: 0.02458, params: {'min_samples_split': 120, 'min_samples_leaf': 50},

    mean: 0.81917, std: 0.02528, params: {'min_samples_split': 140, 'min_samples_leaf': 50}],

    {'min_samples_leaf': 20, 'min_samples_split': 120},

    0.8248650279471544)

    最后我们再对最大特征数max_features做调参:

    param_test4 = {'max_features':range(3,11,2)}

    gsearch4= GridSearchCV(estimator = RandomForestClassifier(n_estimators= 60, max_depth=13, min_samples_split=120,

    min_samples_leaf=20 ,oob_score=True, random_state=10),

    param_grid= param_test4, scoring='roc_auc',iid=False, cv=5)

    gsearch4.fit(X,y)

    gsearch4.grid_scores_, gsearch4.best_params_, gsearch4.best_score_

    输出如下:

    ([mean: 0.81981, std: 0.02586, params: {'max_features': 3},

    mean: 0.81639, std: 0.02533, params: {'max_features': 5},

    mean: 0.82487, std: 0.02110, params: {'max_features': 7},

    mean: 0.81704, std: 0.02209, params: {'max_features': 9}],

    {'max_features': 7},

    0.8248650279471544)

    用我们搜索到的最佳参数,我们再看看最终的模型拟合:

    rf2 = RandomForestClassifier(n_estimators= 60, max_depth=13, min_samples_split=120,

    min_samples_leaf=20,max_features=7 ,oob_score=True, random_state=10)

    rf2.fit(X,y)print rf2.oob_score_

    此时的输出为:

    0.984

    可见此时模型的袋外分数基本没有提高,主要原因是0.984已经是一个很高的袋外分数了,如果想进一步需要提高模型的泛化能力,我们需要更多的数据。

    以上就是RF调参的一个总结,希望可以帮到朋友们。

    (欢迎转载,转载请注明出处。欢迎沟通交流: liujianping-ok@163.com)

    展开全文
  • ↑↑点击上方蓝字,回复资料,N个G的惊喜本文我们重点讲一下:1、集成学习、Bagging和随机森林概念2、随机森林参数解释及设置建议3、随机森林模型调参实战4、随机森林模型优缺点总结集成学习、Bagging和随机森林集成...

    ↑↑点击上方蓝字,回复资料,N个G的惊喜c208d3625a615230555d9df9c40b9f66.png

    本文我们重点讲一下:

    1、集成学习、Bagging和随机森林概念

    2、随机森林参数解释及设置建议 

    3、随机森林模型调参实战

    4、随机森林模型优缺点总结

    集成学习、Bagging和随机森林

    集成学习并不是一个单独的机器学习算法,它通过将多个基学习器(弱学习器)进行结合,最终获得一个强学习器。这里的弱学习器应该具有一定的准确性,并且要有多样性(学习器之间具有差异),比较常用的基学习器有决策树和神经网络。

    5c2a7e29771393f0c3143f5d81ff217b.png
    图片来源:西瓜书

    集成学习的核心就是如何产生并结合好而不同的基学习器,这里有两种方式是,一种是Bagging(基学习器之间没有强依赖关系,可同时生成的并行化方法),一种是Boosting(基学习器之间有强依赖关系,必须串行生成)。集成学习另一个关键问题是结合策略,主要有平均法、投票法和学习法,这里不再展开。

    Bagging是Bootstrap AGGregaING的缩写,Bootstrap即随机采样,比如给定含有个样本的数据集,每次随机的从中选择一个样本,放入新的数据集,然后将其放回初始数据集,放回后有可能继续被采集到,重复这个动作次,我们就得到新的数据集

    3891fc624eca160d306d6e611dfb0cb9.png
    from:towardsdatascience

    用这种方式,我们可以采样出含m个训练样本的采样集,然后基于每个采样集训练基学习器,再将基学习器进行结合,这便是Bagging的基本流程。

    1033d832d119e08c7aa8ee3174bd8822.png
    from:mrlevo520@简书

    随机森林是非常具有代表性的Bagging集成算法,它在Bagging基础上进行了强化。它的所有基学习器都是CART决策树,传统决策树在选择划分属性时是在当前结点的属性集合(假定有d个属性)中选择最优属性。但是随机森林的决策树,现在每个结点的属性集合随机选择部分k个属性的子集,然后在子集中选择一个最优的特征来做决策树的左右子树划分,一般建议.

    随机森林参数解释及设置建议

    在scikit-learn中,RandomForest的分类类是RandomForestClassifier,回归类是RandomForestRegressor,需要调参的参数包括两部分,第一部分是Bagging框架的参数,第二部分是CART决策树的参数。

    b6aec40ec1d61b0837e360b520b1ca4f.png
    18a1b40020279ba94aed96db18e4b360.png
    aa0e8f28a89a8239bc74718a7b1356f8.png
    随机森林参数及设置建议

    随机森林模型调参实战

    这是一道kaggle上的题目,通过信用卡交易记录数据对欺诈行为进行预测,信用卡欺诈检测文件记录了2013年9月欧洲信用卡持有者所发生的交易。在284807条交易记录中共包含492条欺诈记录。 

    数据集下载地址:请在公众号后台回复[56] 

    需要说明的是,本文重点是RF模型调参,所以不涉及数据预处理、特征工程和模型融合的内容,这些我会在本栏目未来的章节中再做介绍。所以最终结果可能会不理想,这里我们只关注通过调参给模型带来的性能提升和加深对重要参数的理解即可。

    1、导入模块

    import numpy as np
    import pandas as pd
    from sklearn.model_selection import GridSearchCV,train_test_split
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import roc_auc_score

    2、导入数据

    df = pd.read_csv("creditcard.csv")
    data=df.iloc[:,1:31]

    284807条交易记录中只有492条欺诈记录,样本严重不平衡,这里我们需要使用下采样策略(减少多数类使其数量与少数类相同)

    X = data.loc[:, data.columns != 'Class']
    y = data.loc[:, data.columns == 'Class']

    number_records_fraud = len(data[data.Class == 1]) # class=1的样本函数
    fraud_indices = np.array(data[data.Class == 1].index) # 样本等于1的索引值
    normal_indices = data[data.Class == 0].index # 样本等于0的索引值
    random_normal_indices = np.random.choice(normal_indices,number_records_fraud,replace = False)
    random_normal_indices = np.array(random_normal_indices)
    under_sample_indices = np.concatenate([fraud_indices,random_normal_indices]) # Appending the 2 indices
    under_sample_data = data.iloc[under_sample_indices,:] # Under sample dataset
    X_undersample = under_sample_data.loc[:,under_sample_data.columns != 'Class']
    y_undersample = under_sample_data.loc[:,under_sample_data.columns == 'Class']
    X_train, X_test, y_train, y_test = train_test_split(X_undersample,y_undersample,test_size = 0.3, random_state = 0)

    3、先用默认参数训练RF

    rf0 = RandomForestClassifier(oob_score=True, random_state=666)
    rf0.fit(X_train,y_train)
    print(rf0.oob_score_)
    y_predprob = rf0.predict_proba(X_test)[:,1]
    print("AUC Score (Train): %f" % roc_auc_score(y_test, y_predprob))

    0.9244186046511628

     AUC Score (Train): 0.967082 

    除oob_score将默认的False改为True, 我们重点优化n_estimators、max_depth、min_samples_leaf 这三个参数。为简单起见,模型评价指标,我们选择AUC值。

    模型调优我们采用网格搜索调优参数(grid search),通过构建参数候选集合,然后网格搜索会穷举各种参数组合,根据设定评定的评分机制找到最好的那一组设置。

    先优化n_estimators

    param_test1 = {'n_estimators':range(10,101,10)}
    gsearch1 = GridSearchCV(estimator = RandomForestClassifier(oob_score=True, random_state=666,n_jobs=2),
    param_grid = param_test1, scoring='roc_auc',cv=5)
    gsearch1.fit(X_train,y_train)
    gsearch1.cv_results_, gsearch1.best_params_, gsearch1.best_score_

    {'n_estimators': 50}, 0.9799524239675649

    n_estimators=50,优化max_features

    param_test2 = {'max_depth':range(2,12,2)}
    gsearch2 = GridSearchCV(estimator = RandomForestClassifier(n_estimators= 50,oob_score=True, random_state=666,n_jobs=2),
    param_grid = param_test2, scoring='roc_auc',cv=5)
    gsearch2.fit(X_train,y_train)
    gsearch2.cv_results_, gsearch2.best_params_, gsearch2.best_score_

    {'max_depth': 6}, 0.9809897227343921

    n_estimators=50max_features=6,优化max_depth

    param_test2 = {'min_samples_split':range(2,8,1)}
    gsearch2 = GridSearchCV(estimator = RandomForestClassifier(n_estimators= 50,max_depth=6,
    oob_score=True, random_state=666,n_jobs=2),
    param_grid = param_test2, scoring='roc_auc',cv=5)
    gsearch2.fit(X_train,y_train)
    gsearch2.cv_results_, gsearch2.best_params_, gsearch2.best_score_

    {'min_samples_split': 5}, 0.9819618127837587

    最后我们将优化后的参数带入模型

    rf1 = RandomForestClassifier(n_estimators= 50,max_depth=6,min_samples_split=5,oob_score=True, random_state=666,n_jobs=2)
    rf1.fit(X_train,y_train)
    print(rf1.oob_score_)
    y_predprob1 = rf1.predict_proba(X_test)[:,1]
    print("AUC Score (Train): %f" % roc_auc_score(y_test, y_predprob1))

    0.9331395348837209 AUC Score (Train): 0.977811 

    最终结果比默认参数时的模型袋外估计准确率得分、测试集上AUC值均有所提升。

    随机森林优缺点总结

    RF优点 

    1. 不容易出现过拟合,因为选择训练样本的时候就不是全部样本。

    2. 可以既可以处理属性为离散值的量,比如ID3算法来构造树,也可以处理属性为连续值的量,比如C4.5算法来构造树。

    3. 对于高维数据集的处理能力令人兴奋,它可以处理成千上万的输入变量,并确定最重要的变量,因此被认为是一个不错的降维方法。此外,该模型能够输出变量的重要性程度,这是一个非常便利的功能。

    4. 分类不平衡的情况时,随机森林能够提供平衡数据集误差的有效方法

    RF缺点 

    1. 随机森林在解决回归问题时并没有像它在分类中表现的那么好,这是因为它并不能给出一个连续型的输出。当进行回归时,随机森林不能够作出超越训练集数据范围的预测,这可能导致在对某些还有特定噪声的数据进行建模时出现过度拟合。

    2. 对于许多统计建模者来说,随机森林给人的感觉像是一个黑盒子——你几乎无法控制模型内部的运行,只能在不同的参数和随机种子之间进行尝试。

    参考:

    https://www.jianshu.com/p/708dff71df3a https://www.cnblogs.com/pinard/p/6156009.html

    c445749e6767da17669c04fc502d3919.gif

    加入机器学习微信群请后台回复【入群】

    推荐阅读:

    Matplotlib数据可视化:入门及组件介绍

    698a7bb6068d7c40468b49a0ad3e93ff.png

    阅后点在看,养成好习惯 92c1aa42bc9f92c39ebd9fe947ee5e06.png
    展开全文
  • 一、一般的模型调参原则1、调参前提:模型调参其实是没有定论,需要根据不同的数据集和不同的模型去调。但是有一些调参的思想是有规律可循的,首先我们可以知道,模型不准确只有两种情况:一是过拟合,而是欠拟合。...
  • 随机森林调参代码

    2018-04-27 10:52:30
    ### 随机森林调参 start = time() from sklearn.grid_search import GridSearchCV rf = RandomForestClassifier(n_jobs = 4,random_state=0) param_1 = {'n_estimators': list(range(30,91,10)), 'max_depth':...
  • 这篇文章中,使用基于方差和偏差的调参方法,在乳腺癌数据上进行一次随机森林调参。乳腺癌数据是sklearn自带的分类数据之一。方差和偏差案例中,往往使用真实数据,为什么我们要使用sklearn自带的数据呢?因为真实...
  • Python随机森林调参红酒品质预测 本节的数据来源是2009年UCI库中的Wine Quality Data Set的数据,大家可以在(http://archive.ics.uci.edu/ml/datasets/Wine+Quality)网址进行下载。 1.引入所需模块 import pandas ...
  • 随机森林调参 - python

    2021-03-04 11:33:48
    文章目录1、一般的模型调参原则2、随机森林的随机性体现在哪几个方面?2.1 数据集的随机选取2.2 待选特征的随机选取3、为什么使用随机森林?4、随机森林的构建过程5、随机森林优缺点总结5.1 优点5.2 缺点6、特征重要...
  • 文章目录随机森林调参应用 ---- 乳腺癌数据集Ⅰ.获取数据集Ⅱ.建模、评估精确度Ⅲ.调参 --- n_estimatorsⅣ.细化调参 ---- n_estimatorsⅤ.网格搜索调参• 调整max_depth• 调整max_features• 调整min_sample_...
  • 随机森林调参示例

    千次阅读 多人点赞 2018-04-01 14:56:14
    前言:特意写在前面,在调参的过程中,一定不要一次调整多个参数,理论是是可以,但那样不仅耗时,而且不好细微的调参,我就以我用随机森林的例子为例,我一次性调整了4个参数,大概花费了我差不多4个小时的时间,...
  • 随机森林调参的影响参数 对结果影响较大的参数 1.n_estimators:表示森林里树的个数。 理论上是越大越好,但是计算时间也相应增长。所以,并不是取得越大就会越好,预测效果最好的将会出现在合理的树个数。当使用的...
  • 原标题:Python机器学习实践:随机森林算法训练及调参-附代码 文章发布于公号【数智物语】 (ID:decision_engine),关注公号不错过每一篇干货。来源 | 博客园作者 | 战争热诚 随机森林是一种有监督学习算法,是以...
  • 随机森林调参笔记

    千次阅读 2018-11-05 10:08:24
    1. scikit-learn随机森林类库概述  在scikit-learn中,RF的分类类是RandomForestClassifier,回归类是RandomForestRegressor。当然RF的变种Extra Trees也有, 分类类ExtraTreesClassifier,回归类...
  • 随机森林调参的基本思路 首先确定各个参数大概的选择范围,形成参数字典 使用sklearn的RandomizedSearchCV(类似于寻找犯罪嫌疑人)(随机在于节省时间,不用地毯式遍历)利用参数字典中的参数对模型进行训练 得到...
  • 一、scikit-learn随机森林类库概述     在scikit-learn中,RF的分类类是RandomForestClassifier,回归类是RandomForestRegressor。当然RF的变种Extra Trees也有, 分类类ExtraTreesClassifier,回归类...
  • sklearn随机森林调参小结

    千次阅读 2018-08-16 17:05:51
    在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结。...重点讲述scikit-learn中RF的调参注意事项,以及和GBDT调参的异同点。 1. scikit-learn随机森林类库概述  在...
  • 本文将使用sklearn自带的乳腺癌数据集,建立随机森林,并基于泛化误差(Genelization Error)与模型复杂度的关系来对模型进行调参,从而使模型获得更高的得分。泛化误差是机器学习中,用来衡量模型在未知数据上的准确...
  • 本文我们重点讲一下:1、集成学习、Bagging和随机森林概念2、随机森林参数解释及设置建议3、随机森林模型调参实战4、随机森林模型优缺点总结集成学习、Bagging和随机森林集成学习...
  • 在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结。...重点讲述scikit-learn中RF的调参注意事项,以及和GBDT调参的异同点。 1. scikit-learn随机森林类库概述
  • param_test2 = {'max_depth': range(3, 14, 2), 'min_samples_split': range(50, 201, 20)}gsearch2 = GridSearchCV(estimator=RandomForestClassifier(n_estimators=60, min_samples_leaf=20, max_features='sqrt',...
  • 在Bagging与随机森林算法原理小...重点讲述scikit-learn中RF的调参注意事项,以及和GBDT调参的异同点。 一、scikit-learn随机森林类库概述  在scikit-learn中,RF的分类类是RandomForestClassifier,回归类是Rando...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 760
精华内容 304
关键字:

随机森林调参