xgboost 逻辑回归:objective参数(reg:logistic,binary:logistic,binary:logitraw,)对比分析

xgboost 逻辑回归:objective参数(reg:logistic,binary:logistic,binary:logitraw,)对比分析

一、问题

熟悉xgboost的小伙伴都知道,它在训练模型时,有train()方法和fit()方法,两种方法都是用于构建模型的,然而在使用过程中有什么不同的地方呢,这篇文章带领大家一起来看一下。train方法使用如下:

  1.  
    params ={'eta': 0.1,
  2.  
    'max_depth': 4,
  3.  
    'num_boost_round':20,
  4.  
    'objective': 'reg:logistic',
  5.  
    'random_state': 27,
  6.  
    'silent':0
  7.  
    }
  8.  
    model = xgb.train(params,xgb.DMatrix(x_train, y_train))
  9.  
    train_pred=model.predict(xgb.DMatrix(x_test))

而fit方法是直接使用xgboost封装好的XGBClassifier或者XGBRegressor时使用:

  1.  
    model = XGBClassifier(
  2.  
    learning_rate=0.1,
  3.  
    n_estimators=20,
  4.  
    max_depth=4,
  5.  
    objective='binary:logistic',
  6.  
    seed=27,
  7.  
    silent=0
  8.  
    )
  9.  
    model.fit(x_train,y_train,verbose=True)
  10.  
    fit_pred=model.predict(x_test)
  11.  
    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都是输出逻辑回归的概率值,实验过程如下:

  1.  
    params ={'eta': 0.1,
  2.  
    'max_depth': 4,
  3.  
    'num_boost_round':20,
  4.  
    'objective': 'binary:logistic',
  5.  
    'random_state': 27,
  6.  
    'silent':0
  7.  
    }
  8.  
    model = xgb.train(params,xgb.DMatrix(x_train, y_train))
  9.  
    bin_log_pred=model.predict(xgb.DMatrix(x_test))
  10.  
    # print bin_log_pred
  11.  
    ###################################
  12.  
    params ={'eta': 0.1,
  13.  
    'max_depth': 4,
  14.  
    'num_boost_round':20,
  15.  
    'objective': 'reg:logistic',
  16.  
    'random_state': 27,
  17.  
    'silent':0
  18.  
    }
  19.  
    model = xgb.train(params,xgb.DMatrix(x_train, y_train))
  20.  
    reg_log_pred=model.predict(xgb.DMatrix(x_test))
  21.  
    # print reg_log_pred
  22.  
    count=0
  23.  
    for i in np.arange(0,len(reg_log_pred)):
  24.  
    if (reg_log_pred[i]==bin_log_pred[i]):
  25.  
    count+=1
  26.  
    print "len:",len(reg_log_pred)
  27.  
    print "count:",count
  28.  
    if count==len(reg_log_pred):
  29.  
    print "true"
  30.  
    else:
  31.  
    print "false"

输出结果:

2、reg:logistic  PK  binary:logitraw 

然后我们再来看下binary:logitraw参数,由文档可以看出这个参数得到的是集成树模型最后输出的得分,即转换成概率值之前的值,我们知道xgboost这类集成树算法用到的回归树,这就决定了它本身就是用来做回归的,调整后可以用来做分类,这里的调整是指通过sigmoid函数处理后来做二分类,通过softmax函数处理后来做多分类。于是,我们定义一个sigmoid函数,把binary:logitraw参数输出的得分通过sigmoid函数映射成概率值,对比下是否和reg:logistic参数得到的概率值是一样的。

  1.  
    params ={'eta': 0.1,
  2.  
    'max_depth': 4,
  3.  
    'num_boost_round':20,
  4.  
    'objective': 'reg:logistic',
  5.  
    'random_state': 27,
  6.  
    'silent':0
  7.  
    }
  8.  
    model = xgb.train(params,xgb.DMatrix(x_train, y_train))
  9.  
    reg_log_pred=model.predict(xgb.DMatrix(x_test))
  10.  
    # print reg_log_pred
  11.  
    ###################################
  12.  
    params ={'eta': 0.1,
  13.  
    'max_depth': 4,
  14.  
    'num_boost_round':20,
  15.  
    'objective': 'binary:logitraw',
  16.  
    # 'n_jobs': 4,
  17.  
    'random_state': 27,
  18.  
    'silent':0
  19.  
    }
  20.  
    model = xgb.train(params,xgb.DMatrix(x_train, y_train))
  21.  
    logitraw_pred=model.predict(xgb.DMatrix(x_test))
  22.  
    print logitraw_pred
  23.  
    def sigmoid(x):
  24.  
    return 1./(1.+np.exp(-x))
  25.  
    y=sigmoid(logitraw_pred)
  26.  
    print y
  27.  
    count=0
  28.  
    for i in np.arange(0,len(reg_log_pred)):
  29.  
    if (reg_log_pred[i]==y[i]):
  30.  
    count+=1
  31.  
    print len(reg_log_pred)
  32.  
    print count
  33.  
    if count==len(reg_log_pred):
  34.  
    print "true"
  35.  
    else:
  36.  
    print "false"

输出结果:

3、总结

上述实验,通过使用相同的数据集,相同的参数(除了objective参数,其他相同),研究了逻辑回归的objective的三种不同参数的输出结果,得到如下结论:

1、binary:logistic和 'objective': 'reg:logistic'的输出是一样的,都是预测的概率

2、binary:logitraw是输出的得分,用sigmoid()函数处理后就和上述两个概率值一致

三、XGBClassifier都做了些什么

回到我们一开始的问题,xgboost train()方法得到概率值之后,如何处理成最终的0,1标签呢?

这个工作应该是在XGBClassifier中完成的,我们进行下列实验进行验证:

  1.  
    model = XGBClassifier(
  2.  
    learning_rate=0.1,
  3.  
    n_estimators=20,
  4.  
    max_depth=4,
  5.  
    objective='binary:logistic',
  6.  
    seed=27,
  7.  
    silent=0
  8.  
    )
  9.  
    model.fit(x_train,y_train,verbose=True)
  10.  
    fit_pred=model.predict(x_test)
  11.  
    print fit_pred
  12.  
    #######################
  13.  
    params ={'learning_rate': 0.1,
  14.  
    'max_depth': 4,
  15.  
    'objective': 'reg:logistic',
  16.  
    'random_state': 27,
  17.  
    'silent':0
  18.  
    }
  19.  
    model = xgb.train(params,xgb.DMatrix(x_train, y_train),num_boost_round=20)
  20.  
    train_pred=model.predict(xgb.DMatrix(x_test))
  21.  
    #概率值的阈值假设为0.5,小于等于0.5的预测为0,否则预测为1
  22.  
    for i in np.arange(0,len(train_pred)):
  23.  
    if train_pred[i]<0.5:
  24.  
    train_pred[i]=0
  25.  
    else:
  26.  
    train_pred[i]=1
  27.  
    print train_pred
  28.  
    print type(train_pred)
  29.  
    count=0
  30.  
    for i in np.arange(0,len(train_pred)):
  31.  
    if (train_pred[i]==fit_pred[i]):
  32.  
    count+=1
  33.  
    print len(train_pred)
  34.  
    print count
  35.  
    if count==len(train_pred):
  36.  
    print "true"
  37.  
    else:
  38.  
    print "false"

输出的结果:

由此可见我们的假设是成立的,XGBClassifier里就是把预测的概率值,取阈值0.5,小于这个值的为0,大于这个值的为1,实验过程中还发现并没有等于0.5的概率值,我的设想是对于一个二分类问题,把概率预测成0.5没有任何意义o(* ̄︶ ̄*)o

为了增加可信度,我们把训练数据放到模型里进行预测,并对于,train和fit输出的预测结果,结果如下:

posted @ 2019-02-20 08:38  Roygood  阅读(7479)  评论(0编辑  收藏  举报