ML刻意练习第1周之KNN算法

本文介绍了k近邻法(k-NN)的基本原理和实战应用,包括约会网站数据分类和手写字体识别。通过KNN算法实现,探讨了数据归一化、特征处理和测试数据的选取。实战部分涉及数据导入、归一化处理、KNN算法实现以及错误率计算,总结了学习要点。
摘要由CSDN通过智能技术生成

k近邻法(k-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一种基本分类与回归方法。它的工作原理是:存在一个样本数据集合,也称作为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一个数据与所属分类的对应关系。输入没有标签的新数据后,将新的数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

KNN实战之一

1.导入算法所用的numpy和operate模块。

import numpy as np
import operator

2.创建最简单的带标签的数据集,并将其封装在函数creatDateSet()中。

def creatDateSet():
    group = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])#创建一个数组
    labels = ['A','A','B','B']
    return group,labels

3.实现最简单的KNN算法,并将其封装在函数classify0()中。
①.首先定义classify0()函数,有四个参数,inx表示待分类的新数据,dataset表示已知标签的数据集,labels为数据对应的标签,k表示待分类样本的分类取决于k个最相近的数据。

def classify0(inX, dataSet, labels, k):

②.函数的实现:首先把数据集中的点放入矩阵中,然后复制n倍(等同于dateset中样本的数目),再与dateset中的数据求距离。相当于将待分类数据与所有样本的距离存储在一个数组distances中。

dataSetSize = dataSet.shape[0]#第一维的个数(多少行)
diffMat = np.tile(inX, (dataSetSize,1)) - dataSet
    #将inX重复1次形成datasetsize行的数组,与原来的dataset的坐标差值
sqDiffMat = diffMat**2#坐标差的平方
sqDistances = sqDiffMat.sum(axis = 1)#距离的平方
distances = sqDistances**0.5#一个数组

之后返回距离从小到大排列后的索引,放入数组sortedDistIndicies中。

sortedDistIndicies = np.argsort(distances)#返回的数组从小到大排序后对应的数组索引

创建字典classCount,统计距离待分类样本最相似的k个样本的类别及每类的样本个数,最后返回最相似的那个类别。

  classCount={
   }#创建字典
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]] #距离最近的k个点分别是哪一类
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#例如{'B': 2, 'A': 1};统计了最近的k个点分别有多少属于哪类
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)#按字典内容降序排列
    return sortedClassCount[0][0]

4.综上:完整代码如下

import numpy as np
import operator
def creatDateSet():
    group = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])#创建一个数组
    labels = ['A','A','B','B']
    return group,labels

def classify0(inX, dataSet, labels, k):
    #inX是待分类的样本,dataset为数据集,labels为样本数据对应的标签,k为距离最近的k个样本
    dataSetSize = dataSet.shape[0]#第一维的个数(多少行)

    diffMat = np.tile(inX, (dataSetSize,1)) - dataSet
    #将inX重复1次形成datasetsize行的数组,与原来的dataset的坐标差值
    sqDiffMat = diffMat**2#坐标差的平方
    sqDistances = sqDiffMat.sum(axis = 1)#距离的平方
    distances = sqDistances**0.5#一个数组
    sortedDistIndicies = np.argsort(distances)#返回的数组从小到大排序后对应的数组索引
    classCount={
   }#创建字典
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]] #距离最近的k个点分别是哪一类
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#{'B': 2, 'A': 1}统计了最近的k个点分别有多少属于哪类
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)#按字典内容降序排列
    return sortedClassCount[0][0]
def main():
    group,labels = creatDateSet()
    result = classify0([0,0], group ,labels,3)
    print(result)
if __name__ == '__main__':
    main()

5.运行结果:

E:\anaconda\envs\tf1\pyt
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值