代码之家  ›  专栏  ›  技术社区  ›  lampShadesDrifter

如何在sparkml分类中指定“正类”?

  •  0
  • lampShadesDrifter  · 技术社区  · 5 年前

    如何在sparkml(二进制)分类中指定“正类”?(或者可能是:一个 MulticlassClassificationEvaluator

    假设我们正在训练一个模型,以达到二元分类问题中的目标精度,如。。。

    label_idxer = StringIndexer(inputCol="response",
                                outputCol="label").fit(df_spark)
    # we fit so we can get the "labels" attribute to inform reconversion stage
    
    feature_idxer = StringIndexer(inputCols=cat_features,
                                  outputCols=[f"{f}_IDX" for f in cat_features],
                                  handleInvalid="keep")
    
    onehotencoder = OneHotEncoder(inputCols=feature_idxer.getOutputCols(),
                                  outputCols=[f"{f}_OHE" for f in feature_idxer.getOutputCols()])
    
    assembler = VectorAssembler(inputCols=(num_features + onehotencoder.getOutputCols()),
                                outputCol="features")
    
    rf = RandomForestClassifier(labelCol=label_idxer.getOutputCol(),
                                featuresCol=assembler.getOutputCol(),
                                seed=123456789)
    
    label_converter = IndexToString(inputCol=rf.getPredictionCol(),
                                    outputCol="prediction_label",
                                    labels=label_idxer.labels)
    
    pipeline = Pipeline(stages=[label_idxer, feature_idxer, onehotencoder,
                                assembler,
                                rf,
                                label_converter])  # type: pyspark.ml.pipeline.PipelineModel
    
    crossval = CrossValidator(estimator=pipeline,
                              evaluator=MulticlassClassificationEvaluator(
                                  labelCol=rf.getLabelCol(),
                                  predictionCol=rf.getPredictionCol(),
                                  metricName="weightedPrecision"),  
                              numFolds=3)
    
    (train_u, test_u) = dff.randomSplit([0.8, 0.2])
    model = crossval.fit(train_u)
    

    我知道。。。

    Precision = TP / (TP + FP) 
    

    …但是如何将特定的类标签指定为精度目标的“正类”?(目前,IDK在培训中实际使用了哪个响应值,以及如何判断)。

    0 回复  |  直到 5 年前
        1
  •  0
  •   lampShadesDrifter    5 年前

    来自spark邮件列表上的讨论。。。

    在多类评估中,F1仅在一对多的意义上定义。您可以设置“metricLabel”来定义在多类中哪个类是“正的”——其他所有的都是“负的”。

    请注意,这意味着(SAN在MulticlassEvaluator中设置metricLabel)StringIndexer(特别是stringOrderType参数 https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.feature.StringIndexer.html?highlight=stringindexer#pyspark.ml.feature.StringIndexer.stringOrderType )将是用户理解他们所说的是他们的积极/消极类的地方。(请注意,根据文档,默认值为 frequencyDesc . 如果在frequencyDesc/Asc下频率相等,则字符串将按字母顺序进一步排序(即,如果是minorty正数类,则可以,否则需要按照0=neg 1=pos约定命名)。

    您可以将其应用于二进制类设置。在这种情况下,您可以简单地为标签0请求F1,这将为“0-vs-rest”计算F1,这就像为F1将0视为“正”类一样。

    关于这种解释,值得关注的一点是,BinaryClassificationEvaluator似乎不具备评估Fbeta、召回率、精确度等的能力( https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.evaluation.BinaryClassificationEvaluator.html?highlight=binaryclassificationevaluator#pyspark.ml.evaluation.BinaryClassificationEvaluator.metricName )而MultiClassificationEvaluator( https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.evaluation.MulticlassClassificationEvaluator.html?highlight=classificationevaluator#pyspark.ml.evaluation.MulticlassClassificationEvaluator.metricName