如何在SparkML二分类中指定正类及MulticlassClassificationEvaluator判定规则
SparkML二分类任务指定正类的方法
核心规则说明
你当前的用法存在两个认知偏差:
- 你配置的
weightedPrecision是多分类场景下所有类别精确率按样本占比加权的结果,不是二分类场景下针对单个正类的精确率 - 正类的判定由两个环节共同决定:
StringIndexer生成的标签与索引的映射规则、MulticlassClassificationEvaluator的指标计算配置
具体操作步骤
步骤1:主动控制标签与索引的映射
StringIndexer默认按照标签出现的频率降序分配索引:出现频率最高的标签对应索引0,次高对应索引1,以此类推。
如果你要主动指定某一个原始标签作为正类,可以通过以下两种方式控制映射规则:
- 调整排序规则:通过
stringOrderType参数指定排序逻辑,可选值包括frequencyDesc(默认,频率降序)、frequencyAsc(频率升序)、alphabetDesc(字母降序)、alphabetAsc(字母升序) - 完全自定义映射:Spark 3.0及以上版本支持直接通过
labels参数指定标签顺序,列表下标就是对应标签的索引值
示例:指定原始标签"yes"为正类,对应索引1,"no"为负类对应索引0:
label_idxer = StringIndexer( inputCol="response", outputCol="label", # 方式1:按字母升序,"no"排在"yes"前面,对应索引0,"yes"对应索引1 stringOrderType="alphabetAsc" # 方式2:完全自定义映射,优先级更高 # labels=["no", "yes"] ).fit(df_spark)
你可以随时打印label_idxer.labels验证映射关系,列表的下标就是对应标签的索引值。
步骤2:给评估器指定正类的索引
Spark 3.0及以上版本的MulticlassClassificationEvaluator提供了metricLabel参数,专门用来指定计算单类指标时的目标类索引。你需要将metricName改为precision,同时设置metricLabel为你要的正类对应的索引值即可:
crossval = CrossValidator( estimator=pipeline, evaluator=MulticlassClassificationEvaluator( labelCol=rf.getLabelCol(), predictionCol=rf.getPredictionCol(), metricName="precision", # 这里填正类对应的索引,比如前面示例的"yes"对应1就填1 metricLabel=1 ), numFolds=3 )
如果你使用的是Spark 2.x版本没有metricLabel参数,可以选择:
- 切换为
BinaryClassificationEvaluator,该评估器默认以索引1为正类,符合二分类场景使用习惯 - 手动统计TP/FP计算精确率,再传入评估逻辑
内容的提问来源于stack exchange,提问作者lampShadesDrifter
相关产品推荐
相关产品推荐

