kNN算法是k-近邻算法的简称,主要用来进行分类,主要思路如下:
1. 存在一个训练数据集,每个数据都有对应的标签,也就是说,我们知道样本集中每一数据和他对应的类别。
2. 当输入一个新数据进行类别或标签判定时,将新数据的每个特征值与训练数据集中的每个数据进行比较,计算其到训练数据集中每个点的距离(下列代码实现使用的是欧式距离)。
3. 然后提取k个与新数据最接近的训练数据点所对应的标签或类别。
4. 出现次数最多的标签或类别,记为当前预测新数据的标签或类别。
欧式距离:
数据来源:https://archive.ics.uci.edu/ml/datasets/Ecoli
(使用时删除了部分个数较少的数据)
import numpy as np
import operator
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
# KNN分类器
def KNNClassifier (X, train_data, train_lable, k):
# 向量X在行方向平铺
XTile = np.tile(X, (train_data.shape[0], 1))
# 向量X与训练数据差值的平方
squareDiff = (XTile - train_data) ** 2
# 在列方向求和并开方得到距离向量
distance = (squareDiff.sum(axis=1)) ** 0.5
# 得到距离排序后的索引
sortedIndex = np.argsort(distance)
# 分类map key:类别 value:出现的次数
claMap = {}
for i in range(k):
lab = train_lable[sortedIndex[i]]
claMap[lab] = claMap.get(lab, 0) + 1
sortedMap = sorted(claMap.items(), key=operator.itemgetter(1), reverse=True)
return sortedMap[0][0]
if __name__ == '__main__':
# 读取数据
url = r'C:\Users\70423\Desktop\ecoli.data'
ori_data = np.loadtxt(url, usecols=(range(1, 9)), dtype=str)
# 数据清洗(打乱数据顺序)
np.random.shuffle(ori_data)
# 数据集
data = ori_data[:, :7]
# 标签集
lable = ori_data[:, 7]
# PCA降维
pca = PCA(n_components=2)
reduce_data = pca.fit_transform(data)
# 选取200个数据作为训练样本
train_data = reduce_data[:200]
train_lable = lable[:200]
# 剩下的数据作为测试集
test_data = reduce_data[200:]
test_lable = lable[200:]
# 通过KNN分类器得到的标签
cla_lable = []
map_color = {'cp': 'r', 'im': 'b', 'pp': 'g'}
train_color = list(map(lambda x: map_color[x], train_lable))
plt.scatter(train_data[:, 0], train_data[:, 1], c=train_color, label='train data')
plt.legend(edgecolor='blue')
plt.savefig(r"E:\Material\KNN\1.jpg")
plt.show()
sum = 0
for i in range(len(test_data)):
lab = KNNClassifier(test_data[i], train_data, train_lable, 10)
cla_lable.append(lab)
if lab == test_lable[i]:
sum += 1
# 分类准确率
accuracy = sum / len(test_data)
print("Accuracy of this way is %.4f" % accuracy)
test_color = list(map(lambda x: map_color[x], cla_lable))
plt.scatter(test_data[:, 0], test_data[:, 1], c=test_color, marker='x', label='test data')
plt.legend(edgecolor='blue')
plt.savefig(r"E:\Material\KNN\2.jpg")
plt.show()
plt.scatter(train_data[:, 0], train_data[:, 1], c=train_color, label='train data')
plt.scatter(test_data[:, 0], test_data[:, 1], c=test_color, label='test data', marker='x')
plt.legend(edgecolor='blue')
plt.savefig(r"E:\Material\KNN\3.jpg")
plt.show()
# PCA降维
pca = PCA(n_components=2)
reduce_data = pca.fit_transform(data)
# 向量X在行方向平铺
XTile = np.tile(X, (train_data.shape[0], 1))
# 向量X与训练数据差值的平方
squareDiff = (XTile - train_data) ** 2
# 在列方向求和并开方得到距离向量
distance = (squareDiff.sum(axis=1)) ** 0.5
在数据集中(一共272个数据),选取前200个数据作为本次实验的训练数据,剩下的作为测试数据。
初始的200个数据分布如下所示:
测试数据通过KNN算法(参数k设置为10)得到的分布图:
训练数据与测试数据汇总的分布图:
分类的准确率:
https://www.jb51.net/article/131053.htm
https://blog.csdn.net/weixin_43769946/article/details/103522194