我们使用EuclideanDistanceSimilarity类来计算使用Hadoop的一堆项目的相似性。
不幸的是,尽管与物品高度相似,但有些物品的零件或极少数都会产生相似的物品。
我想我已经在EuclideanDistanceSimilarity类中跟踪了这一行:
double euclideanDistance = Math.sqrt(normA - 2 * dots + normB);
传递给sqrt的值有时是负数,在这种情况下返回NaN。我想也许在那里应该有一个Math.abs,但是我的数学不够强大,无法理解欧几里德计算是如何重新排列的,所以不确定效果会是什么。
任何人都可以更好地解释数学并确认是否
double euclideanDistance = Math.sqrt(Math.abs(normA - 2 * dots + normB));
是一个可以接受的修复方法吗?
答案 0 :(得分:5)
代码位于org.apache.mahout.math.hadoop.similarity.cooccurrence.measures. EuclideanDistanceSimilarity
。
是的,它是以这种方式编写的,因为在计算中它具有向量A和B的规范及其点积,因此计算距离的速度要快得多。
身份非常简单。设C = A-B,令a,b和c为相应矢量的长度。我们需要c。根据余弦定律,c 2 = a 2 + b 2 - 2ab·cos (θ),和ab· cos (θ)只是点积的值。请注意,代码中的normA
实际上是范数(长度)的平方 - 实际上应该更好地命名。
回到问题:你是对的,这里有一个错误,因为四舍五入会使论证变得消极。该修复程序不是abs()
,而是:
double euclideanDistance = Math.sqrt(Math.max(0.0, normA - 2 * dots + normB));
它只需要限制为0.我可以承诺。