【问题标题】:How to calculate the log loss metric in scala/spark?如何计算 scala/spark 中的对数损失指标?
【发布时间】:2019-11-09 05:29:52
【问题描述】:

我已经训练了一个二元分类器 (XGBoostClassifier) 模型,并且在我的结果数据框中有两列:PREDICTED_COLTARGET_COL。例如,我可以通过以下方式计算 areaUnderROC:

val metrics = new BinaryClassificationMetrics(df.select(col(PREDICTED_COL), col(TARGET_COL)).rdd.map(row => (row.getDouble(0), row.getInt(1).toDouble)))
val auc = metrics.areaUnderROC()

但是,没有相应/简单的方法来计算对数损失指标。该怎么做?

注意:我尝试使用 org.apache.spark.mllib.tree.loss.LogLoss,但该函数不接受任何参数(例如我的 PREDICTED_COL 和 TARGET_COL),所以不知道如何使用它。

这里是 LogLoss 公式:

【问题讨论】:

    标签: scala apache-spark data-science xgboost


    【解决方案1】:

    你可以只实现公式:

    val df_ll = df.withColumn("logloss", -($"target_col" * log($"predicted_col") + (lit(1) - $"target_col") * log(lit(1) - $"predicted_col")))
    

    请注意,我们仅使用 spark.sql.functions 中的内置函数,这意味着我们可以获得相当好的性能(比 UDF 更好)

    【讨论】:

    • 谢谢!剩下的唯一部分是计算样本 logloss 的平均值(这是我们从您的代码中得到的,即一列双精度数),如下所示:val loglossA = df_ll.agg(mean("logloss").alias("ll")).collect() 看起来对吗?
    【解决方案2】:

    所以这里有一个方便的函数来计算给定数据帧的对数损失(TARGET_COL 是ground truth aka label,PREDICTED_COL 是模型返回的预测):

    def calcualteLogLoss (df: Dataset[Row]): Double = {
        val df2 = df.withColumn("logloss",
          col(TARGET_COL).multiply(lit(-1))
            .multiply(log(col(PREDICTED_COL)))
          .minus(
            lit(1.0).minus(col(TARGET_COL))
              .multiply(log(lit(1).minus(col(PREDICTED_COL))))
          )
        )
    
        // calculate desired logloss as average of all samples
        val loglossA = df2.agg(mean("logloss").alias("ll")).collect()
        var logloss = -1d
        if (loglossA != null && loglossA.length > 0){
          val loglossB = loglossA.head
          if (loglossB != null && loglossB.length > 0 && loglossB.get(0) != null) {
            logloss = loglossB.getDouble(0)
          }
        }
    
        logloss
      }
    

    【讨论】:

      【解决方案3】:

      这个简单的函数可以用来获取log loss。

      from pyspark.sql.types import *
      import pyspark.sql.functions as F
      
      def logloss(predictions, label_column):
              """
              function for calculation of log loss
              :param spark.DataFrame predictions : model predicted spark dataframe
              :param string label_column : column name containing true labels
              :return float
              """
              get_first_element = F.udf(lambda v:float(v[1]), FloatType())
              predictions = predictions.select(F.col(label_column).alias("label"), "probability")
              predictions = predictions.withColumn("true_prediction_probability", \
                                                     get_first_element(F.col("probability"))).drop("probability")
      
              predictions = predictions.withColumn("logloss", -(F.col("label") * F.log(F.col("true_prediction_probability")) + \
                                   (F.lit(1) - F.col("label")) * F.log(F.lit(1) - F.col("true_prediction_probability"))))
              log_loss = predictions.select(F.mean("logloss")).collect()[0][0]
      
              return log_loss
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-21
        • 2016-08-28
        • 2022-07-14
        • 2016-09-27
        • 2020-08-03
        • 1970-01-01
        • 1970-01-01
        • 2020-12-19
        相关资源
        最近更新 更多