2015-12-22 7 views
10

Ich habe eine benutzerdefinierte Abstandsmetrik, die ich für KNN, K Nearest Neighbors verwenden muss.Wie erlaubt man sklearn K Nearest Neighbors benutzerdefinierte Distanz Metrik zu nehmen?

Ich versuchte folgende this, aber ich kann es aus irgendeinem Grund nicht funktionieren.

Ich würde davon ausgehen, dass die Distanzmetrik zwei Vektoren/Arrays die gleiche Länge nehmen soll, wie ich weiter unten geschrieben haben:

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) 

jedoch, wenn ich rufe: knn.kneighbors(), scheint es nicht, die benutzerdefinierte Funktion zu mögen. Hier ist die Unterseite des Fehler-Stack:

Allerdings sehe ich genau das gleiche in der Frage, die ich zitiert habe. Irgendwelche Ideen, wie man diese Arbeit an sklearn version 0.14 machen kann? Mir sind keine Unterschiede in den Versionen bekannt.

Danke.

+0

auch Ihre Distanzfunktion nicht gut ist, wird es einen Vektor zurückgeben, wheras es einen einzigen Wert zurückgeben muss – maxymoo

Antwort

7

The documentation ist eigentlich ziemlich klar über die Verwendung des metrischen Argument:

metric : string or callable, default ‘minkowski’

metric to use for distance computation. Any metric from scikit-learn or scipy.spatial.distance can be used.

If metric is a callable function, it is called on each pair of instances (rows) and the resulting value recorded. The callable should take two arrays as input and return one value indicating the distance between them. This works for Scipy’s metrics, but is less efficient than passing the metric name as a string.

So (wie auch gemäß der Fehlermeldung), metric sollte ein aufrufbar, kein String sein. Und es sollte zwei Argumente (Arrays) akzeptieren und eins zurückgeben. Welches ist Ihre lambda Funktion.

So kann der Code vereinfacht werden zu:

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

Danke. Die Dokumentation, die ich gesehen habe, war [hier] (http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html) und [hier] (http://scikit-learn.org/stable/ modules/generated/sklearn.neighbors.KNeighborsRegressor.html), von denen keines so detailliert ist wie das, was Sie angegeben haben. Vielen Dank. – Candic3

+0

Ich habe den folgenden Code verwendet. Es gibt mir Beizfehler. Kannst du mir dabei helfen? My-Code: def dist2 (a, b): return Jaccard (a, b) knnobj = NearestNeighbors (n_neighbors = 6, algorithm = 'Auto', metric = lambda a, b: dist2 (a, b)) .fit (my_Data) PicklingError: Kann nicht : attribute lookup __ builtin __ – csalive