使用用户定义的指标Sklearn kNN用法

use*_*523 26 python knn

目前我正在做一个可能需要使用kNN算法来找到给定点的前k个最近邻居的项目,比如P. im使用python,sklearn包来完成这项工作,但是我们的预定义度量不是那些默认值指标.所以我必须使用用户定义的度量标准,来自sklearn的文档,可以在这里这里找到.

似乎最新版本的sklearn kNN支持用户定义的度量标准,但我无法找到如何使用它:

import sklearn
from sklearn.neighbors import NearestNeighbors
import numpy as np
from sklearn.neighbors import DistanceMetric
from sklearn.neighbors.ball_tree import BallTree
BallTree.valid_metrics
Run Code Online (Sandbox Code Playgroud)

我已经定义了一个名为mydist = max(xy)的度量,然后使用DistanceMetric.get_metric使其成为DistanceMetric对象:

dt=DistanceMetric.get_metric('pyfunc',func=mydist)
Run Code Online (Sandbox Code Playgroud)

从文档中,该行应该如下所示

nbrs = NearestNeighbors(n_neighbors=4, algorithm='auto',metric='pyfunc').fit(A)
distances, indices = nbrs.kneighbors(A)
Run Code Online (Sandbox Code Playgroud)

但我dt在哪里可以放入?谢谢

alk*_*lko 31

您将度量标准作为metric参数传递,并将其他度量标准参数作为关键字参数传递给NN构造函数:

>>> def mydist(x, y):
...     return np.sum((x-y)**2)
...
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])

>>> nbrs = NearestNeighbors(n_neighbors=4, algorithm='ball_tree',
...            metric='pyfunc', func=mydist)
>>> nbrs.fit(X)
NearestNeighbors(algorithm='ball_tree', leaf_size=30, metric='pyfunc',
         n_neighbors=4, radius=1.0)
>>> nbrs.kneighbors(X)
(array([[  0.,   1.,   5.,   8.],
       [  0.,   1.,   2.,  13.],
       [  0.,   2.,   5.,  25.],
       [  0.,   1.,   5.,   8.],
       [  0.,   1.,   2.,  13.],
       [  0.,   2.,   5.,  25.]]), array([[0, 1, 2, 3],
       [1, 0, 2, 3],
       [2, 1, 0, 3],
       [3, 4, 5, 0],
       [4, 3, 5, 0],
       [5, 4, 3, 0]]))
Run Code Online (Sandbox Code Playgroud)

  • @ShishirPandey您可以检查以下提交,https://github.com/scikit-learn/scikit-learn/commit/ad751a3b6996a4c209c1a243d396aa6930d4acc4,NN签名已更改.我想你可以直接将mydist作为"公制"参数传递 (6认同)
  • 我正在使用scikit-learn 0.18.dev0版本,我收到以下错误 - `_init_params()得到了一个意外的关键字参数'func' (2认同)

Mah*_*oud 15

前一个答案的一小部分.如何使用带有其他参数的用户定义度量标准.

>>> def mydist(x, y, **kwargs):
...     return np.sum((x-y)**kwargs["metric_params"]["power"])
...
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
>>> Y = np.array([-1, -1, -2, 1, 1, 2])
>>> nbrs = KNeighborsClassifier(n_neighbors=4, algorithm='ball_tree',
...            metric=mydist, metric_params={"power": 2})
>>> nbrs.fit(X, Y)
KNeighborsClassifier(algorithm='ball_tree', leaf_size=30,                                                                                                                                                          
       metric=<function mydist at 0x7fd259c9cf50>, n_neighbors=4, p=2,
       weights='uniform')
>>> nbrs.kneighbors(X)
(array([[  0.,   1.,   5.,   8.],
       [  0.,   1.,   2.,  13.],
       [  0.,   2.,   5.,  25.],
       [  0.,   1.,   5.,   8.],
       [  0.,   1.,   2.,  13.],
       [  0.,   2.,   5.,  25.]]),
 array([[0, 1, 2, 3],
       [1, 0, 2, 3],
       [2, 1, 0, 3],
       [3, 4, 5, 0],
       [4, 3, 5, 0],
       [5, 4, 3, 0]]))
Run Code Online (Sandbox Code Playgroud)

  • 我实际上认为在函数中它需要是kwargs ["power"],而不是kwargs ["metric_params"] ["power"].至少这是我用sklearn'0.16.1'观察到的行为 (2认同)