gpt4 book ai didi

python - 如何在 pyspark 2.3 中的二元问题(BinaryClassificationEvaluator)中为 CrossValidator 评估器使用 f1-score

转载 作者:行者123 更新时间:2023-12-04 12:55:19 25 4
gpt4 key购买 nike

我的用例是一个常见用例:带有不平衡标签的二元分类,因此我们决定使用 f1-score 通过交叉验证进行超参数选择,我们使用 pyspark 2.3 和 pyspark.ml,我们创建了一个 CrossValidator 对象,但对于评估者,问题如下:

  • BinaryClassificationEvaluator 没有 f1 分数作为评估指标。
  • MulticlassClassificationEvaluator 有 f1 分数,但返回错误的结果,我的猜测是它为每个类计算 f1(在这种情况下只有 2)并返回它们的某种平均值,因为负类(y = 0)占主导地位,它产生高f1 但模型真的很糟糕(正类的 f1 分数为 0)
  • MulticlassClassificationEvaluator 在最近的版本中添加了参数 evaluator.metricLabel,我认为它允许指定要使用的标签(在我的情况下,我会将其设置为 1),但它在 spark 2.3 上不可用

  • 但问题是:我使用公司/企业 Spark 集群,没有升级当前版本(2.3)的计划,所以问题是:考虑到我们仅限于 Spark 2.3,我如何在 CrossValidator 评估器中使用 f1 分数进行二进制案例

    最佳答案

    您可以为此创建一个类。我公司的 spark 2.4 也有同样的问题,所以我尝试为二元分类制作一个 F1 分数评估器。我必须指定 .evaluate.isLargerBetter新类的方法。这是我尝试时的示例代码 this数据集:

    class F1BinaryEvaluator():

    def __init__(self, predCol="prediction", labelCol="label", metricLabel=1.0):
    self.labelCol = labelCol
    self.predCol = predCol
    self.metricLabel = metricLabel

    def isLargerBetter(self):
    return True

    def evaluate(self, dataframe):
    tp = dataframe.filter(self.labelCol + ' = ' + str(self.metricLabel) + ' and ' + self.predCol + ' = ' + str(self.metricLabel)).count()
    fp = dataframe.filter(self.labelCol + ' != ' + str(self.metricLabel) + ' and ' + self.predCol + ' = ' + str(self.metricLabel)).count()
    fn = dataframe.filter(self.labelCol + ' = ' + str(self.metricLabel) + ' and ' + self.predCol + ' != ' + str(self.metricLabel)).count()
    return tp / (tp + (.5 * (fn +fp)))


    f1_evaluator = F1BinaryEvaluator()

    from pyspark.ml.tuning import ParamGridBuilder, CrossValidator
    from pyspark.ml.classification import GBTClassifier
    gbt = GBTClassifier()
    paramGrid = (ParamGridBuilder()
    .addGrid(gbt.maxDepth, [3, 5, 7])
    .addGrid(gbt.maxBins, [10, 30])
    .addGrid(gbt.maxIter, [10, 15])
    .build())
    cv = CrossValidator(estimator=gbt, estimatorParamMaps=paramGrid, evaluator=f1_evaluator, numFolds=5)

    cvModel = cv.fit(train)
    cv_pred = cvModel.bestModel.transform(test)
    CV 过程运行没有问题,但我不知道性能。我还尝试将评估器与 sklearn.metrics.f1_score 进行比较并且值很接近。
    from sklearn.metrics import f1_score
    print("made-up F1 Score evaluator : ", f1_evaluator.evaluate(cv_pred))
    print("sklearn F1 Score evaluator : ", f1_score(cv_pred.select('label').toPandas(), cv_pred.select('prediction').toPandas()))

    made-up F1 Score evaluator : 0.9363636363636364
    sklearn F1 Score evaluator : 0.9363636363636363

    关于python - 如何在 pyspark 2.3 中的二元问题(BinaryClassificationEvaluator)中为 CrossValidator 评估器使用 f1-score,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68213862/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com