[机器学习]xgboost多分类实战

4,514 阅读3分钟

参考网址

blog.csdn.net/HHTNAN/arti…

“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

“multi:softmax” 和 “multi:softprob”的区别是什么

multi:softmax是使用softmax后产生的分类结果,而multi:softprob是输出的概率矩阵。

我们这里以标签为0,1,2的三分类数据为例,前者输出的结果是一维数据,0,1,2的分类标签;
后者输出的是ndata*num_class的概率矩阵(n为测试数据的条数,num_class是数据的类别),
不管是直接返回诊断类型,还是返回各类型的概率,然后取概率最大的那个对应的类型的index,结果都是一样的。
如下图所示:

image.png

1/实战1(给出预测出类别)

xgboost官方给出的例子是根据34个特征识别6种皮肤病。
这是一个6分类问题。
# 第一种情况:给出属于哪个类别
# multi:softmax
 
import xgboost as xgb # 这里用的是原生接口(陈天奇)
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 
data = np.loadtxt('dermatology.data.txt', 
                 delimiter=',',
                 converters={33: lambda x:int(x == '?'), 34: lambda x:int(x)-1} )
sz = data.shape # 数据的结构

x = data[:,0:33] # 前33列,是特征列
y = data[:,34]   # 最后一列是标签列,target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(x,y,
                                                    test_size=0.3,
                                                    random_state=0)

# 加载numpy的数组到DMatrix对象
xg_train = xgb.DMatrix( X_train, label=y_train ) 
xg_test = xgb.DMatrix( X_test, label=y_test )

# 超参数
param = {}
param['objective'] = 'multi:softmax'  
param['num_class'] = 6 # 6个类别
param['eta'] = 0.1
param['max_depth'] = 6
param['silent'] = 1
param['nthread'] = 4 
# 这里的并行是指:在同一棵树中,同一个节点选择哪个特征进行划分的时候,可以并行计算gini系数或者mse均方差

watchlist = [ (xg_train,'train'), (xg_test, 'test') ]
num_round = 6

# 训练模型
bst = xgb.train(param, # 参数
                xg_train,  # 训练数据
                num_round,  # 弱学习器的个数,weak_learner
                watchlist );


# 通过测试数据,检测模型的优劣
pred = bst.predict( xg_test );
print ('predicting, classification error=%f' % (sum( int(pred[i]) != y_test[i] for i in range(len(y_test))) / float(len(y_test)) ))

2/实战2(给出属于每个类别的概率)

# 
# multi:softprob
param['objective'] = 'multi:softprob'

bst = xgb.train(param, 
                xg_train,
                num_round,
                watchlist );
                
# Note: this convention has been changed since xgboost-unity
# get prediction, this is in 1D array, need reshape to (ndata, nclass)
yprob = bst.predict( xg_test ).reshape( y_test.shape[0], 6 )
# 从预测的6组中选择最大的概率进行输出
ylabel = np.argmax(yprob, axis=1)  # return the index of the biggest pro

print ('predicting, classification error=%f' % (sum( int(ylabel[i]) != y_test[i] for i in range(len(y_test))) / float(len(y_test)) ))

# 最小二乘方差
mse2 = mean_squared_error(y_test,ylabel)

print(mse2)

from sklearn import metrics 
print ('ACC: %.4f' % metrics.accuracy_score(y_test,ylabel))
print(metrics.confusion_matrix(y_test,ylabel))

# 显示特征的重要程度
plot_importance(bst)
plt.show()

image.png