python实现k-近邻算法

本文不涉及k-近邻算法的原理,只通过python代码实现算法,并且没有用到机器学习库,根据算法流程一步一步实现。

代码实现

数据处理

假设我们已经获取了数据及其标签的文本文件,如下图所示。

在这里插入图片描述

数据有3个属性,标签分为3个类型,。python读取数据

# 读取数据并记录
def readFile(filename):
    file = open(filename)              # 打开文件
    lines = file.readlines()           # 读取每行数据
    num = len(lines)                   # 数据的数量
    X_data = np.zeros((num, 3))        # 准备存储数据特征矩阵
    X_label = []                       # 准备存储数据标签
    index = 0
    for line in lines:
        line = line.strip()            # 丢弃数据后的换行
        list = line.split('\t')        # 数据分隔
        X_data[index, :] = list[0:3]   # 存储数据特征
        X_label.append(int(list[-1]))  # 存储标签
        index += 1
    return X_data, X_label

读取数据之后,对特征进行归一化处理

# 特征归一化
def norm(data):
    min = data.min(0)       # 获取每个特征最小值
    max = data.max(0)       # 每个特征最大值
    ranges = max - min      # 每个特征极差
    normData = np.zeros(np.shape(data))             # 准备存储归一化后的特征
    m = data.shape[0]                               # 获取数据的数量
    normData = data - np.tile(min, (m, 1))          # 将最小值扩展成为矩阵的形式,大小与data相同,并相减
    normData = normData / np.tile(ranges, (m, 1))   # 将极差扩展成为矩阵的形式,大小与data相同,并相除

数据分类

kNN分类器

# kNN分类
def classify(X_data, X_label, y_data, k):
    num = X_data.shape[0]                      # 训练数据的数量          
    y = np.tile(y_data, (num, 1)) - X_data     # 测试数据扩展为训练数据大小相同的矩阵形式,并相减
    y2 = y ** 2                                # 计算平方
    distances = (y2.sum(axis=1)) ** 0.5        # 计算距离                         
    sortedDisIndex = distances.argsort()       # 排序,并获得索引
    classCount = {}
    # 前k个标签
    for i in range(k):
        vote = X_label[sortedDisIndex[i]]              # 第i个标签
        classCount[vote] = classCount.get(vote, 0) + 1  # 标签数量加1
    sortedClassCount = sorted(classCount.items(), 
        key=operator.itemgetter(1), reverse=True)       # 标签数量排序
    return sortedClassCount[0][0]

算法测试

选取10%的数据用于测试

# 测试
def test():
    ratio = 0.10                               # 0.1的数据用于测试
    X_data, X_label = readFile('set.txt')      # 读取数据
    normData, ranges, minVals = norm(X_data)   # 特征归一化
    num = normData.shape[0]                    # 数据数量
    numTest = int(num * ratio)                 # 测试数据数量
    errorCount = 0.0
    for i in range(numTest):
        result = classify(normData[numTest: num, :], X_label[numTest: num], normData[i, :], 3)   # 分类
        print("分类结果: %d, 实际结果: %d" % (result, X_label[i]))
        if (result != X_label[i]): errorCount += 1.0
    print("错误率: %f" % (errorCount / float(numTest)))
    print(errorCount)

最后通过运行test()函数即可进行测试。如果有新的数据,运行classify()函数获得分类结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值