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