我是 Mahout 新手,最近将我以前的许多机器学习代码转换为这个框架。在很多地方,我使用 vector 之间的余弦相似度进行聚类、分类等。然而,研究 Mahout 的 distance method 给了我相当大的惊喜。在下面的代码片段中,尺寸和浮点值取 self 的一个程序的实际输出(这里并不重要):
import org.apache.mahout.math.RandomAccessSparseVector;
import org.apache.mahout.common.distance.CosineDistanceMeasure;
public static void main(String[] args) {
RandomAccessSparseVector u = new RandomAccessSparseVector(373);
RandomAccessSparseVector v = new RandomAccessSparseVector(373);
u.set(24, 0.4526985183337534);
u.set(55, 0.5333219834564495);
u.set(54, 0.5333219834564495);
u.set(53, 0.4756042214095471);
v.set(57, 0.6653016370845252);
v.set(56, 0.6653016370845252);
v.set(11, 0.3387439495921685);
CosineDistanceMeasure cosineDistanceMeasure = new CosineDistanceMeasure();
System.out.println(cosineDistanceMeasure.distance(u, v));
}
输出为1.0
。不应该是0.0
吗?
将其与 cosineDistanceMeasure.distance(u, u)
的输出进行比较,我意识到我正在寻找的是 1 - cosineDistanceMeasure.distance(u, v)
。但这种逆转对我来说毫无意义。知道为什么要这样实现吗?或者我错过了一些非常明显的东西?
最佳答案
当两点“靠近”时,从原点看作为 vector 时它们形成的角度很小,接近于零。接近 0 的角度的余弦值接近 1,随着角度接近 90 度,然后接近 180 度,余弦值减小。
所以余弦随着距离的增加而减小。这就是为什么两个 vector 之间的角度的余弦本身不能作为距离度量有意义。距离度量的“规范”方法是 1 - 余弦;这是一个合适的指标。
关于java - Mahout 中 RandomAccessSparseVectors 的余弦距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15303728/