【问题标题】:Using cosine distance with scikit learn KNeighborsClassifier在 scikit learn KNeighborsClassifier 中使用余弦距离
【发布时间】:2016-03-12 17:00:31
【问题描述】:

scikit learn 的 KNeighborsClassifier 是否可以使用类似 1 的余弦相似度?

This 回答说不,但在 KNeighborsClassifier 的documentation 上,它说DistanceMetrics 中提到的指标可用。距离度量不包括明确的余弦距离,可能是因为它不是真正的距离,但据说可以将函数输入到度量中。我尝试将 scikit 学习线性内核输入到 KNeighborsClassifier 中,但它给了我一个错误,即该函数需要两个数组作为参数。其他人试过吗?

【问题讨论】:

  • KNN 分类器可能会使用一些依赖于三角不等式的优化。余弦度量不服从它,因此无法保证 KNN 的正确行为。
  • @Barmaley.exe 可以使余弦度量服从三角不等式,并且无论如何都可以在没有显式实现的情况下实现相同的排序。详情见我的回答

标签: python machine-learning scikit-learn knn


【解决方案1】:

余弦相似度一般定义为xT y / (||x|| * ||y||),如果相同则输出1,如果相同则输出-1完全不同。这个定义在技术上不是一个度量,所以你不能使用加速结构,比如球和 kd 树。如果你强制 scikit 学习使用蛮力方法,你应该能够将它用作距离,如果你将它传递给你自己的自定义距离度量对象。如果您想使用球树,有一些方法可以将余弦相似度转换为有效的距离度量(您可以在 JSAT library 中找到一种)

请注意,xT y / (||x|| * ||y||) = (x/||x||)T ( y/||y||)。欧式距离可以等效地写为 sqrt(xTx + yTy − 2 xTy)。如果我们在将每个数据点提供给 KNeighborsClassifier 之前对其进行归一化,那么对于所有 xx^T x = 1。所以欧几里得距离会降到sqrt(2 − 2x^T y)。对于完全相同的输入,我们会得到sqrt(2-2*1) = 0 和完全相反的sqrt(2-2*-1)= 2。它显然是一个简单的形状,因此您可以通过对数据进行归一化然后使用欧几里德距离来获得与余弦距离相同的排序。只要您使用uniform 权重选项,结果将与使用正确的余弦距离相同。

【讨论】:

  • 太简单了。感谢 Raff 提供这个优雅的解决方案 :)
【解决方案2】:

KNN 系列类构造函数有一个名为metric 的参数,您可以在最近邻模型中使用的不同距离度量之间进行切换。 可以找到可用距离指标的列表here

如果您想使用余弦度量来解决排名和分类问题,您可以在归一化特征向量上使用范数 2 欧几里得距离,这会为您提供相同的排名/分类(由 argmax 或 argmin 操作做出的预测)结果。

【讨论】:

  • 正如问题中已经观察到的那样。该列表没有提到余弦距离。
猜你喜欢
  • 2017-07-10
  • 2017-12-12
  • 2016-10-17
  • 2016-09-15
  • 2017-06-22
  • 2013-02-24
  • 2021-09-09
  • 1970-01-01
  • 2014-05-26
相关资源
最近更新 更多