XGBoost模型调参、训练、保存、评估和预测

XGBoost在二分类问题中的使用

一.前期准备工作

1.1工具包和参数的简单说明

本文中脚本编写时使用的库版本如下, scikit-learn==0.24.1xgboost==1.6.1graphviz==0.20.1pandas==1.2.4,如果使用中碰到问题,分别执行下方pip命令重新安装库即可


pip list | find "scikit-learn"

pip uninstall scikit-learn

pip install scikit-learn==0.24.1 -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install xgboost==1.6.1 -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install graphviz==0.20.1 -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install pandas==1.2.4 -i https://pypi.tuna.tsinghua.edu.cn/simple/

xgboostXGBClassifier方法是分类模型,具体模型参数见xgboost官网参数(default)
sklearn.model_selectionGridSearchCV是用来调参的方法;
sklearn.metricsccuracy_score, roc_auc_score, f1_score做分类问题的评分指标,其他指标见官网sklearn评估指标(Metrics)

"""
    xgboost模型调参、训练、保存、预测
    官网信息辅助理解:
    xgboost官网参数(default) https://xgboost.readthedocs.io/en/latest/parameter.html#general-parameters
    sklearn评估指标(Metrics) https://scikit-learn.org/stable/modules/model_evaluation.html
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score, roc_auc_score, f1_score
import xgboost as xgb
from xgboost import XGBClassifier, plot_importance
import warnings

warnings.filterwarnings('ignore')
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei']

1.2划分训练集和验证集

百度网盘提取数据和完整脚本(提取码:54ul)无论训练集、验证集还是测试集,输入的数据都是数值型。XGBoost本身无法处理定性数据(分类数据和顺序数据),而是像随机森林一样,只接受定量数据。因此训练和测试数据必须通过各种编码方式:例如标记编码、均值编码或独热编码对数据进行处理。


dataset = pd.read_csv('Oil_well_parameters_train.csv', engine='python')

X_train, X_test, y_train, y_test = train_test_split(dataset.iloc[:, :-1], dataset.iloc[:, -1], test_size=0.2,
random_state=42)

二.模型调参

调参策略:逐个或逐类参数调整,避免所有参数一起调整导致模型复杂度过高。因此,调参过程分多步进行,每次调整相同类型的参数。

2.1调参示例

假设第一步 n_estimators迭代次数已调参完毕,最佳参数为 50,进行第二部调参演示,其余调参步骤按步进行,每次将确认好的最佳参数添加到 fine_params字典中。

def xgboost_parameters():
    """模型调参过程"""

    params = {'max_depth': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'min_child_weight': [1, 2, 3, 4, 5, 6]}

    fine_params = {'n_estimators': 50}
    return params, fine_params

模型调参过程会输出每个组合的平均得分值。根据 GridSearchCV参数指定使用 roc_auc为评分指标,进行 cv=5 5折交叉验证,返回的平均得分即为5折交叉验证auc值的平均值。

def model_adjust_parameters(cv_params, other_params):
    """模型调参"""

    model = XGBClassifier(**other_params)

    optimized_param = GridSearchCV(estimator=model, param_grid=cv_params, scoring='roc_auc', cv=5, verbose=1)

    optimized_param.fit(X_train, y_train)

    means = optimized_param.cv_results_['mean_test_score']
    params = optimized_param.cv_results_['params']
    for mean, param in zip(means, params):
        print("mean_score: %f,  params: %r" % (mean, param))

    print('参数的最佳取值:{0}'.format(optimized_param.best_params_))

    print('最佳模型得分:{0}'.format(optimized_param.best_score_))

    parameters_score = pd.DataFrame(params, means)
    parameters_score['means_score'] = parameters_score.index
    parameters_score = parameters_score.reset_index(drop=True)
    parameters_score.to_excel('parameters_score.xlsx', index=False)

    plt.figure(figsize=(15, 12))
    plt.subplot(2, 1, 1)
    plt.plot(parameters_score.iloc[:, :-1], 'o-')
    plt.legend(parameters_score.columns.to_list()[:-1], loc='upper left')
    plt.title('Parameters_size', loc='left', fontsize='xx-large', fontweight='heavy')
    plt.subplot(2, 1, 2)
    plt.plot(parameters_score.iloc[:, -1], 'r+-')
    plt.legend(parameters_score.columns.to_list()[-1:], loc='upper left')
    plt.title('Score', loc='left', fontsize='xx-large', fontweight='heavy')
    plt.show()

调用自定义的调参函数进行调参,根据 model_adjust_parameters设定会打印调参信息并画图辅助判断

if __name__ == '__main__':
"""
        模型调参
        调参策略:网格搜索、随机搜索、启发式搜索
        补充:此处采用启发式搜索,逐个或逐类参数调整,避免所有参数一起调整导致模型训练复杂度过高
"""

    adj_params, fixed_params = xgboost_parameters()

    model_adjust_parameters(adj_params, fixed_params)

返回参数组合及对应的模型得分

XGBoost模型调参、训练、保存、评估和预测

根据图可以清晰观察到随着 min_child_weight的变大,得分值减小,所以可以重新设定参数取值,重新执行调参过程。

XGBoost模型调参、训练、保存、评估和预测

2.2详细的调参过程

每次记录最佳参数及其模型得分,便于对比提升度。具体参数需要根据实际项目手动调整,当最佳参数处于最大最小值时,需要扩大参数范围。
gamma[default=0, alias: min_split_loss]指定节点分裂所需的最小损失下降值,取值范围: [0,∞],值越大,算法越保守。
params = {'gamma': [0.1, 0.3, 0.4, 0.5, 0.6]}时最佳参数若为 {'gamma': 0.1},则需要调整 params = {'gamma': [0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6]},由返回信息和图可观察到 gamma=0.05gamma=0.1模型得分一致,即可确定最佳参数 gamma=0.1(也可更细划分),否则仍需调整参数继续训练。

XGBoost模型调参、训练、保存、评估和预测
图像绘制结果,便于观察参数变化带来的模型效果走势
XGBoost模型调参、训练、保存、评估和预测
下方代码为参数迭代调整过程,每次将确认好的最佳参数添加到 fine_params字典中,然后进行其余参数调参。
def xgboost_parameters():
    """模型调参过程"""

    params = {'learning_rate': [0.01, 0.05, 0.07, 0.1, 0.2, 0.25, 0.3, 0.4]}

    fine_params = {'n_estimators': 50, 'max_depth': 2, 'min_child_weight': 1, 'gamma': 0.1, 'colsample_bytree': 1,
                   'subsample': 1, 'reg_alpha': 0.01, 'reg_lambda': 3, 'learning_rate': 0.3}
    return params, fine_params

三.模型训练与保存

3.1模型训练、验证、评估及特征重要性提取

根据调参确定好的参数训练模型,对验证集数据进行预测,预测结果与验证集标签进行对比给出准确率 accuracy、F1值 f1_score、auc曲线下面积 roc_auc_score,判断模型效果。值得注意的是,模型调参是在训练数据集上进行,并不能保证一定会在测试集得到更好的体现,即在预测时的泛化误差并不一定会有减小。
其中 metrics_sklearn()feature_importance_selected()两个模块的内容在下方单独写出,便于测试集对模型评估的使用

def model_fit():
    """模型训练"""

    model = XGBClassifier(learning_rate=0.3, n_estimators=50, max_depth=2, min_child_weight=1,
                          subsample=1, colsample_bytree=1, gamma=0.1, reg_alpha=0.01, reg_lambda=3)
    model.fit(X_train, y_train)

    y_pred = model.predict(X_test)
    y_test_ = y_test.values
    print('y_test:', y_test_)
    print('y_pred:', y_pred)

    y_pred_proba = model.predict_proba(X_test)

    y_pred_proba_ = []
    for i in y_pred_proba.tolist():
        y_pred_proba_.append(i[1])
    print('y_pred_proba:', y_pred_proba_)

    metrics_sklearn(y_test_, y_pred)

    feature_importance_selected(model)

    return model

模型评估:准确率、精准率、召回率、F1值、AUC值的标准调用。

def metrics_sklearn(y_valid, y_pred_):
    """模型对验证集和测试集结果的评分"""

    accuracy = accuracy_score(y_valid, y_pred_)
    print('Accuracy:%.2f%%' % (accuracy * 100))

    precision = precision_score(y_valid, y_pred_)
    print('Precision:%.2f%%' % (precision * 100))

    recall = recall_score(y_valid, y_pred_)
    print('Recall:%.2f%%' % (recall * 100))

    f1 = f1_score(y_valid, y_pred_)
    print('F1:%.2f%%' % (f1 * 100))

    auc = roc_auc_score(y_valid, y_pred_)
    print('AUC:%.2f%%' % (auc * 100))

    fpr, tpr, thresholds = roc_curve(y_valid, y_pred_)
    ks = max(abs(fpr - tpr))
    print('KS:%.2f%%' % (ks * 100))

这里利用 model.get_booster().get_fscore() 提取特征重要性为字典格式, plot_importance绘制图形。特殊强调:特征重要性保存到本地的作用是特征的筛选,当数据特征很多时,实际参与分类的特征可能很少。例如:原数据有1000个特征,只有90个有重要性,且重要性大于5的只有30个,其他910个特征并未参与模型的建立和预测。此时可以只取部分有特征重要性的特征(90)或重要性大于某一阈值的特征(30个)入模参与预测。

def feature_importance_selected(clf_model):
    """模型特征重要性提取与保存"""

    feature_importance = clf_model.get_booster().get_fscore()
    feature_importance = sorted(feature_importance.items(), key=lambda x: x[1], reverse=True)
    feature_ipt = pd.DataFrame(feature_importance, columns=['特征名称', '重要性'])
    feature_ipt.to_csv('feature_importance.csv', index=False)
    print('特征重要性:', feature_importance)

    plot_importance(clf_model)
    plt.show()

3.2模型训练与保存

模型保存通过 save_model实现,保存为 .model文件,模型的保存是对训练好的模型结果的持久化。另外,这里也实现了 dump_model方法保存模型为 .txt格式,便于模型分析、优化和提供可解释性(可解释性详见《Graphviz绘制模型树》,本文不再赘述)。

def model_save_type(clf_model):

    clf_model.save_model('xgboost_classifier_model.model')

    clf = clf_model.get_booster()
    clf.dump_model('dump.txt')

实际作业中并不会每次都去训练模型然后应用,加载已保存的模型是常规操作

if __name__ == '__main__':
"""
        模型训练、评分与保存
        结论:训练集k折交叉验证带来的模型评分提升,未必会在测试集上得到提升
"""

    model_xgbclf = model_fit()

    model_save_type(model_xgbclf)

模型验证集预测结果及得分

XGBoost模型调参、训练、保存、评估和预测
特征重要性结果的绘图展示
XGBoost模型调参、训练、保存、评估和预测
特征重要性结果已保存到当前目录下的 feature_importance.csv 文件内,演示用例特征较少,实际项目中会碰到几百个特征,保存起来就很必要了。

四.模型加载与预测

模型加载过程,需要使用到 Booster,不同于常规的load_model方式。模型预测打印预测结果 y_pred及类别概率 y_pred_proba

def model_load(model, x_transform):

    clf = xgb.XGBClassifier()
    booster = xgb.Booster()
    booster.load_model(model)
    clf._Booster = booster

    y_pred = [round(value) for value in clf.predict(x_transform)]
    y_pred_proba = clf.predict_proba(x_transform)
    print('y_pred:', y_pred)
    print('y_pred_proba:', y_pred_proba)

预测数据也要是数值格式, ndarray的格式可以直接用于预测,注意[[]],一定是两层,即使只有一组数据也要写成两层括号

if __name__ == '__main__':
"""
        模型加载与数据预测
        结论:持久化的模型用来预测数据结果,随着业务的变化模型也需要随之调整
        补充:如果有测试集数据,与此预测相同,另外可通过 metrics_sklearn() 模块来进行预测结果评估,以此来判断模型可靠性
"""
    x_pred = np.array([[0.63, 0.72, 7.6, 85.4, 40, 38, 0.598787852, 0.474784735],
                       [0.39, 0.42, 6.2, 95.4, 39, 38, 0.71287283, 0.5838785491],
                       [0.29, 0.32, 20.43, 92.7, 41, 39, 0.498825525, 0.476575973]])
    model_save_load('xgboost_classifier_model.model', x_pred)

预测结果如下

XGBoost模型调参、训练、保存、评估和预测

五.附加-模型的评估与理解

1.关于XGBoost的原理内容,
《XGBoost算法原理及基础知识》 ,包括集成学习方法,XGBoost模型、目标函数、算法,公式推导等;

2.关于分类任务的评估指标值详解,
《分类任务评估1——推导sklearn分类任务评估指标》,其中包含了详细的推理过程;
《分类任务评估2——推导ROC曲线、P-R曲线和K-S曲线》,其中包含ROC曲线、P-R曲线和K-S曲线的推导与绘制;

3.关于XGBoost模型中树的绘制和模型理解,
《Graphviz绘制模型树1——软件配置与XGBoost树的绘制》,包含Graphviz软件的安装和配置,以及to_graphviz()和plot_trees()两个画图函数的部分使用细节;
《Graphviz绘制模型树2——XGBoost模型的可解释性》,从模型中的树着手解释XGBoost模型,并用EXCEL构建出模型。

4.关于XGBoost实践,
《机器学习实践(1.1)XGBoost分类任务》,包含二分类、多分类任务以及多分类的评估方法;
《机器学习实践(1.2)XGBoost回归任务》,包含回归任务模型训练、评估(R2、MSE)。

❤️ 机器学习内容持续更新中… ❤️

声明:本文所载信息不保证准确性和完整性。文中所述内容和意见仅供参考,不构成实际商业建议,可收藏可转发但请勿转载,如有雷同纯属巧合。

Original: https://blog.csdn.net/LMTX069/article/details/124279643
Author: 赫加青空
Title: XGBoost模型调参、训练、保存、评估和预测

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/669487/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球