第三章 k近邻法

 

k近邻法没有显示的学习过程,无模型

找到K个最近点后,使用多数表决(即投票)的方式确定预测点的类别

 

 

距离度量:

预测过程中直接遍历预测点与所有点的距离,并找到最近的K个点即可。找到K个最近点后,使用多数表决(即投票)的方式确定预测点的类别。

 

K近邻算法缺点:

1、在预测样本类别时,待预测样本需要与训练集中所有样本计算距离,当训练集数量过高时(例如Mnsit训练集有60000个样本),每预测一个样本都要计算60000个距离,计算代价过高,尤其当测试集数目也较大时(Mnist测试集有10000个)。

KD树:

查找最近领点方法优化

'''
数据集:Mnist
训练集数量:60000
测试集数量:实际使用:100
------------------------------
运行结果:(邻近k数量:25)
向量距离使用算法——欧式距离
    正确率:0.98
    运行时长:108.94
'''

import numpy as np
import time
from tqdm import tqdm

def loadData(fileName):
    '''
    加载Mnist数据集
    :param fileName:要加载的数据集路径
    :return: list形式的数据集及标记
    '''
    print('start to read data')
    data = []
    label = []
    fr = open(fileName, 'r')
    for line in fr.readlines():
        curLine = line.strip().split(',')
        # if int(curLine[0]) >= 5:
        #     label.append(1)
        # else:
        #     label.append(-1)
        label.append(int(curLine[0]))
        data.append([int(num)/255 for num in curLine[1:]])
    return data, label

# 向量之间的欧式距离
def calcDist(x1, x2):
    return np.sqrt(np.sum(np.square(x1 - x2)))

def getClosest(trainDataMat, trainLabelMat, x, topK):
    '''
    :param trainDataMat:训练集数据集
    :param trainLabelMat:训练集标签集
    :param x:要预测的样本x
    :param topK:选择参考最邻近样本的数目(样本数目的选择关系到正确率,详看3.2.3 K值的选择)
    :return:预测的标记
    '''
    distList = [0] * len(trainLabelMat)
    for i in range(len(trainDataMat)):
        x1 = trainDataMat[i]
        curDist = calcDist(x1, x)
        distList[i] = curDist
    topKList = np.argsort(np.array(distList))[:topK]        #升序排序
    labelList = [0] * 10
    for index in topKList:
        labelList[int(trainLabelMat[index])] += 1
    return labelList.index(max(labelList))


def test(trainDataArr, trainLabelArr, testDataArr, testLabelArr, topK):
    '''
    测试正确率
    :param trainDataArr:训练集数据集
    :param trainLabelArr: 训练集标记
    :param testDataArr: 测试集数据集
    :param testLabelArr: 测试集标记
    :param topK: 选择多少个邻近点参考
    :return: 正确率
    '''
    print('start test')
    #将所有列表转换为矩阵形式,方便运算
    trainDataMat = np.mat(trainDataArr);
    trainLabelMat = np.mat(trainLabelArr).T
    testDataMat = np.mat(testDataArr);  # 10000,784
    testLabelMat = np.mat(testLabelArr).T  # 10000,1
    #错误值技术
    errorCnt = 0
    #测试100个样本点,时间比较长,没有实现kd树
    for i in tqdm(range(100)):
        x = testDataMat[i]
        y = getClosest(trainDataMat, trainLabelMat, x, topK)
        if y != testLabelMat[i]:
            errorCnt += 1
            # print("y: {},  testLabelMat[i]{}".format(y, testLabelMat[i]))
    return 1 - (errorCnt / 100)

if __name__ == "__main__":
    start = time.time()

    #获取训练集
    trainDataArr, trainLabelArr = loadData('../Mnist/mnist_train.csv')
    #获取测试集
    testDataArr, testLabelArr = loadData('../Mnist/mnist_test.csv')
    #计算测试集正确率
    accur = test(trainDataArr, trainLabelArr, testDataArr, testLabelArr, 25)
    #打印正确率
    print('accur is:%d'%(accur * 100), '%')
    end = time.time()
    #显示花费时间
    print('time span:', end - start)


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值