应用XGboost实现多分类模型实践

栏目: 编程工具 · 发布时间: 6年前

内容简介:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaoyw/article/details/88970481

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaoyw/article/details/88970481

在应用XGBoost算法进行多分类应用时,发生了如下错误:

XGBoostError: b’value 0 for Parameter num_class should be greater equal to 1’

意思是,参数num_class的xgboost sklearn包装值0应该大于1。

忽然,我理解了参数及其设置,这里的”num_class“参数,与”objective“参数匹配,本案例是多分类应用,那么”objective“参数设置为”multi:softmax“,同时,”num_class“参数设置为”4“(本文用到的4个分类,0、1、2、3,分别代表着0-正常,1- 抽油杆断,2- 供液不足,3- 气影响,参考[3])。

1. 输入数据

本案例数据源为csv格式(csv格式为每个数据由逗号“,”分隔)。

0.29,0.31,32.8,92.5,22,20,0.7750820447097237,0.5326322957198866
0.61,0.76,7.8,84.4,42,40,0.6650599517190358,0.47773242152197465
0.21,0.23,19.8,84.8,31,30,0.6798212287221709,0.6725660513935667
0.25,0.28,88.1,94.3,75,74,0.529969222169283,0.5878974216397194
0.45,0.48,16.5,99.9,77,75,0.6958968659268767,0.7047297521312826
0.4,0,39.2,94.2,36,32,0.7301196680207003,0.48968041620245173

数据的含义分别是“油压”、“套压”、“产液量”、“含水率”、“上行电流”、“下行电流”,以及数据特征变换值“欧几里得距离”、“功图面积与基准面积的比值”。

使用numpy中的 loadtxt(‘gtdata0010.csv’, delimiter=",")读取csv格式数据进入到List中。

注:输入数据是数值型。XGBoost 和 CatBoost 以及 LGBM 算法不同,XGBoost 本身无法处理分类变量,而是像随机森林一样,只接受数值数据。因此在将分类数据传入 XGBoost 之前,必须通过各种编码方式:例如标记编码、均值编码或独热编码对数据进行处理。

由于每个井的井号是非数值型,而且只是个分类标识号,无数值意义。为了区分各个井的差别,体现相同的井,使用井的描述参数,例如:泵径、沉没度、下泵深度等等。

2. 模型及其参数

XGBoost模型objective说明:

  • “reg:linear” —— 线性回归。
  • “reg:logistic”—— 逻辑回归。
  • “binary:logistic”—— 二分类的逻辑回归问题,输出为概率。
  • “binary:logitraw”—— 二分类的逻辑回归问题,输出的结果为wTx。
  • “count:poisson”—— 计数问题的poisson回归,输出结果为poisson分布。在poisson回归中,max_delta_step的缺省值为0.7。(used to safeguard optimization)
  • “multi:softmax” –让XGBoost采用softmax目标函数处理多分类问题,同时需要设置参数num_class(类别个数)
  • “multi:softprob” –和softmax一样,但是输出的是ndata * nclass的向量,可以将该向量reshape成ndata行nclass列的矩阵。输出每(列)个数据表示样本所属于每个类别的概率。
  • “rank:pairwise” –set XGBoost to do ranking task by minimizing the pairwise loss
params ={'learning_rate': 0.1,
          'max_depth': 5,
          'num_boost_round':20,
          'objective': 'multi:softmax',
          'random_state': 27,
          'silent':0,
          'num_class':4
        }
model = xgb.train(params,xgb.DMatrix(X_train, y_train))#,num_boost_round=20)
y_pred=model.predict(xgb.DMatrix(X_test))

3. 预测输出

在多分类预测模型下,预测输出分为两种情况:一是直接输出分类,参数’objective’为’multi:softmax’;另一种是输出各个分类的概率,参数’objective’为’multi:softprob’。本案例使用输出各个分类概率,贴近实际工作场景,如出现一种工况,计算机给出“供液不足”的概率是78%、“气影响”的概率是21%、其他…。

通过取出最大概率的分类,则可以为预测分析结果,如下代码所示:

y_pred=model.predict(xgb.DMatrix(X_test))

yprob = np.argmax(y_pred, axis=1)  # return the index of the biggest pro

注:训练模型时,输入的标签(Lable)为单列分类数字,例如本案例分类为[0,1,2,3],通过代码中“np.argmax(y_pred, axis=1)”取到最大概率值的位置为结果。

4. 模型的训练

4.1 数据源及重要特征

对于数据源,分成训练数据及其对应的标签,例如本案例中的“gtdata0010.csv”为训练数据的自变量X,“gtlable001.csv”为训练数据的因变量Y。数据源准备,先由少量再到大量数据,数据维度和特征也逐步扩大。

随着数据维度和特征的增加,模型的准确度也在提高。如下图所示,数据增加了2个维度。

应用XGboost实现多分类模型实践

看到“Feature Importance”图的代码如下所示:

# 显示重要特征
plot_importance(model)
plt.show()

4.2. 训练参数优化

数据预处理、特征工程、调参对Xgboost的效果有着非常重要的影响。

在这里只介绍Tree,重点是调优“learning_rate”学习率和“max_dept”构建树的深度,一般学习率中0.1 ~ 1间调整,而树的深度是随着数据量和维度增加而增加,我实验的经历是从5开始,已经到24了,再增大的效果是反而下降。网上推荐“max_dept”取值为6 ~ 10。

params ={'learning_rate': 0.4,
          'max_depth': 20,                # 构建树的深度,越大越容易过拟合
          'num_boost_round':2000,
          'objective': 'multi:softprob', # 多分类的问题
          'random_state': 7,
          'silent':0,
          'num_class':4,                 # 类别数,与 multisoftmax 并用
          'eta':0.8                      #为了防止过拟合,更新过程中用到的收缩步长。eta通过缩减特征 的权重使提升计算过程更加保守。缺省值为0.3,取值范围为:[0,1]
        }

关于优化,后续将参考寒小阳的博文 《机器学习系列(12)_XGBoost参数调优完全指南(附 Python 代码)》 , 使用xgb.cv ()函数交叉验证,优化参数。

5. 模型训练的应用实践代码

'''
Created on 2019年4月1日

@author: xiaoyw
'''
from xgboost import plot_importance
from matplotlib import pyplot as plt

import xgboost as xgb
from numpy import loadtxt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import numpy as np
# load data
dataset = loadtxt('gtdata0010.csv', delimiter=",")
# split data into X and y
X = dataset[:,:8]
dataset = loadtxt('gtlable001.csv', delimiter=",")
Y = dataset[:,1]

# split data into train and test sets
seed = 7
test_size = 0.2
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)

params ={'learning_rate': 0.4,
          'max_depth': 20,                # 构建树的深度,越大越容易过拟合
          'num_boost_round':2000,
          'objective': 'multi:softprob', # 多分类的问题
          'random_state': 7,
          'silent':0,
          'num_class':4,                 # 类别数,与 multisoftmax 并用
          'eta':0.8                      #为了防止过拟合,更新过程中用到的收缩步长。eta通过缩减特征 的权重使提升计算过程更加保守。缺省值为0.3,取值范围为:[0,1]
        }
model = xgb.train(params,xgb.DMatrix(X_train, y_train))
y_pred=model.predict(xgb.DMatrix(X_test))

model.save_model('testXGboostClass.model')  # 保存训练模型

yprob = np.argmax(y_pred, axis=1)  # return the index of the biggest pro

predictions = [round(value) for value in yprob]

# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))

# 显示重要特征
plot_importance(model)
plt.show()

6. 关于fit()与train()的区别补充

这段是困惑的内容,以下是摘自网络参考文档,还未展开研究。

1、xgboost.XGBClassifier()利用函数参数设置模型参数

XGBClassifier()使用sklearn接口(推荐) ,XGBClassifier - 是xgboost的sklearn包。这个包允许我们像GBM一样使用Grid Search 和并行处理。

2、xgboost.train()利用param列表设置模型参数。

原始的xgboost,xgb - 直接引用xgboost。 有“cv”函数。

参考代码,还抽出时间实验,先收录到本文中再用[2]。

clf = XGBClassifier(
    n_estimators=20,  # 迭代次数
    learning_rate=0.1,  # 步长
    max_depth=5,  # 树的最大深度
    min_child_weight=1,  # 决定最小叶子节点样本权重和
    silent=1,  # 输出运行信息
    subsample=0.8,  # 每个决策树所用的子样本占总样本的比例(作用于样本)
    colsample_bytree=0.8,  # 建立树时对特征随机采样的比例(作用于特征)典型值:0.5-1
    objective='multi:softmax',  # 多分类!!!!!!
    num_class=3,
    nthread=4,
    seed=27)
print "training..."
clf.fit(x_train, y_train, verbose=True)
fit_pred = clf.predict(x_test)
print fit_pred
xgb_params = {
    'learning_rate': 0.1,  # 步长
    'max_depth': 5,  # 树的最大深度
    'objective': 'multi:softmax',
    'num_class': 3,
    'min_child_weight': 1,  # 决定最小叶子节点样本权重和,如果一个叶子节点的样本权重和小于min_child_weight则拆分过程结束。
    'silent': 0,  # 输出运行信息
    'subsample': 0.8,
    'colsample_bytree': 0.8,  # 建立树时对特征随机采样的比例(作用于特征)典型值:0.5-1
    'nthread': 4,
    'seed': 27}
print "training..."
model = xgb.train(xgb_params, xgb.DMatrix(x_train, y_train), num_boost_round=20)
train_pred = model.predict(xgb.DMatrix(x_test))
count = 0
print train_pred
# 判断train_pred和fit_pred是否一致
for i in np.arange(0, len(train_pred)):
    if (train_pred[i] == fit_pred[i]):
        count += 1
print "len:", len(train_pred)
print "count:", count
if count == len(train_pred):
    print "true"
else:
    print "false"

参考:

[1]《XGBOOST从原理到实战:二分类 、多分类》 CSDN博客 DemonHunter211 2018年7月

[2]《xgboost 多分类:objective参数(reg:linear,multi:softmax,multi:softprob)对比分析》 CSDN博客 phyllisyuell 2018年7月

[3]《TensorFlow CNN卷积神经网络实现工况图分类识别(一)》 CSDN博客 肖永威 2019年3月

[4]《xgboost.XGBClassifier, xgboost.train()》 CSDN博客 liulina603 2017年12月

[5]《XGBoost算法应用入门学习实践》 CSDN博客 肖永威 2018年6月


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Rationality for Mortals

Rationality for Mortals

Gerd Gigerenzer / Oxford University Press, USA / 2008-05-02 / USD 65.00

Gerd Gigerenzer's influential work examines the rationality of individuals not from the perspective of logic or probability, but from the point of view of adaptation to the real world of human behavio......一起来看看 《Rationality for Mortals》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具