[英]How to calculate the log loss metric in scala/spark?
我已经训练了一个二元分类器 ( XGBoostClassifier
) model,并在我的结果 dataframe 中有两列: PREDICTED_COL
和TARGET_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但 function 不带任何参数(例如我的 PREDICTED_COL 和 TARGET_COL),所以不知道如何使用它。
您可以只实现公式:
val df_ll = df.withColumn("logloss", -($"target_col" * log($"predicted_col") + (lit(1) - $"target_col") * log(lit(1) - $"predicted_col")))
请注意,我们仅使用 spark.sql.functions 的内置函数,这意味着我们获得了相当好的性能(比 UDF 更好)
所以这里有一个方便的 function 来计算给定 dataframe 的对数损失( TARGET_COL
是基本事实,又名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
}
这个简单的 function 可以用来获取日志丢失。
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 log_loss
"""
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.