spark xgboost损失函数和评价函数的修改

spark xgboost自定义损失函数和评价函数

一、spark xgboost自定义损失函数

image

xgboost定义损失函数的是通过setCustomObj定义,要想定义损失函数,首先我们得知道其接收的数据类型是什么类型的


image

可见它需要的数据类型是ObjectiveTrait的实现类。


image

可见,我们只需重载getGradient方法即可。代码如下
/**
    * 自定义损失函数
    */
  class  MyObject extends ObjectiveTrait {
    @Override
    def getGradient(predicts: Array[Array[Float]], dtrain: DMatrix): List[Array[Float]] = {
     var penalty  = 1.0f
      val weight: Array[Float] = dtrain.getWeight
      //定义惩罚系数和指数
      //指数
      val label = dtrain.getLabel //得到训练数据的lable值
      val gradArr  = new Array[Float](label.length)
      val hasArr = new Array[Float](label.length)
      val resList = new ListBuffer[Array[Float]]
      for (i: Int <- label.indices) {
        //每个样本计算其一阶导数
        gradArr(i) = -penalty*label(i) / predicts(i)(0) + (1 - label(i) )/ (1 - predicts(i)(0))
        gradArr(i) = gradArr(i) * weight(i)

        hasArr(i) = penalty *(label(i) / Math.pow(predicts(i)(0), 2)).toFloat
        +(1 - label(i))/ Math.pow(1 - predicts(i)(0), 2) //每个样本计算其二阶导数
        hasArr(i) = hasArr(i) * weight(i)

        println(gradArr(i))
        println(hasArr(i))
      }
      resList.append(gradArr)
      resList.append(hasArr)
      resList.toList
    }
  }

掉坑记录1:以后list的长度和样本的长度一样,然后array是二维的。实际上是list的长度是2,list(0)放的是一阶导数的值,list(1)是二阶导数的值

你可能感兴趣的:(spark xgboost损失函数和评价函数的修改)