PySpark:按AUC分组计算

时间:2016-06-02 03:56:31

标签: python apache-spark pyspark apache-spark-mllib

  • Spark版本:1.6.0

我尝试按字段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这样的第三方模块)?

2 个答案:

答案 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()他们进入内存,不要使用这个