2014-01-10 8 views
16

Derzeit mache ich ein Projekt, das möglicherweise einen kNN-Algorithmus benötigen, um die Top k nächsten Nachbarn für einen bestimmten Punkt zu finden, sagen P. im Python, sklearn-Paket, um die Arbeit zu tun , aber unsere vordefinierte Metrik gehört nicht zu diesen Standardmetriken. also muss ich die benutzerdefinierte Metrik verwenden, aus den Dokumenten von sklearn, die here und here finden können.Sklearn kNN Verwendung mit einer benutzerdefinierten Metrik

Es scheint, dass die neueste Version von sklearn kNN den Benutzer unterstützen Metrik definiert, aber ich kann nicht finden, wie man es benutzt:

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 

sagen, dass ich eine Metrik genannt MYDIST = max (xy) definiert haben, dann verwenden DistanceMetric.get_metric es ein DistanceMetric Objekt zu machen:

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

aus dem Dokument sieht die Zeile sollte wie folgt

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

aber wo kann ich die dt in? Dank

+0

der Grund 'NBRs = NearestNeighbors (n_neighbors = 4, algorithm = 'auto', metric = 'pyfunc'). Passen (A) Entfernungen, Indizes = nbrs.kneighbors (A)' nicht funktioniert auch i put 'func = mydist' ist da, weil der Parameter' algorithm = auto' keine benutzerdefinierten Metriken akzeptiert, weder 'algorithm = kd_tree' oder' algorithm = brute'. Nur der 'algorithm = ball_tree' akzeptiert – user2926523

Antwort

21

Sie übergeben eine Metrik als metric param und zusätzliche metrische Argumente als Schlüsselwort paramethers zu NN Konstruktor:

>>> 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]])) 
+1

Ich benutze scikit-learn 0.18.dev0 Version und erhalte den folgenden Fehler -' _init_params() hat ein unerwartetes Schlüsselwortargument 'func'' –

+3

@ShishirPandey Sie könnten das folgende Commit, https überprüfen : //github.com/scikit-learn/scikit-learn/commit/ad751a3b6996a4c209c1a243d396aa6930d4acc4, die NN-Signatur wurde geändert. Ich denke, Sie könnten einfach mydist direkt als "metric" Argument übergeben – alko

+0

Wie kann ich benutzerdefinierte Metrik für sparse Vektoren definieren? Mit dieser Methode bekomme ich: 'ValueError: Metrik 'pyfunc' nicht gültig für sparse Eingabe ' – mpr

8

Ein kleiner Zusatz zu der vorherigen Antwort. Wie verwende ich eine benutzerdefinierte Metrik, die zusätzliche Argumente.

>>> 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]])) 
+0

Ich denke eigentlich, dass in der Funktion muss es Kwargs sein [" Power "], nicht Kwargs [" metric_params "] [" Power " ]. Das ist zumindest das Verhalten, das ich mit sklearn '0.16.1' beobachte – benbo

Verwandte Themen