我尝试按字段id
分组计算AUC(ROC下的区域)。鉴于以下数据:
# Within each key-value pair
# key is "id"
# value is a list of (score, label)
data = sc.parallelize(
[('id1', [(0.5, 1.0), (0.6, 0.0), (0.7, 1.0), (0.8, 0.0)),
('id2', [(0.5, 1.0), (0.6, 0.0), (0.7, 1.0), (0.8, 0.0))
]
BinaryClassificationMetrics类可以在给定(score, label)
列表的情况下计算AUC。
我想按键计算AUC(即id1, id2
)。但是如何" map"按键class
到RDD?
我试图将BinaryClassificationMetrics
包装在一个函数中:
def auc(scoreAndLabels):
return BinaryClassificationMetrics(scoreAndLabels).areaUnderROC
然后将包装函数映射到每个值:
data.groupByKey()\
.mapValues(auc)
但(score, label)
的列表实际上是ResultIterable
中的mapValues()
类型,BinaryClassificationMetrics
期望RDD
。
是否有任何方法可以将ResultIterable
转换为RDD
,以便可以应用auc
函数?或者计算group-by AUC的任何其他解决方法(不导入像scikit-learn这样的第三方模块)?
答案 0 :(得分:4)
您可以使用sklearn.metrics.auc而不是使用BinaryClassificationMetrics
来映射每个RDD元素值,并且您将获得每个键的AUC值:
from sklearn.metrics import auc
data = sc.parallelize([
('id1', [(0.5, 1.0), (0.6, 0.0), (0.7, 1.0), (0.8, 0.0)]),
('id2', [(0.5, 1.0), (0.6, 0.0), (0.7, 1.0), (0.8, 0.0)])])
result_aucs = data.map(lambda x: (x[0] + '_auc', auc(*zip(*x[1]))))
result_aucs.collect()
Out [1]: [('id1_auc', 0.15000000000000002), ('id2_auc', 0.15000000000000002)]
答案 1 :(得分:0)
以下是一种在不使用auc
的情况下获取sklearn
的方法:
keys = data.map(lambda x: x[0]).distinct().collect()
rslt = {}
for k in keys:
scoreAndLabels = data.filter(lambda x: x[0]==k).flatMap(lambda x: x[1])
rslt[k] = BinaryClassificationMetrics(scoreAndLabels).areaUnderROC
print(rslt)
注意:此解决方案要求key
的数量足够小,以适应内存。
如果你有这么多的钥匙,你不能collect()
他们进入内存,不要使用这个