Utilisation de Sklearn kNN avec une métrique définie par l'utilisateur

actuellement je suis en train de faire un projet qui pourrait nécessiter l'utilisation d'un algorithme kNN pour trouver les meilleurs K voisins les plus proches pour un point donné, disons p. im en utilisant python, paquet sklearn pour faire le travail, mais notre métrique prédéfinie n'est pas une de ces métriques par défaut. je dois donc utiliser la métrique définie par l'utilisateur, à partir des documents de sklearn, que l'on peut trouver ici et ici.

Il semble que la dernière version de sklearn kNN soutien, l'utilisateur a défini le système métrique, mais je je ne trouve pas comment l'utiliser:

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

disons que j'ai défini une métrique appelée mydist=max(x-y), puis utilisez DistanceMetric.get_metric pour en faire un objet DistanceMetric:

dt=DistanceMetric.get_metric('pyfunc',func=mydist)

du document, la ligne devrait ressembler à ceci

nbrs = NearestNeighbors(n_neighbors=4, algorithm='auto',metric='pyfunc').fit(A)
distances, indices = nbrs.kneighbors(A)

mais où puis-je mettre le dt? Merci

20
demandé sur alko 2014-01-10 23:12:53

2 réponses

vous passez une métrique comme metric param et métriques supplémentaires arguments comme mot-clé paramethers à NN constructeur:

>>> 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]]))
25
répondu alko 2014-01-10 20:08:05

Un petit ajout à la réponse précédente. Comment utiliser une métrique qui prend arguments supplémentaires.

>>> 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]]))
8
répondu Mahmoud 2015-07-24 09:05:13