问题是我有两个字符串列表。一个列表是另一个列表的近似值,我需要一些方法来测量近似值的准确性。
作为对近似值进行评分的临时方法,我在根据与字符串对应的数值进行排序后,将每个列表(近似值和答案)分成3个分区(高,中低)。然后我比较了近似中的所有元素,看看字符串是否存在于正确列表的同一分区中。
我将正确分类的字符串的数量相加并将其除以字符串的总数。我知道这是衡量估算准确性的一种非常粗略的方法,并希望有更好的替代方案。这是较大工作的一个非常小的组成部分,并且希望不必重新发明轮子。
编辑: 我觉得我不够清楚。我不需要两个列表完全相同,我需要某种措施来显示列表是相似的。例如,我们采用的高 - 中 - 低(H-M-L)方法表明估计列表足够相似。这种方法的缺点是,如果估计列表在“高”括号的底部有一个项目,并且在实际列表中,该项目位于中等集合的顶部,则分数算法无法提供。
除了H-M-L方法之外,还可能是每个分区的最低20%与下一个分区的前20%或沿着这些线的东西进行比较。
谢谢大家的帮助!!
答案 0 :(得分: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之间的值决定了相等程度。在我的样本中,百分比。
如果你比较这两个列表,你将检索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);
我希望它有所帮助。
答案 1 :(得分: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);
}
答案 2 :(得分:0)
我会同时使用List<String>
并将每个元素组合成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;