栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

机器学习

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

机器学习

机器学习_1:K-近领算法

文章目录
  • 实验背景
  • 1.k-近邻算法
    • 1.1算法原理
    • 1.2算法解析
    • 1.3算法实验
  • 2.基于k-近邻算法的手写体识别
    • 2.1代码解析
    • 2.2代码实现
  • 3.实验总结

实验背景

本次实验基于机器学习经典的k-近邻算法,我会先介绍k-近邻算法的原理和基础的分类实验,然后介绍如何使用k-近邻算法进行手写体识别。

1.k-近邻算法 1.1算法原理


什么是k-近邻算法,就是根据给定的要判断的点,找出k个与它距离最近的点,而这k个点中,哪种标签出现次数最多,这个要判断的点就属于那个标签。如图所示,这里的k取值为5,而这5个点中,有四个w1,所以这个判断点属于w1,这就是k-近邻算法。
伪代码:
对测试数据集中的每个点依次执行以下操作:
(1)计算训练数据集中的点与当前点之间的距离;
(2)按照距离从小到大递增排序;
(3)选取与当前点距离最小的k个点;
(4)确定这k个点所在类别的出现频率(即统计k个点中每个种类的数量)
(5)返回这k个点中出现频率最高的类别作为当前点的预测分类

1.2算法解析
以下代码为k-近邻算法的原理代码,我会尽量解析大部分代码,争取让阅读本文章的所有人都能看懂
#科学计算包numpy
from numpy import *            
#运算符模块 
import operator                 
def createDataSet():
    group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels=['A','A','B','B']
    return group,labels

#四个参数,输入向量inx(输入的测试坐标点),训练样本集dataSet(上面的那个数组group),标签向量labels(上面那个labels),k为最近邻居的数目(kNN算法中的k)
def classify0(inx,dataSet,labels,k):
    #读取矩阵第一维的长度
    dataSetSize=dataSet.shape[0]
    #diffMat存储通过tile计算输入向量inx与样本集dataSet的差值
    diffMat=tile(inx,(dataSetSize,1))-dataSet
    #将diffMat数组中的每个数平方
    sqDiffMat=diffMat**2
    #将这些数求和
    sqDistances=sqDiffMat.sum(axis=1)
    #将求和结果开根
    distances=sqDistances**0.5
    #将数据从小到大排序
    sortedDistIndicies=distances.argsort()
    #建立字典
    classCount={}
    #循环k次
    for i in range(k):
        #将标签与排列顺序对应
        voteIlabel=labels[sortedDistIndicies[i]]
        #统计标签出现频率
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    #再次排序,根据第二个元素次序,降序排序
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    #返回频率最高的标签
    return sortedClassCount[0][0]

距离的计算公式采取欧式距离公式,公式如下:

可以简单理解为对应坐标之差的平方和再开根号

1.3算法实验


如图点击上方路径,输入cmd打开命令提示符,按顺序依次输入
python
import KNN(你命名的保存k-近邻算法的文件)
group,labels=KNN.createDataSet()(创建group和labels)
KNN.classify0([0,0],group,labels,3)
这里可能会出现报错

原因是新版的python不再支持iteritems,将其改成items即可
测试结果如图,结果为B(不是B的注意下代码是否有出入)

2.基于k-近邻算法的手写体识别 2.1代码解析
#将32*32的图像转换成1*1024的向量
def img2vector(filename):
    #初始化
    returnVect=zeros((1,1024))
    #打开文件
    fr=open(filename)
    #循环赋值
    for i in range(32):
        lineStr=fr.readline()
        for j in range(32):
            returnVect[0,32*i+j]=int(lineStr[j])
    #返回数组
    return returnVect

#手写体识别测试集代码
def handwritingClassTest():
    #创建空的标签数组
    hwLabels=[]
    #获取目录内容
    trainingFileList=listdir('trainingDigits')
    #得到训练集数量
    m=len(trainingFileList)
    #初始化
    trainingMat=zeros((m,1024))
    #循环m次
    for i in range(m):
        #获取文件名
        fileNameStr=trainingFileList[i]
        #去除文件后缀
        fileStr=fileNameStr.split('.')[0]
        #文件命名格式为k_x,比如9_45(表示这个图片是数字9,在这类图像中排第45个),获取类别
        classNumStr=int(fileStr.split('_')[0])
        #将类别添加到标签数组
        hwLabels.append(classNumStr)
        trainingMat[i,:]=img2vector('trainingDigits/%s'%fileNameStr)
    #导入测试集
    testFileList=listdir('testDigits')
    #错误统计
    errorCount=0.0
    #测试数量
    mTest=len(testFileList)
    #循环训练
    for i in range(mTest):
        #获取文件名
        fileNameStr=testFileList[i]
        #去除文件后缀
        fileStr=fileNameStr.split('.')[0]
        #获取测试类别
        classNumStr=int(fileStr.split('_')[0])
        #转换成1*1024向量
        vectorUnderTest=img2vector('testDigits/%s'%fileNameStr)
        #用classify0进行判断
        classifierResult=classify0(vectorUnderTest,trainingMat,hwLabels,3)
        #显示判断结果和真实结果
        print ("the classifier came back with:%d,the real answer is :%d"%(classifierResult,classNumStr))
        #判断是否一致,不一致错误数+1
        if(classifierResult!=classNumStr):errorCount+=1.0
    #输出错误数量
    print("nthe total number of errors is:%d"%errorCount)
    #输出错误率
    print("nthe total error rate is :%f"%(errorCount/float(mTest)))
2.2代码实现

跟之前的实验一样,在代码目录输入cmd打开命令提示符后
依次输入:
python
import KNN
KNN.handwritingClassTest()

如图所示,测试结果一般在1%左右波动。

3.实验总结

本次实验可以很明显的看出k近邻算法的优缺点
优点:
1.简单有效
2.便于理解
缺点:
1.必须保存全部数据集,如果训练数据集很大,会耗费大量存储空间
2.相比其他算法,因为需要计算每个数据的距离,会非常耗时
3.无法给出任何数据的基础结构信息,因此无法知晓平均实例样本和典型样本具有什么特征
通过优缺点我们可以发现,k近邻算法很明显是适合初学者进行机器学习的基础算法,也许可以对其进一步优化,但它的设计思路决定了它的上限,很难有巨大的突破。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/290954.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号