大家好,又见面了,我是你们的朋友全栈君。
数据集 提取码:mrfr
浏览本文前请先搞懂K近邻的基本原理:最简单的分类算法之一:KNN(原理解析+代码实现)
算法实现步骤:
knn中邻居一词指的就是距离相近。我们要想计算两个样本之间的距离,就必须将每一个数字变成一个向量。具体做法就是将32X32的数据每一行接在一起,形成一个1X1024的数据,这样我们就可以计算欧式距离。
代码实现:
import os
def load_data(path):
check = [i for i in range(10)]
final_data = []
for i in range(10):
final_data.append([])
files = os.listdir(path) #文件夹
for file in files:
data = open(path + "/" + file)
str = "" #将所有数据接在一起
temp = []
for line in data.readlines():
str = str + line[:-1] #去掉回车,一行接一行
for i in str:
temp.append(int(i)) #变成数字
final_data[check.index(int(file[0]))].append(temp) #根据标签放在列表相应的位置
return final_data, len(files)
def knn_mnist(K,test_data):
train_data, length = load_data('manifold/digits/trainingDigits')
distance = [] #存储测试数据到所有训练数据的距离
for i in range(len(train_data)):
for j in range(len(train_data[i])):
res = 0
for k in range(len(test_data)):
res += (test_data[k]-train_data[i][j][k]) ** 2 #欧氏距离
distance.append([res ** 0.5, i]) #距离+训练集数据标签
distance = sorted(distance, key=(lambda x: x[0])) #按距离从小到大排序
weight = [] #权重与序号
sum_distance = 0.0
for i in range(K):
sum_distance += distance[i][0] #计算前K个距离的和
for i in range(K):
weight.append([1 - distance[i][0] / sum_distance, distance[i][1]]) #权重+序号
#将相同序号的加起来
num = [] #统计有哪些序号
for i in range(K):
num.append(weight[i][1])
num = list(set(num)) #去重
final_res = []
for i in range(len(num)):
res = 0.0
for j in range(len(weight)):
if weight[j][1] == num[i]: #前K个标签一样的样本权值加起来
res += weight[j][0]
final_res.append([res, num[i]])
final_res = sorted(final_res, key=(lambda x: x[0]),reverse=True) # 按照权重从大到小排序
return final_res[0][1] #最终返回最大权值对应的标签
def test():
K = 5
test_data, length = load_data('manifold/digits/testDigits')
#测试
for i in range(len(test_data)):
for j in range(len(test_data[i])):
print(knn_mnist(K, test_data[i][j]))
if __name__ == '__main__':
test()
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/125683.html原文链接:https://javaforall.cn