【发布时间】:2013-04-11 04:36:16
【问题描述】:
我目前正在尝试在 ruby 中实现 ROC 曲线的计算。我尝试将伪代码从http://people.inf.elte.hu/kiss/13dwhdm/roc.pdf(参见第 6 站点,第 5 章,算法 1“生成 ROC 点的有效方法”)转换为 Ruby 代码。
我制定了一个简单的示例,但我总是得到超过1.0 的值以供召回。我想我误解了一些东西,或者在编程时犯了一个错误。到目前为止,这是我所了解的:
# results from a classifier
# index 0: users voting
# index 1: estimate from the system
results = [[5.0,4.8],[4.6,4.2],[4.3,2.2],[3.1,4.9],[1.3,2.6],[3.9,4.3],[1.9,2.4],[2.6,2.3]]
# over a score of 2.5 an item is a positive one
threshold = 2.5
# sort by index 1, the estimate
l_sorted = results.sort { |a,b| b[1] <=> a[1] }
# count the real positives and negatives
positives, negatives = 0, 0
positives, negatives = 0, 0
l_sorted.each do |item|
if item[0] >= threshold
positives += 1
else
negatives += 1
end
end
fp, tp = 0, 0
# the array that holds the points
r = []
f_prev = -Float::INFINITY
# iterate over all items
l_sorted.each do |item|
# if the score of the former iteration is different,
# add another point to r
if item[1]!=f_prev
r.push [fp/negatives.to_f,tp/positives.to_f]
f_prev = item[1]
end
# if the current item is a real positive
# (user likes the item indeed, and estimater was also correct)
# add a true positive, otherwise, add a false positve
if item[0] >= threshold && item[1] >= threshold
tp += 1
else
fp += 1
end
end
# push the last point (1,1) to the array
r.push [fp/negatives.to_f,tp/positives.to_f]
r.each do |point|
puts "(#{point[0].round(3)},#{point[1].round(3)})"
end
基于数组的results 数组,代码尝试计算点。我不确定f_prev 是什么意思。是在f_prev 中存储的分类器的分数,还是只有在true 或false 时?
如果有人可以快速查看我的代码并帮助我找出错误,那就太棒了。谢谢!
【问题讨论】:
-
我习惯了分类器是 0 或 1 为什么你的索引 0 是一个分数呢?您确定您的问题需要 ROC,它看起来更像是一种回归吗?编辑:我只有 ROC 下区域的简化代码,而不是曲线本身。这很简单,但可能不是您需要的。
-
我已经运行了您编写的代码而没有修改,并且召回率低于 1.0(结果数组的索引 1)。您的意思是 fp rate 超过 1.0 吗?
-
感谢您的 cmets!不,索引 0 是召回率(在 X 轴上),索引 1 是精度(在 Y 轴上)。还是我错了?