【机器学习】集成学习算法使用与对比(随机森林、GBDT、XGBoost、LightGBM等)

集成学习方法随机森林、GBDT、XGBoost、LightGBM 的使用与对比

import warnings  
warnings.filterwarnings("ignore")  
import pandas as pd  
from sklearn.model_selection import train_test_split  

生成数据

生成12000行的数据,训练集和测试集按照3:1划分

from sklearn.datasets import make_hastie_10_2  
  
data, target = make_hastie_10_2()  
X_train, X_test, y_train, y_test = train_test_split(data, target, random_state=123)  
X_train.shape, X_test.shape  
((9000, 10), (3000, 10))  

模型对比

对比六大模型,都使用默认参数

from sklearn.linear_model import LogisticRegression  
from sklearn.ensemble import RandomForestClassifier  
from sklearn.ensemble import AdaBoostClassifier  
from sklearn.ensemble import GradientBoostingClassifier  
from xgboost import XGBClassifier  
from lightgbm import LGBMClassifier  
from sklearn.model_selection import cross_val_score  
import time  
  
clf1 = LogisticRegression()  
clf2 = RandomForestClassifier()  
clf3 = AdaBoostClassifier()  
clf4 = GradientBoostingClassifier()  
clf5 = XGBClassifier()  
clf6 = LGBMClassifier()  
  
for clf, label in zip([clf1, clf2, clf3, clf4, clf5, clf6], [  
        'Logistic Regression', 'Random Forest', 'AdaBoost', 'GBDT', 'XGBoost',  
        'LightGBM'  
]):  
    start = time.time()  
    scores = cross_val_score(clf, X_train, y_train, scoring='accuracy', cv=5)  
    end = time.time()  
    running_time = end - start  
    print("Accuracy: %0.8f (+/- %0.2f),耗时%0.2f秒。模型名称[%s]" %  
          (scores.mean(), scores.std(), running_time, label))  
Accuracy: 0.47488889 (+/- 0.00),耗时0.04秒。模型名称[Logistic Regression]  
Accuracy: 0.88966667 (+/- 0.01),耗时16.34秒。模型名称[Random Forest]  
Accuracy: 0.88311111 (+/- 0.00),耗时3.39秒。模型名称[AdaBoost]  
Accuracy: 0.91388889 (+/- 0.01),耗时13.14秒。模型名称[GBDT]  
Accuracy: 0.92977778 (+/- 0.00),耗时3.60秒。模型名称[XGBoost]  
Accuracy: 0.93188889 (+/- 0.01),耗时0.58秒。模型名称[LightGBM]  

对比了六大模型,可以看出,逻辑回归速度最快,但准确率最低。而LightGBM,速度快,而且准确率最高,所以,现在处理结构化数据的时候,大部分都是用LightGBM算法。

XGBoost的使用

1.原生XGBoost的使用

import xgboost as xgb  
#记录程序运行时间  
import time  
  
start_time = time.time()  
  
#xgb矩阵赋值  
xgb_train = xgb.DMatrix(X_train, y_train)  
xgb_test = xgb.DMatrix(X_test, label=y_test)  
##参数  
params = {  
    'booster': 'gbtree',  
#     'silent': 1,  #设置成1则没有运行信息输出,最好是设置为0.  
    #'nthread':7,# cpu 线程数 默认最大  
    'eta': 0.007,  # 如同学习率  
    'min_child_weight': 3,  
    # 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言  
    #,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。  
    #这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。  
    'max_depth': 6,  # 构建树的深度,越大越容易过拟合  
    'gamma': 0.1,  # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。  
    'subsample': 0.7,  # 随机采样训练样本  
    'colsample_bytree': 0.7,  # 生成树时进行的列采样   
    'lambda': 2,  # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。  
    #'alpha':0, # L1 正则项参数  
    #'scale_pos_weight':1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。  
    #'objective': 'multi:softmax', #多分类的问题  
    #'num_class':10, # 类别数,多分类与 multisoftmax 并用  
    'seed': 1000,  #随机种子  
    #'eval_metric': 'auc'  
}  
plst = list(params.items())  
num_rounds = 500  # 迭代次数  
watchlist = [(xgb_train, 'train'), (xgb_test, 'val')]  
#训练模型并保存  
# early_stopping_rounds 当设置的迭代次数较大时,early_stopping_rounds 可在一定的迭代次数内准确率没有提升就停止训练  
model = xgb.train(  
    plst,  
    xgb_train,  
    num_rounds,  
    watchlist,  
    early_stopping_rounds=100,  
)  
#model.save_model('./model/xgb.model') # 用于存储训练出的模型  
print("best best_ntree_limit", model.best_ntree_limit)  
y_pred = model.predict(xgb_test, ntree_limit=model.best_ntree_limit)  
print('error=%f' %  
      (sum(1  
           for i in range(len(y_pred)) if int(y_pred[i] > 0.5) != y_test[i]) /  
       float(len(y_pred))))  
# 输出运行时长  
cost_time = time.time() - start_time  
print("xgboost success!", '\n', "cost time:", cost_time, "(s)......")  

[0]	train-rmse:1.11000	val-rmse:1.10422  
[1]	train-rmse:1.10734	val-rmse:1.10182  
[2]	train-rmse:1.10465	val-rmse:1.09932  
[3]	train-rmse:1.10207	val-rmse:1.09694  

……

[497]	train-rmse:0.62135	val-rmse:0.68680  
[498]	train-rmse:0.62096	val-rmse:0.68650  
[499]	train-rmse:0.62056	val-rmse:0.68624  
best best_ntree_limit 500  
error=0.826667  
xgboost success!   
 cost time: 3.5742645263671875 (s)......  

2.使用scikit-learn接口

会改变的函数名是:

eta -> learning_rate

lambda -> reg_lambda

alpha -> reg_alpha

from sklearn.model_selection import train_test_split  
from sklearn import metrics  
  
from xgboost import XGBClassifier  
  
clf = XGBClassifier(  
    #     silent=0,  #设置成1则没有运行信息输出,最好是设置为0.是否在运行升级时打印消息。  
    #nthread=4,# cpu 线程数 默认最大  
    learning_rate=0.3,  # 如同学习率  
    min_child_weight=1,  
    # 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言  
    #,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。  
    #这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。  
    max_depth=6,  # 构建树的深度,越大越容易过拟合  
    gamma=0,  # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。  
    subsample=1,  # 随机采样训练样本 训练实例的子采样比  
    max_delta_step=0,  #最大增量步长,我们允许每个树的权重估计。  
    colsample_bytree=1,  # 生成树时进行的列采样   
    reg_lambda=1,  # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。  
    #reg_alpha=0, # L1 正则项参数  
    #scale_pos_weight=1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。平衡正负权重  
    #objective= 'multi:softmax', #多分类的问题 指定学习任务和相应的学习目标  
    #num_class=10, # 类别数,多分类与 multisoftmax 并用  
    n_estimators=100,  #树的个数  
    seed=1000  #随机种子  
    #eval_metric= 'auc'  
)  
clf.fit(X_train, y_train)  
  
y_true, y_pred = y_test, clf.predict(X_test)  
print("Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred))  
Accuracy : 0.936  

LIghtGBM的使用

1.原生接口

import lightgbm as lgb  
from sklearn.metrics import mean_squared_error  
# 加载你的数据  
# print('Load data...')  
# df_train = pd.read_csv('../regression/regression.train', header=None, sep='\t')  
# df_test = pd.read_csv('../regression/regression.test', header=None, sep='\t')  
#  
# y_train = df_train[0].values  
# y_test = df_test[0].values  
# X_train = df_train.drop(0, axis=1).values  
# X_test = df_test.drop(0, axis=1).values  
  
# 创建成lgb特征的数据集格式  
lgb_train = lgb.Dataset(X_train, y_train)  # 将数据保存到LightGBM二进制文件将使加载更快  
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)  # 创建验证数据  
  
# 将参数写成字典下形式  
params = {  
    'task': 'train',  
    'boosting_type': 'gbdt',  # 设置提升类型  
    'objective': 'regression',  # 目标函数  
    'metric': {'l2', 'auc'},  # 评估函数  
    'num_leaves': 31,  # 叶子节点数  
    'learning_rate': 0.05,  # 学习速率  
    'feature_fraction': 0.9,  # 建树的特征选择比例  
    'bagging_fraction': 0.8,  # 建树的样本采样比例  
    'bagging_freq': 5,  # k 意味着每 k 次迭代执行bagging  
    'verbose': 1  # <0 显示致命的, =0 显示错误 (警告), >0 显示信息  
}  
  
print('Start training...')  
# 训练 cv and train  
gbm = lgb.train(params,  
                lgb_train,  
                num_boost_round=500,  
                valid_sets=lgb_eval,  
                early_stopping_rounds=5)  # 训练数据需要参数列表和数据集  
  
print('Save model...')  
  
gbm.save_model('model.txt')  # 训练后保存模型到文件  
  
print('Start predicting...')  
# 预测数据集  
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration  
                     )  #如果在训练期间启用了早期停止,可以通过best_iteration方式从最佳迭代中获得预测  
# 评估模型  
print('error=%f' %  
      (sum(1  
           for i in range(len(y_pred)) if int(y_pred[i] > 0.5) != y_test[i]) /  
       float(len(y_pred))))  
Start training...  
[LightGBM] [Warning] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000448 seconds.  
You can set `force_col_wise=true` to remove the overhead.  
[LightGBM] [Info] Total Bins 2550  
[LightGBM] [Info] Number of data points in the train set: 9000, number of used features: 10  
[LightGBM] [Info] Start training from score 0.012000  
[1]	valid_0's auc: 0.814399	valid_0's l2: 0.965563  
Training until validation scores don't improve for 5 rounds  
[2]	valid_0's auc: 0.84729	valid_0's l2: 0.934647  
[3]	valid_0's auc: 0.872805	valid_0's l2: 0.905265  
[4]	valid_0's auc: 0.884117	valid_0's l2: 0.877875  
[5]	valid_0's auc: 0.895115	valid_0's l2: 0.852189  

……

[191]	valid_0's auc: 0.982783	valid_0's l2: 0.319851  
[192]	valid_0's auc: 0.982751	valid_0's l2: 0.319971  
[193]	valid_0's auc: 0.982685	valid_0's l2: 0.320043  
Early stopping, best iteration is:  
[188]	valid_0's auc: 0.982794	valid_0's l2: 0.319746  
Save model...  
Start predicting...  
error=0.664000  

2.scikit-learn接口

from sklearn import metrics  
from lightgbm import LGBMClassifier  
  
clf = LGBMClassifier(  
    boosting_type='gbdt',  # 提升树的类型 gbdt,dart,goss,rf  
    num_leaves=31,  #树的最大叶子数,对比xgboost一般为2^(max_depth)  
    max_depth=-1,  #最大树的深度  
    learning_rate=0.1,  #学习率  
    n_estimators=100,  # 拟合的树的棵树,相当于训练轮数  
    subsample_for_bin=200000,  
    objective=None,  
    class_weight=None,  
    min_split_gain=0.0,  # 最小分割增益  
    min_child_weight=0.001,  # 分支结点的最小权重  
    min_child_samples=20,  
    subsample=1.0,  # 训练样本采样率 行  
    subsample_freq=0,  # 子样本频率  
    colsample_bytree=1.0,  # 训练特征采样率 列  
    reg_alpha=0.0,  # L1正则化系数  
    reg_lambda=0.0,  # L2正则化系数  
    random_state=None,  
    n_jobs=-1,  
    silent=True,  
)  
clf.fit(X_train, y_train, eval_metric='auc')  
#设置验证集合 verbose=False不打印过程  
clf.fit(X_train, y_train)  
  
y_true, y_pred = y_test, clf.predict(X_test)  
print("Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred))  
Accuracy : 0.927  

参考

1.https://xgboost.readthedocs.io/

2.https://lightgbm.readthedocs.io/

3.https://blog.csdn.net/q383700092/article/details/53763328?locationNum=9&fps=1

你可能感兴趣的:(机器学习,算法,集成学习)