【问题标题】:Is there a statistical test that can compare two ordered lists是否有可以比较两个有序列表的统计测试
【发布时间】:2021-09-01 17:07:25
【问题描述】:

我想获得一个统计测试统计数据来比较两个列表。假设我的基准列表是

Benchmark = [a,b,c,d,e,f,g]

我还有另外两个列表

A =  [g,c,b,a,f,e,d]
C = [c,d,e,a,b,f,g]

我希望测试告诉我哪个列表更接近基准。测试应该考虑绝对位置,但也应该考虑相对位置,例如它应该惩罚这样一个事实:在列表 A 'g' 是在开始但在基准测试中它是在结束(与真实情况相差多远)位置),但它也应该奖励'a'和'b'在列表C中彼此接近的事实,就像在Benchmark中一样。 A 和 C 总是被洗牌的基准。我想要一个统计测试或某种指标来告诉我列表ABC 的排序与基准测试的排序在统计上没有差异,但某个列表D 的排序显着在某个阈值或 p 值(例如 5%)处有所不同。即使在ABC 列表中,测试也应该完美地勾勒出哪个排序更接近基准。

【问题讨论】:

  • AC 是否总是洗牌 Benchmark?也就是说,它们包含完全相同的项,但对它们应用了某种排列?
  • 另外,如果您需要“哪个列表更接近基准?”的答案,您不需要统计测试,只需一个简单的指标即可,喜欢def dist(a, b) -> float:。我对该函数的外观有一个可靠的想法。
  • @CaptainTrojan 是的,A 和 C 总是被打乱的基准测试,但对它们应用了某种排列,我问统计测试的原因是,假设列表有 100 个元素,如何我们考虑一个阈值是好是坏,我们怎么知道列表 A 在统计上与 Benchmark 有显着差异,而 C 则不然。
  • 这很好。如果您不向我们隐瞒这条信息,那肯定会有所帮助,因为它可能会帮助我们更快地解决您的问题。您特别询问“哪个列表更接近 Benchmark?”,这实际上并不是您想要找出的。
  • 顺便说一句,即使是统计测试也需要您指定confidence level,这相当于您不想成为系统参数的threshold。很可能必须如此。

标签: python arrays list sorting statistics


【解决方案1】:

好吧,如果您得出一个指标就足够的结论,那么您就可以了:

def dist(a, b):
    perm = []
    for v in b:
        perm.append(a.index(v))
        
    perm_vals = [a[p] for p in perm]
        
    # displacement
    ret = 0
    for i, v in enumerate(perm):
        ret += abs(v - i)
    
    # coherence break
    current = perm_vals.index(a[0])          
    for v in a[1:]:
        new = perm_vals.index(v)
        ret += abs(new - current) - 1
        current = new
    
    return ret

我已经创建了一些示例来测试这个:

import random

ground_truth = [0, 1, 2, 3, 4, 5, 6]
samples = []
for i in range(7):
    samples.append(random.sample(ground_truth, len(ground_truth)))
    
samples.append([0, 6, 1, 5, 3, 4, 2])
samples.append([6, 5, 4, 3, 2, 1, 0])
samples.append([0, 1, 2, 3, 4, 5, 6])

def dist(a, b):
    perm = []
    for v in b:
        perm.append(a.index(v))
        
    perm_vals = [a[p] for p in perm]
        
    # displacement
    ret = 0
    for i, v in enumerate(perm):
        ret += abs(v - i)
    
    # coherence break
    current = perm_vals.index(a[0])          
    for v in a[1:]:
        new = perm_vals.index(v)
        ret += abs(new - current) - 1
        current = new
    
    return ret
        
    
for s in samples:
    print(s, dist(ground_truth, s))

指标是一种成本,即越低越好。如果排列是一个身份,我将其设计为产生0。留给您的工作,没有人可以为您完成,是决定您在使用此指标评估样本时希望达到的严格程度,这绝对取决于您要达到的目标。

【讨论】:

  • 感谢一百万的回答,这对让我开始尝试执行的任务非常有帮助。然而,这种方法是针对数字排列的,有什么方法可以将它设计成一个字符串列表......这就是我真正需要的
  • @Jamesj 你用字符串列表试过了吗?据我所知,它应该适用于任何实现了__eq__ (a == b) 的对象,例如intfloatstr。也就是说,我声称它应该适用于GT = ['ab', 'cd', 'ef']A = ['cd', 'ab', 'ef'] 之类的数组,例如B = ['ef', 'cd', 'ab']。诀窍是使用perm.index(...) 函数,它总是返回一个int(索引)——不管它是索引整数、浮点数、字符串还是其他任何东西。
  • 所以连贯性中断部分有些奇怪,有时它有效,有时它不起作用,例如 () ----> 1 dist([5,0,1,2,3,4,7],[5,3,0,4,2,1,7] ) in dist(a, b) 12 current = perm.index(a[0]) 13 for v in a[1:]: ---> 14 new = perm.index(v) 15 ret += abs( new - current) - 1 16 current = new ValueError: 7 is not in list`
  • 让我看看。
  • 我看到了问题,我会尽快解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多