Как упомянуто в комментарии, вам нужно рассмотреть другие алгоритмы для ускорения KNN, такие как деревья шаров (которые хорошо работают на наборах данных с большим количеством признаков) или деревья kd. Оптимизация алгоритма уменьшит временную сложность в геометрической прогрессии.
Но если вы продолжите поиск методом грубой силы, вам может пригодиться следующая информация:
Поскольку вы уже используете numpy почему бы не использовать scipy для ускорения ваших расчетов. Вы можете использовать scipy.spatial.distance.cdist
вместо тройных циклов, чтобы получить метрику расстояния, и scipy.argsort
, чтобы найти индекс для первого NN.
Я изменил ваш код следующим образом:
from scipy.spatial.distance import cdist
from scipy import argsort
from scipy.stats import mode
def KNN2(x, y):
# Create sum of square distances for each feature in each row
d_arr = cdist(x,x)
d_arr += np.eye(x.shape[0])*np.max(d_arr)
# Find the index for the first NN
idx_arr = argsort(d_arr, axis=1)[:, : 1]
# ! I don't touch this part
# Make a prediction based off the position in y_train for the test row
y_hat = []
for i in range(0,len(idx_arr)):
y_hat.append(float(y[idx_arr[i]]))
del idx_arr
y_hat = np.array(y_hat)
y_hat = np.reshape(y_hat,(len(y_hat),1))
a = np.where(y==y_hat, 1, 0)
accuracy = float(np.sum(a,axis=0)/float(len(a)))*100.0
return accuracy
Тестирование на моем P C:
%timeit KNN1(xtrain2,ytrain2)
# 51.4 ms ± 523 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit KNN2(xtrain2,ytrain2)
# 1.24 ms ± 26.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Один крошечный KNN, который я реализовал, можно увидеть здесь .