nic*_*liu 2 apache-spark apache-spark-sql apache-spark-ml apache-spark-mllib
我正在尝试使用 scala API 计算按关键字段分组的 AUC(ROC 下的区域),类似于以下问题:PySpark:Calculate grouped-by AUC。
不幸的是,我不能使用sklearn. 我该如何进行?
我们将使用 sklearn/mllib 中使用的相同方法,即梯形规则。这是一种用于逼近定积分的技术。
非常简单,您可以在源代码中找到相同的代码。
def trapezoid(points: Seq[(Double, Double)]): Double = {
require(points.length == 2)
val x = points.head
val y = points.last
(y._1 - x._1) * (y._2 + x._2) / 2.0
}
def areaUnderCurve(curve: Iterable[(Double, Double)]): Double = {
curve.toIterator.sliding(2).withPartial(false).aggregate(0.0)(
seqop = (auc: Double, points: Seq[(Double, Double)]) => auc + trapezoid(points),
combop = _ + _
)
}
val seq = Seq((0.0, 0.0), (1.0, 1.0), (2.0, 3.0), (3.0, 0.0))
areaUnderCurve(seq)
// res77: Double = 4.0
Run Code Online (Sandbox Code Playgroud)
结果是4.0,符合预期。
现在让我们将其应用到数据集上。数据已按此处的键分组:
val data = Seq(("id1", Array((0.5, 1.0), (0.6, 0.0), (0.7, 1.0), (0.8, 0.0))), ("id2", Array((0.5, 1.0), (0.6, 0.0), (0.7, 1.0), (0.8, 0.3)))).toDF("key","values")
case class Record(key : String, values : Seq[(Double,Double)])
data.as[Record].map(r => (r.key, r.values, areaUnderCurve(r.values))).show
// +---+--------------------+-------------------+
// | _1| _2| _3|
// +---+--------------------+-------------------+
// |id1|[[0.5, 1.0], [0.6...|0.15000000000000002|
// |id2|[[0.5, 1.0], [0.6...|0.16500000000000004|
// +---+--------------------+-------------------+
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助。
| 归档时间: |
|
| 查看次数: |
1901 次 |
| 最近记录: |