python实现 kNN(k-nearst neighbors)算法

kNN算法是k-近邻算法的简称,主要用来进行分类,主要思路如下:

1. 存在一个训练数据集,每个数据都有对应的标签,也就是说,我们知道样本集中每一数据和他对应的类别。

2. 当输入一个新数据进行类别或标签判定时,将新数据的每个特征值与训练数据集中的每个数据进行比较,计算其到训练数据集中每个点的距离(下列代码实现使用的是欧式距离)。

3. 然后提取k个与新数据最接近的训练数据点所对应的标签或类别。

4. 出现次数最多的标签或类别,记为当前预测新数据的标签或类别。

欧式距离:

 

1. 实验数据

数据来源:https://archive.ics.uci.edu/ml/datasets/Ecoli

(使用时删除了部分个数较少的数据)

 

2. 代码实现

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()

 

3. 代码说明

  • 原数据是7维的,为了使用方便,采用PCA算法降到了2维。   
    # 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

     

4. 实验结果及分析

在数据集中(一共272个数据),选取前200个数据作为本次实验的训练数据,剩下的作为测试数据。

初始的200个数据分布如下所示:

python实现 kNN(k-nearst neighbors)算法_第1张图片

 

测试数据通过KNN算法(参数k设置为10)得到的分布图:

python实现 kNN(k-nearst neighbors)算法_第2张图片

 

训练数据与测试数据汇总的分布图:

 

python实现 kNN(k-nearst neighbors)算法_第3张图片

分类的准确率:

 

参考

https://www.jb51.net/article/131053.htm

https://blog.csdn.net/weixin_43769946/article/details/103522194

 

你可能感兴趣的:(机器学习,机器学习,python,深度学习)