web-dev-qa-db-fra.com

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

Actuellement, je fais un projet qui peut nécessiter l'utilisation d'un algorithme kNN pour trouver les k premiers voisins les plus proches pour un point donné, par exemple P. im en utilisant python, le package sklearn pour faire le travail, mais notre métrique prédéfinie n'est pas l'une de celles par défaut métrique. je dois donc utiliser la métrique définie par l'utilisateur, à partir des documents de sklearn, qui peuvent être trouvés ici et ici .

Il semble que la dernière version de sklearn kNN prenne en charge la métrique définie par l'utilisateur, mais je ne peux pas trouver 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

26
user2926523

Vous transmettez une métrique en tant que paramètre metric et des arguments de mesure supplémentaires en tant que paramètres de mot clé au constructeur 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]]))
31
alko

Un petit ajout à la réponse précédente. Comment utiliser une métrique définie par l'utilisateur 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]]))
14
Mahmoud