赞
踩
“物以类聚,人以群分”相似的数据往往拥有相同的类别
其大概原理就是一个样本归到哪一类,当前样本需要归到频次最高的哪个类去
也就是说有一个待分类的样本,然后跟他周围的k个样本来看,k中哪一个类最多,待分类的样本就是哪一个。
那就以手写数字识别为例吧
import matplotlib.pyplot as plt import numpy as np import os #%% # 读入mnist数据集 m_x = np.loadtxt('./data/mnist_x', delimiter=' ') m_y = np.loadtxt('./data/mnist_y') #%% # 数据集可视化 data = np.reshape(np.array(m_x[0], dtype=int), [28, 28]) plt.figure() plt.imshow(data, cmap='gray') #%% # 将数据集分为训练集和测试集 ratio = 0.8 split = int(len(m_x) * ratio) # 打乱数据 np.random.seed(0) idx = np.random.permutation(np.arange(len(m_x))) #随机排序 m_x = m_x[idx] m_y = m_y[idx] x_train, x_test = m_x[:split], m_x[split:] y_train, y_test = m_y[:split], m_y[split:] #%% #定义距离函数 def distance(x,y): return np.sqrt(np.sum(np.square(x-y))) #%% #定义KNN模型 class KNN: def __init__(self,k,label_num): self.k=k self.label_num=label_num #类别的数量 def fit(self,x_train,y_train): self.x_train=x_train self.y_train=y_train def get_knn_indices(self,x): #获得距离目标样本最近的k个点的标签,a来做self_x.train dis=list(map(lambda a:distance(a,x),self.x_train)) knn_indices=np.argsort(dis) #对距离排序,在选择k个出来 knn_indices=knn_indices[:self.k]#标签 return knn_indices def get_label(self,x):#计算k个点中,样本的标签数量是多少 knn_indices=self.get_knn_indices(x) label_statistic=np.zeros(shape=[self.label_num]) for index in knn_indices: label=int(self.y_train[index]) label_statistic[label]+=1 return np.argmax(label_statistic) #找出最大的类别 def predict(self,x_test): predicted_test_labels=np.zeros(shape=[len(x_test)],dtype=int) for i,x in enumerate(x_test): #枚举 predicted_test_labels[i]=self.get_label(x) return predicted_test_labels #%% for k in range(1,10): knn=KNN(k,label_num=10) knn.fit(x_train,y_train) predicted_labels=knn.predict(x_test) accuracy=np.mean(predicted_labels==y_test) print(f'k的取值为{k},预测准确率为{accuracy*100:.lf}%')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。