是否可以在scikit learn的KNeighbors分类器中使用类似1-余弦相似性的东西?
这个答案是否定的,但在KNeighborsClassifier的文档中,它说DistanceMetrics中提到的度量是可用的。距离度量不包括显式余弦距离,可能是因为它不是真正的距离,但据说可以在度量中输入函数。我尝试将scikit学习线性内核输入KNeighborsClassifier,但它给了我一个错误,即函数需要两个数组作为参数。还有人试过这个吗?
余弦相似度通常定义为xTy/(||x||*||y||),如果它们相同,则输出1,如果它们完全不同,则返回-1。从技术上讲,这个定义不是一个度量,因此你不能使用球和kd树等加速结构。如果你强迫scikit学会使用蛮力方法,如果你把它传给你自己的自定义距离度量对象,你应该能够把它用作距离。如果你想使用球树(你可以在JSAT库中找到一个),有一些方法可以将余弦相似性转换为有效的距离度量
但是,请注意,xTy/(||x||*|y||)=(x/|x||)T(y/|y||。欧氏距离可以等价地写成sqrt(xTx+yTy−2 xTy)。如果我们在将每个数据点提供给KNeighborsClassifier之前对其进行归一化,那么所有x
的x^T x = 1
。因此欧氏距离将退化为sqrt(2 − 2x^T y)
。对于完全相同的输入,我们将得到sqrt(2-2*1) = 0
,对于完全相反的sqrt(2-2*-1)= 2
。它显然是一个简单的形状,所以你可以通过标准化你的数据,然后使用欧氏距离,得到与余弦距离相同的排序。只要使用uniform
权重选项,结果将与使用正确的余弦距离相同。
metric
的参数,您可以在最近邻模型中使用的不同距离度量之间切换。可用距离度量的列表可以在这里找到
如果你想使用余弦度量来解决排名和分类问题,你可以在归一化特征向量上使用范数2欧几里得距离,这会给你相同的排名/分类(通过argmax或argmin运算进行的预测)结果。