我有一个自定义距离度量,需要用于KNN
、K Nearest Neighbors
。
我试着遵循这个,但由于某种原因,我无法让它发挥作用。
我假设距离度量应该取两个相同长度的矢量/阵列,正如我在下面所写的:
import sklearn
from sklearn.neighbors import NearestNeighbors
import numpy as np
import pandas as pd
def d(a,b,L):
# Inputs: a and b are rows from a data matrix
return a+b+2+L
knn=NearestNeighbors(n_neighbors=1,
algorithm='auto',
metric='pyfunc',
func=lambda a,b: d(a,b,L)
)
X=pd.DataFrame({'b':[0,3,2],'c':[1.0,4.3,2.2]})
knn.fit(X)
然而,当我调用:knn.kneighbors()
时,它似乎不喜欢自定义函数。这是错误堆栈的底部:
ValueError: Unknown metric pyfunc. Valid metrics are ['euclidean', 'l2', 'l1', 'manhattan', 'cityblock', 'braycurtis', 'canberra', 'chebyshev', 'correlation', 'cosine', 'dice', 'hamming', 'jaccard', 'kulsinski', 'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean', 'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule', 'wminkowski'], or 'precomputed', or a callable
然而,我在我引用的问题中看到了完全相同的情况。关于如何在sklearn version 0.14
上实现这一点,有什么想法吗?我不知道这些版本有什么不同。
谢谢。
文档实际上非常清楚度量参数的使用:
metric:字符串或可调用,默认为"minkowski"
用于距离计算的度量。可以使用scikit learn或scipy.spatial.distance中的任何度量。
如果metric是一个可调用的函数,则会在每对实例(行)上调用它,并记录结果值。可调用应以两个数组作为输入,并返回一个表示距离的值他们之间。这适用于Scipy的指标,但效率较低而不是将度量名称作为字符串传递。
因此(同样根据错误消息),metric
应该是可调用,而不是字符串。它应该接受两个参数(数组),并返回一个。这是您的lambda
函数。
因此,您的代码可以简化为:
import sklearn
from sklearn.neighbors import NearestNeighbors
import numpy as np
import pandas as pd
def d(a,b,L):
return a+b+2+L
knn=NearestNeighbors(n_neighbors=1,
algorithm='auto',
metric=lambda a,b: d(a,b,L)
)
X=pd.DataFrame({'b':[0,3,2],'c':[1.0,4.3,2.2]})
knn.fit(X)