一、K近邻算法简介
1.K近邻算法:
当输入一个测试数据,我们在训练数据集当中找到K个与输入数据最相近的,通常这个可以用欧几里得距离来衡量(当然其他距离也可以)。然后观察这K个邻居中他们的标签(类别),最多的是哪一类,最后把输入的测试数据的标签设定为投票数最多的类别即完成目标。
通常K近邻算法是用来完成分类任务的,所以它可以被视为分类算法。但是实际上该算法思想也可以用来完成回归任务,比如把输入数据的y值设定为K个邻居的y值的平均数,即可完成回归任务。事实上,sklearn中除了有KNeighborsClassifier,也有KNeighborsRegressor,用来完成回归任务。
2.优点:
精度高,因为是经过了所有训练数据的投票。
对异常值不敏感,因为个别异常值在投票中占少数。
不用对模型进行训练,直接计算即可。
无数据输入假定。
3.缺点
计算复杂度高,空间复杂度高(当数据量上万时,速度会很慢)
二、代码实现
import scipy.io as scio
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import numpy as np
def load_data():
print("[INFO]: loading MNIST (full) dataset...")
dataset = scio.loadmat(
r"~\mnist-original.mat" #换成你的数据所在路径,数据可以搜索名字,下载
)
data = dataset['data'].astype("float") /255.0
return train_test_split(data.T,dataset['label'].T)
def classify(x, dataset, labels, k):
# np.tile 让x在第一个维度上重复dataset.shape[0]次,在第二个维度上重复一次,
# 最后形状跟dataset一样
diff_matrix=np.tile(x, (dataset.shape[0],1)) - dataset
square_diff_matrix = diff_matrix ** 2
distances = np.sqrt(square_diff_matrix.sum(axis=1))
sorted_idx = distances.argsort()
class_count = {}
for i in range(k):
vote_label = labels[sorted_idx[i]][0]
class_count[vote_label] = class_count.get(vote_label, 0) + 1
sorted_class_count = sorted(class_count.items(), key=lambda x: x[1], reverse=True)
return sorted_class_count[0][0]
def fit(testX,dataset,labels,k):
result = []
for each in testX:
result.append(classify(each,dataset,labels,k))
return result
(trainX, testX, trainY, testY) = load_data()
predictions = fit(testX[0:50], trainX[0:1000], trainY[0:1000], 10)
print(classification_report(testY[0:50], predictions))
三、调用sklearn中的KNeighborsClassifier
事实上,sklearn中已经有该算法的实现,我们需要的时候可以直接调用,而不需要自己编写。
from sklearn.neighbors import KNeighborsClassifier
#这里的load_data函数与上面的一致
(trainX, testX, trainY, testY) = load_data()
model = KNeighborsClassifier(n_neighbors=10, n_jobs=-1)
model.fit(trainX[0:1000], trainY[0:1000])
print(classification_report(testY[0:50], model.predict(testX[0:50])))