3

问题是我有两个字符串列表。一个列表是另一个列表的近似值,我需要某种方法来测量近似值的准确性。

作为对近似值进行评分的一种临时方法,在根据与字符串对应的数值进行排序后,我将每个列表(近似值和答案)分为 3 个分区(高、中低)。然后我比较近似值中的所有元素,以查看字符串是否存在于正确列表的同一分区中。

我将正确分类的字符串的数量相加,然后除以字符串的总数。我知道这是一种非常粗略的方法来衡量估计的准确性,并希望有更好的替代方案可用。这是一个更大的工作的一个非常小的组成部分,并希望不必重新发明轮子。

编辑:我想我不够清楚。我不需要两个列表完全相等,我需要某种显示列表相似的度量。例如,我们采用的 High-Medium-Low (HML) 方法表明估计的列表足够相似。这种方法的缺点是,如果估计列表中有一个项目位于“高”括号的底部,而在实际列表中,该项目位于中等集合的顶部,则评分算法无法传递。

除了 HML 方法之外,可能还会将每个分区的底部 20% 与下一个分区的顶部 20% 或类似的东西进行比较。

感谢你的帮助!!

4

3 回答 3

1

好问题。好吧,我认为您可以使用以下方法来比较您的列表:

 public double DetermineAccuracyPercentage(int numberOfEqualElements, int yourListsLength)
    {
        return ((double)numberOfEqualElements / (double)yourListsLength) * 100.0; 
    }

返回的数字应该确定两个列表之间存在多少相等。如果 numberOfEqualElements = yourLists.Length (Count),那么它们绝对相等。近似值的准确度 = (numberOfEqualElements / yourLists.Length) 1 = 完全相等,0 = 完全不同,0 到 1 之间的值决定了相等的程度。在我的样本中是一个百分比。

如果您比较这 2 个列表,您将检索到 75% 的相等性,与 4 个相等元素中的 3 个 (3/4) 相同。

        IList<string> list1 = new List<string>();
        IList<string> list2 = new List<string>();

        list1.Add("Dog");
        list1.Add("Cat");
        list1.Add("Fish");
        list1.Add("Bird");

        list2.Add("Dog");
        list2.Add("Cat");
        list2.Add("Fish");
        list2.Add("Frog");


          int resultOfComparing = list1.Intersect(list2).Count();
        double accuracyPercentage = DetermineAccuracyPercentage(resultOfComparing,   list1.Count); 

我希望它有所帮助。

于 2014-01-09T21:34:05.947 回答
1

因此,我们采用一系列项目并将其分组为具有高、中和低三个类别的分区。让我们首先创建一个对象来表示这三个分区:

public class Partitions<T>
{
    public IEnumerable<T> High { get; set; }
    public IEnumerable<T> Medium { get; set; }
    public IEnumerable<T> Low { get; set; }
}

接下来要进行估计,我们要取其中两个对象,一个用于实际对象,一个用于估计值。对于每个优先级,我们想查看两个集合中有多少项;这是一个“十字路口”;我们想总结每个集合的交集的计数。

然后将该计数除以总数:

public static double EstimateAccuracy<T>(Partitions<T> actual
    , Partitions<T> estimate)
{
    int correctlyCategorized = 
        actual.High.Intersect(estimate.High).Count() +
        actual.Medium.Intersect(estimate.Medium).Count() +
        actual.Low.Intersect(estimate.Low).Count();

    double total = actual.High.Count()+
        actual.Medium.Count()+
        actual.Low.Count();

    return correctlyCategorized / total;
}

当然,如果我们将其推广到不是 3 个优先级,而是一个序列序列,其中每个序列对应于某个桶(即有 N 个桶,而不仅仅是 3 个桶),代码实际上变得更容易:

public static double EstimateAccuracy<T>(
    IEnumerable<IEnumerable<T>> actual
    , IEnumerable<IEnumerable<T>> estimate)
{
    var query = actual.Zip(estimate, (a, b) => new
    {
        valid = a.Intersect(b).Count(),
        total = a.Count()
    }).ToList();
    return query.Sum(pair => pair.valid) /
        (double)query.Sum(pair => pair.total);
}
于 2014-01-09T21:35:47.207 回答
0

我会同时使用List<String>s 并将每个元素组合成 a IEnumerable<Boolean>

public IEnumerable<Boolean> Combine<Ta, Tb>(List<Ta> seqA, List<Tb> seqB)
{
  if (seqA.Count != seqB.Count)
    throw new ArgumentException("Lists must be the same size...");

  for (int i = 0; i < seqA.Count; i++)
    yield return seqA[i].Equals(seqB[i]));
}

然后用于Aggregate()验证哪些字符串匹配并保持运行总计:

var result = Combine(a, b).Aggregate(0, (acc, t)=> t ? acc + 1 : acc) / a.Count; 
于 2014-01-09T21:16:07.090 回答