我试图理解两个类型为double的数组之间的“Jaccard相似性”,其值大于零且小于一。
到目前为止,我已经搜索了很多网站,但我发现这两个数组的大小应该相同(数组1中的元素数应该等于数组2中的元素数)。但是我在两个数组中都有不同数量的元素。有没有办法实现“jaccard相似度”?
答案 0 :(得分:4)
使用C#的LINQ ...
假设您有一个名为A的双精度数组和另一个名为B的双精度数。这将为您提供Jaccard索引:
var CommonNumbers = from a in A.AsEnumerable<double>()
join b in B.AsEnumerable<double>() on a equals b
select a;
double JaccardIndex = (((double) CommonNumbers.Count()) /
((double) (A.Count() + B.Count())));
第一个语句获取两个数组中出现的数字列表。第二个计算索引 - 这只是交集的大小(两个数组中出现的数量)除以联合的大小(一个数组的大小,或者更确切的计数,加上另一个数组的计数)。 / p>
答案 1 :(得分:2)
Jaccard相似度是两个集合之间交集大小的指数,除以并集的大小。在您的情况下,您必须编写代码以找出两个数组中出现的元素数量,然后将其除以两个数组的大小之和。
答案 2 :(得分:0)
很抱歉,您的尸体投寄遗忘了,但以上答案被标记为正确答案。如果集合完全相同,则@AgapwIesu答案的Jaccard相似系数最大为0.5。至少,您需要将分子x2乘以对其进行归一化,如下所示:
var CommonNumbers = from a in A.AsEnumerable<double>()
join b in B.AsEnumerable<double>() on a equals b
select a;
double JaccardIndex = 2*(((double) CommonNumbers.Count()) /
((double) (A.Count() + B.Count())));
请注意,该相似性系数是非交集,由Wikipedia定义的并集来定义。如果要使用LINQ通过联合来划分交集,可以尝试以下代码:
private static double JaccardIndex(IEnumerable<double> A, IEnumerable<double> B)
{
return (double)A.Intersect(B).Count() / (double)A.Union(B).Count();
}
请注意,Union
和Intersect
适用于唯一对象,因此使用非唯一集合时应格外小心:
List<int> A = new List<int>() { 1, 1, 1, 1 };
List<int> B = new List<int>() { 1, 1, 1, 1 };
Console.WriteLine(A.Union(B).Count()); // = 1, not 4
Console.WriteLine(A.Intersect(B).Count()); // = 1, not 4