原生python实现knn算法

作者:无*
时间:2019-10-11

一.题目分析:

原生python实现knn分类算法:
最近邻(k-Nearest Neighbor,KNN)的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,就可以得到该样本的属性。

二.算法设计:

对需要分类的点依次执行以下操作:
1.计算已知类别数据集中每个点与该点之间的距离
2.按照距离递增顺序排序
3.选取与该点距离最近的k个点
4.确定前k个点所在类别出现的频率
5.返回前k个点出现频率最高的类别作为该点的预测分类
**主要思想:
获取样本行数
将输入的测试样本扩展成格式、数量一样的矩阵
矩阵做差、平方、求平方和、开方
排序
返回最小的差值包含最多的标签数

三.源代码

from numpy import *
import operator
import  numpy as np

def createDataSet(filename):         #训练集数据及其类型
    group = []
    labels = []
    s1=[]       #训练集数据
    labels1=[]   #训练集标签
    s2=[]       #测试集数据
    labels2=[]   #测试集标签
    fr = open(filename)
    for line in fr.readlines():
        lineArr = line.strip().split(",")
        group.append([float(lineArr[0]), float(lineArr[1]), float(lineArr[2]), float(lineArr[3])])
        s1=group[:75]
        s2=group[75:100]
        labels.append(lineArr[4])
        labels1=labels[:75]
        labels2=labels[75:100]

    return s1,s2,labels1,labels2

    # return group, labels
def classify0(inX, dataSet, labels, k):
    # 返回“数组”的行数,如果shape[1]返回的则是数组的列数
    dataSetSize = np.array(dataSet).shape[0]          #numpy.array可使用 shape。list不能使用shape
    # 两个“数组”相减,得到新的数组
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet  # 求平方
    sqDiffMat = diffMat ** 2  # 求和,返回的是一维数组
    sqDistances = sqDiffMat.sum(axis=1)# 开方,即测试点到其余各个点的距离
    distances = sqDistances ** 0.5# 排序,返回值是原数组从小到大排序的下标值
    sortedDistIndicies = distances.argsort()# 定义一个空的字典
    classCount = {}
    for i in range(k):# 返回距离最近的k个点所对应的标签值
        voteIlabel = labels[sortedDistIndicies[i]]
        # 存放到字典中
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    # 排序 classCount.iteritems() 输出键值对 key代表排序的关键字 True代表降序
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    # 返回距离最小的点对应的标签

    return sortedClassCount[0][0]

s1,s2,labels1,labels2 = createDataSet('dataset.txt')
result=[]                 #result为knn算法判别结果
count=0.0
for i in s2:
    tmp = classify0(i, s1, labels1, 3)
    result.append(tmp)
print('正确的分类结果为:')
print(labels2)
print("knn判别结果为:")
print(result)
# c=[i for i in labels2 if i in result]
for i in range(len(result)):
    if(result[i]==labels2[i]):
        count+=1
score =count / len(labels2)
print(score)                                     #模型精度

(1)对训练集和测试集数据及类型进行划分(这里采用鸢尾花数据集,将鸢尾花数据集导入100组数据存储在dataset.txt中,75%划分为训练集,25%划分为测试集(利用切片操作))
在这里插入图片描述(2)将输入的测试样本扩展成格式、数量一样的矩阵。矩阵做差、平方、求平方和、开方
然后进行排序,返回最小的差值包含最多的标签数
在这里插入图片描述
(3)对此算法进行测试,result记录knn的判别结果,labels记录正确的标签结果,定义变量计算此算法的精确度。
在这里插入图片描述

四.测试及调试

(1)调试:从文本中导入鸢尾花数据集
在这里插入图片描述

计算过程:
在这里插入图片描述
(2)此程序中,应用了两组数据集进行测试,得到了以下两种结果
(文本文档为鸢尾花的数据集,总共有100组数据,75组用于训练集,25组用于测试集,最后计算出knn算法精确度)
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

五.总结

1.错误分析与解决方法

python报错:‘list’ object has no attribute ‘shape’ 解决方法:numpy.array可使用
shape。list不能使用shape。 可以使用np.array(list A)进行转换。(此处要导入numpy :import
numpy as np )
在这里插入图片描述
2.经验归纳:
  KNN算法也称为K邻近算法,是数据挖掘分类技术之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。
  KNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN算法在类别决策时,只与极少量的相邻样本有关。由于KNN算法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。在python编写代码的过程中要注意书写规范,要注意for语句和if语句的书写规范,其次就是要对数据集进行正确的分类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值