排序列表差异
Posted
技术标签:
【中文标题】排序列表差异【英文标题】:Sorted list difference 【发布时间】:2010-10-25 23:07:21 【问题描述】:我有以下问题。
我有一组元素,可以通过某种算法 A 进行排序。分拣不错,就是很贵。
还有一个算法B可以逼近A的结果,速度快很多,但是排序不会完全一样。
将 A 的输出作为“黄金标准”,我需要对在相同数据上使用 B 所导致的误差进行有意义的估计。
任何人都可以建议我可以查看的任何资源来解决我的问题吗? 提前致谢!
编辑:
根据要求:添加一个示例来说明案例: 如果数据是字母表的前 10 个字母,
A 输出:a,b,c,d,e,f,g,h,i,j
B 输出:a,b,d,c,e,g,h,f,j,i
产生的误差有哪些可能的测量方法,这将允许我调整算法 B 的内部参数以使结果更接近 A 的输出?
【问题讨论】:
【参考方案1】:斯皮尔曼的 rho
我想你想要的是Spearman's rank correlation coefficient。使用两个排序的索引 [rank] 向量(完美A
和近似B
),您可以计算等级相关rho
,范围从-1(完全不同)到1(完全相同):
其中 d(i) 是 A 和 B 之间每个字符的等级差异
您可以将误差度量定义为距离D := (1-rho)/2
。
【讨论】:
是的,这看起来很像我要找的东西,谢谢!【参考方案2】:我会确定最大的正确排序的子集。
+-------------> I
| +--------->
| |
A -> B -> D -----> E -> G -> H --|--> J
| ^ | | ^
| | | | |
+------> C ---+ +-----------> F ---+
在您的示例中,10 分中有 7 分,因此算法得分为 0.7。其他集合的长度为 6。正确排序得分 1.0,反向排序得分 1/n。
我认为这与反转次数有关。 x + y 表示 x y(错误顺序)。
A + B + D - C + E + G + H - F + J - I
我们得到几乎相同的结果 - 9 个中有 6 个是正确的,得分为 0.667。再次正确排序分数 1.0 和反向排序分数 0.0,这可能更容易计算。
【讨论】:
【参考方案3】:您是否正在寻找一些算法来计算基于以 A 排序的数组和以 B 排序的数组作为输入的差异?或者您是否正在寻找一种通用方法来确定使用 B 排序时数组的平均偏差?
如果是第一个,那么我建议一些简单的方法,比如每个项目与它应该在的位置之间的距离(平均值会比总和更好,以消除数组长度作为一个问题)
如果是第二个,那么我想我需要了解更多关于这些算法的信息。
【讨论】:
这还不够好,好像列表是 z, a, b, c, d……整个列表移动了 1。【参考方案4】:很难给出一个好的通用答案,因为适合您的解决方案取决于您的应用程序。
我最喜欢的选项之一就是有序元素对的数量除以对的总数。这是一个很好的、简单的、易于计算的指标,它只是告诉你有多少错误。但它没有尝试量化这些错误的严重程度。
double sortQuality = 1;
if (array.length > 1)
int inOrderPairCount = 0;
for (int i = 1; i < array.length; i++)
if (array[i] >= array[i - 1]) ++inOrderPairCount;
sortQuality = (double) inOrderPairCount / (array.length - 1);
【讨论】:
【参考方案5】:计算RMS Error 可能是许多可能的方法之一。这是小python代码。
def calc_error(out_A,out_B):
# in <= input
# out_A <= output of algorithm A
# out_B <= output of algorithm B
rms_error = 0
for i in range(len(out_A)):
# Take square of differences and add
rms_error += (out_A[i]-out_B[i])**2
return rms_error**0.5 # Take square root
>>> calc_error([1,2,3,4,5,6],[1,2,3,4,5,6])
0.0
>>> calc_error([1,2,3,4,5,6],[1,2,4,3,5,6]) # 4,3 swapped
1.414
>>> calc_error([1,2,3,4,5,6],[1,2,4,6,3,5]) # 3,4,5,6 randomized
2.44
注意: 取平方根不是必需的,但取平方是因为差值之和可能为零。我认为 calc_error 函数给出了错误放置对的近似数量,但我没有任何方便的编程工具,所以:(。
看看this question.
【讨论】:
我也在考虑 RMSE。但是最初的问题说“排序很昂贵”,所以我必须假设必须计算错误度量,而无需进行规范排序进行比较。如果没有规范顺序,您将无法计算 RMSE。 不,OP 可以访问黄金标准进行培训。他想要一个误差函数,这样他就可以在松开它之前优化他的近似分拣机。【参考方案6】:你可以试试hamming distance
【讨论】:
我不认为汉明距离是解决这个问题的好方法。它提供了逐个元素的比较,但两个元素之间的距离并不能说明排序质量。 你是对的,我不是说只使用汉明距离,而是说涉及它的东西。如果他想进行更昂贵的估算,他应该使用距离计算。【参考方案7】:如果有人使用 R 语言,我已经实现了一个函数,该函数使用@bubake 上述方法计算“spearman 秩相关系数”:
get_spearman_coef <- function(objectA, objectB)
#getting the spearman rho rank test
spearman_data <- data.frame(listA = objectA, listB = objectB)
spearman_data$rankA <- 1:nrow(spearman_data)
rankB <- c()
for (index_valueA in 1:nrow(spearman_data))
for (index_valueB in 1:nrow(spearman_data))
if (spearman_data$listA[index_valueA] == spearman_data$listB[index_valueB])
rankB <- append(rankB, index_valueB)
spearman_data$rankB <- rankB
spearman_data$distance <-(spearman_data$rankA - spearman_data$rankB)**2
spearman <- 1 - ( (6 * sum(spearman_data$distance)) / (nrow(spearman_data) * ( nrow(spearman_data)**2 -1) ) )
print(paste("spearman's rank correlation coefficient"))
return( spearman)
结果:
get_spearman_coef(c("a","b","c","d","e"), c("a","b","c","d","e") )
斯皮尔曼等级相关系数:1
get_spearman_coef(c("a","b","c","d","e"), c("b","a","d","c","e") )
斯皮尔曼等级相关系数:0.9
【讨论】:
以上是关于排序列表差异的主要内容,如果未能解决你的问题,请参考以下文章