2017-03-16 13 views
2

私は自分のkNN分類子を実装しようとしています。 、私はループのいずれかを使用していない場合はk最近傍分類器numpyを使用

def euclidean_distance(X_train, X_test): 
    """ 
    Create list of all euclidean distances between the given 
    feature vector and all other feature vectors in the training set 
    """ 
    return [np.linalg.norm(X - X_test) for X in X_train] 

def k_nearest(X, Y, k): 
    """ 
    Get the indices of the nearest feature vectors and return a 
    list of their classes 
    """ 
    idx = np.argpartition(X, k) 
    return np.take(Y, idx[:k]) 

def predict(X_test): 
    """ 
    For each feature vector get its predicted class 
    """ 
    distance_list = [euclidean_distance(X_train, X) for X in X_test] 
    return np.array([Counter(k_nearest(distances, Y_train, k)).most_common()[0][0] for distances in distance_list]) 

はどこ明らか

X = [[ 1.96701284 6.05526865] 
    [ 1.43021202 9.17058291]] 

Y = [ 1. 0.] 

(例えば)それははるかに高速になります...私は何かを実装するために管理してきましたが、それは信じられないほど遅いです私はそれがなくても動作させる方法を知らない。ループ/リスト内包を使わずにこれを行う方法はありますか?ここで

+0

'X_train'何ですか? – Divakar

+0

@Divakar 'X'をトレーニングセットとテストセットに分割しました。 'X'は実際には' x、y'の値が2行ではなく200行であるとします。これを 'X_train'と' X_test'に分割します。 – user5368737

答えて

5

はベクトル化されたアプローチだ -

from scipy.spatial.distance import cdist 
from scipy.stats import mode 

dists = cdist(X_train, X) 
idx = np.argpartition(dists, k, axis=0)[:k] 
nearest_dists = np.take(Y_train, idx) 
out = mode(nearest_dists,axis=0)[0] 
+0

私は 'spatial.KDTree'を使ってそれを実装しましたが、これは間違いなく高速ですが、この[example](http://scikit-learn.org/stable/auto_examples/neighbors/plot_classification.html)を試してみるとまだ40秒(240秒前)だった。私は 'sklearn 'が0.7秒でこれをどうやってやれるのか理解できない? – user5368737

+0

@ user5368737さて、私はそれの内部を認識していません。しかし、もし私が推測を投げなければならないなら、私たちがここでやっているように、すべての距離を計算しておらず、最も近い 'k 'を除いてすべてを投げていないかもしれないと言うでしょう。しかし、はい、私は 'kDtree'がPython/Numpyの実装に比べて非常に速いことを見てきました。 – Divakar

+0

@ user5368737ちょっと好奇心旺盛だが、提案されたコードを変更して、より大きなデータセットに最も多くの時間を費やしているステップを確認しましたか? – Divakar

関連する問題