常用的距离计算方法有欧式距离和曼哈顿距离两种,公式下所示:
欧氏距离:
曼哈顿距离:
KNN首先需要“记忆”所有的训练数据,这也可以看做模型的训练过程。由于只需要“记忆”而不需要参数调整,KNN的训练速度非常快。
KNN的预测方法是找出K个与待测样本距离相近的训练样本(使用上述的距离公式计算距离)。若A为K个训练样本中样本所属最多的那个种类,那么新的待测样本被预测为A。
例如:当K为5时,为带预测样本p找到最相邻的训练样本为n1,n2,n3,n4,n5。其中n1,n3,n4属于A类,a2,a5为B类,那么带预测的样本p的种类被KNN预测为A。
若累计有m个训练样本,每个样本含有特征数量为n。KNN需要计算待测样本与训练样本中的所有样本的距离(O(m))。而在计算距离时,需要分别计算每一个特征的距离(O(n))。那么,KNN模型的时间复杂度为O(m*n)。在特征数量较多,样本数量较多的时候,KNN效率较低。可以引入KD树来提升模型效率。
为了保证每个特征对模型产生相同的影响,在模型训练前需要对模型进行归一化。
使用scikit learn来实现KNN模型,采用iris数据进行测试。
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
# load data
iris_dataset = load_iris()
x_train,x_test,y_train,y_test=train_test_split(
iris_dataset['data'], iris_dataset['target'],random_state=0)
# iris data has been normalized, so no more normalization is needed
# implement knn model with k = 9
knn=KNeighborsClassifier(n_neighbors=9)
knn.fit(x_train,y_train)
# get accuracy
print("Accuracy:{:.2f}".format(knn.score(x_test,y_test)))
y_pred=knn.predict(x_test)
# compare true label and predict label
print("Predict label in test:",y_pred)
print("Real label in test:",y_test)
print("Predict result:",y_pred==y_test)