当前位置:   article > 正文

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

xgboost多分类

在应用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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

使用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))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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

  • 1
  • 2
  • 3
  • 4

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

4. 模型的训练

4.1 数据源及重要特征

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

随着数据维度和特征的增加,模型的准确度也在提高。如下图所示,数据增加了2个维度。
在这里插入图片描述
看到“Feature Importance”图的代码如下所示:

# 显示重要特征
plot_importance(model)
plt.show()
  • 1
  • 2
  • 3

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]
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

关于优化,后续将参考寒小阳的博文《机器学习系列(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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

参考:
[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月

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号