xgboost 逻辑回归:objective参数(reg:logistic,binary:logistic,binary:logitraw,)对比分析
一、问题
熟悉xgboost的小伙伴都知道,它在训练模型时,有train()方法和fit()方法,两种方法都是用于构建模型的,然而在使用过程中有什么不同的地方呢,这篇文章带领大家一起来看一下。train方法使用如下:
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'reg:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
train_pred=model.predict(xgb.DMatrix(x_test))
而fit方法是直接使用xgboost封装好的XGBClassifier或者XGBRegressor时使用:
-
model = XGBClassifier(
-
learning_rate= 0.1,
-
n_estimators= 20,
-
max_depth= 4,
-
objective= 'binary:logistic',
-
seed= 27,
-
silent= 0
-
)
-
model.fit(x_train,y_train,verbose= True)
-
fit_pred=model.predict(x_test)
-
print fit_pred
相同的数据集,相同的参数得到的预测值却是不一样的,fit_pred的值是0,1的具体的预测标签,train_pred的值是0-1之间的概率值;为什么结果是不一样的呢?如何把0-1之间的概率值映射成0,1标签呢?这个后面揭晓,我们先看下,xgboost中用于做逻辑回归的objective的参数都有哪些,得到预测结果有什么不同!
二、objective参数比较
xgboost官方文档关于逻辑回归objective有三个参数,如下:
1、reg:logistic PK binary:logistic
实际上reg:logistic,binary:logistic都是输出逻辑回归的概率值,实验过程如下:
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'binary:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
bin_log_pred=model.predict(xgb.DMatrix(x_test))
-
# print bin_log_pred
-
###################################
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'reg:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
reg_log_pred=model.predict(xgb.DMatrix(x_test))
-
# print reg_log_pred
-
count= 0
-
for i in np.arange(0,len(reg_log_pred)):
-
if (reg_log_pred[i]==bin_log_pred[i]):
-
count+= 1
-
print "len:",len(reg_log_pred)
-
print "count:",count
-
if count==len(reg_log_pred):
-
print "true"
-
else:
-
print "false"
输出结果:
2、reg:logistic PK binary:logitraw
然后我们再来看下binary:logitraw参数,由文档可以看出这个参数得到的是集成树模型最后输出的得分,即转换成概率值之前的值,我们知道xgboost这类集成树算法用到的回归树,这就决定了它本身就是用来做回归的,调整后可以用来做分类,这里的调整是指通过sigmoid函数处理后来做二分类,通过softmax函数处理后来做多分类。于是,我们定义一个sigmoid函数,把binary:logitraw参数输出的得分通过sigmoid函数映射成概率值,对比下是否和reg:logistic参数得到的概率值是一样的。
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'reg:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
reg_log_pred=model.predict(xgb.DMatrix(x_test))
-
# print reg_log_pred
-
###################################
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'binary:logitraw',
-
# 'n_jobs': 4,
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
logitraw_pred=model.predict(xgb.DMatrix(x_test))
-
print logitraw_pred
-
def sigmoid(x):
-
return 1./(1.+np.exp(-x))
-
y=sigmoid(logitraw_pred)
-
print y
-
count= 0
-
for i in np.arange(0,len(reg_log_pred)):
-
if (reg_log_pred[i]==y[i]):
-
count+= 1
-
print len(reg_log_pred)
-
print count
-
if count==len(reg_log_pred):
-
print "true"
-
else:
-
print "false"
输出结果:
3、总结
上述实验,通过使用相同的数据集,相同的参数(除了objective参数,其他相同),研究了逻辑回归的objective的三种不同参数的输出结果,得到如下结论:
1、binary:logistic和 'objective': 'reg:logistic'的输出是一样的,都是预测的概率
2、binary:logitraw是输出的得分,用sigmoid()函数处理后就和上述两个概率值一致
三、XGBClassifier都做了些什么
回到我们一开始的问题,xgboost train()方法得到概率值之后,如何处理成最终的0,1标签呢?
这个工作应该是在XGBClassifier中完成的,我们进行下列实验进行验证:
-
model = XGBClassifier(
-
learning_rate= 0.1,
-
n_estimators= 20,
-
max_depth= 4,
-
objective= 'binary:logistic',
-
seed= 27,
-
silent= 0
-
)
-
model.fit(x_train,y_train,verbose= True)
-
fit_pred=model.predict(x_test)
-
print fit_pred
-
#######################
-
params ={ 'learning_rate': 0.1,
-
'max_depth': 4,
-
'objective': 'reg:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train),num_boost_round= 20)
-
train_pred=model.predict(xgb.DMatrix(x_test))
-
#概率值的阈值假设为0.5,小于等于0.5的预测为0,否则预测为1
-
for i in np.arange(0,len(train_pred)):
-
if train_pred[i]<0.5:
-
train_pred[i]= 0
-
else:
-
train_pred[i]= 1
-
print train_pred
-
print type(train_pred)
-
count= 0
-
for i in np.arange(0,len(train_pred)):
-
if (train_pred[i]==fit_pred[i]):
-
count+= 1
-
print len(train_pred)
-
print count
-
if count==len(train_pred):
-
print "true"
-
else:
-
print "false"
输出的结果:
由此可见我们的假设是成立的,XGBClassifier里就是把预测的概率值,取阈值0.5,小于这个值的为0,大于这个值的为1,实验过程中还发现并没有等于0.5的概率值,我的设想是对于一个二分类问题,把概率预测成0.5没有任何意义o(* ̄︶ ̄*)o
为了增加可信度,我们把训练数据放到模型里进行预测,并对于,train和fit输出的预测结果,结果如下: