2017-03-18 88 views
0

作爲一項任務,我必須創建自己的kNN分類器,而不使用for循環。我設法使用scipy.spatial.KDTree找到測試集中每個向量的最近鄰居,然後使用scipy.stats.mode返回預測類的列表。然而,當這個集合的大小非常大時,這需要很長的時間。例如,我創建了下面的示例this page提高kNN分類器的性能(速度)

import numpy as np 
from sklearn.model_selection import train_test_split 
from scipy import spatial 
from scipy.stats import mode 

def predict(X_test): 
    X = Y_train[tree.query(X_test, k=k)[1]] 
    Y = mode(X, axis=-1)[0].T[0] 
    return Y 

def load_data(): 
    x1 = 1.5 * np.random.randn(100) + 1 
    y1 = 1.5 * np.random.randn(100) + 2 
    x2 = 1.5 * np.random.randn(100) + 3 
    y2 = 1.5 * np.random.randn(100) + 4 
    X = np.vstack((np.hstack((x1,x2)),np.hstack((y1,y2)))).T 
    y = 1.0*np.hstack((np.zeros(100), np.ones(100))) 
    return X, y 

if __name__ == '__main__': 
    X, y = load_data() 
    X_train, X_test, Y_train, Y_test = train_test_split(X, y) 

    k = 7 
    Z = predict(np.c_[xx.ravel(), yy.ravel()]) 
    Z = Z.reshape(xx.shape) 

這需要很長的啓發(40-60秒!),因爲X = Y_train[tree.query(X_test, k=k)[1]]部分。有沒有什麼辦法可以提高這個的具體實現速度,還是我應該想辦法做到這一點?例如,sklearn的實現只需要0.4秒,與我的實現相比,這是非常快速的。

回答

2

不得不閱讀你的代碼幾次,但後來我看到你正在使用KDTree而不是cKDTree。後者是用Cython實現的(而不是普通的Python和numpy),並且應該給你一個體面的加速。