侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python机器学习实战之最近邻kNN分类器

Python  /  管理员 发布于 7年前   170

K近邻法是有监督学习方法,原理很简单,假设我们有一堆分好类的样本数据,分好类表示每个样本都一个对应的已知类标签,当来一个测试样本要我们判断它的类别是, 就分别计算到每个样本的距离,然后选取离测试样本最近的前K个样本的标签累计投票, 得票数最多的那个标签就为测试样本的标签。

源代码详解:

#-*- coding:utf-8 -*- #!/usr/bin/python  # 测试代码 约会数据分类 import KNN  KNN.datingClassTest1() 标签为字符串  KNN.datingClassTest2() 标签为整形 # 测试代码 手写字体分类 import KNN  KNN.handwritingClassTest()  from numpy import *  # 科学计算包 import operator    # 运算符模块 from os import listdir # 获得指定目录中的内容(手写字体文件夹下样本txt) 类型命令行 ls  import matplotlib         # 画图可视化操作 import matplotlib.pyplot as plot  # 显示一个 二维图 def myPlot(x, y, labels):   fig = plot.figure()#创建一个窗口   ax = fig.add_subplot(111)# 画一个图   #ax.scatter(x,y)   ax.scatter(x,y,15.0*array(labels),15.0*array(labels)) # 支持 分类颜色显示   ax.axis([-2,25,-0.2,2.0])   plot.xlabel('Percentage of Time Spent Playing Video Games')# 坐标轴名称   plot.ylabel('Liters of Ice Cream Consumed Per Week')   plot.show()     # 创建假 的数据测试 def createDataSet():   groop = array([[1.0, 1.1],[1.0, 1.0],[0, 0],[0, 0.1]]) # numpy的array 数组格式   labels = ['A','A','B','B']# 标签 list   return groop, labels  # 定义 KNN 分类函数 def knnClassify0(inX, dataSet, labels, k):   # inX 待分类的点 数据集和标签 DataSet, label 最近领域个数 k   dataSetSize = dataSet.shape[0] # 数据集大小(行数)     # tile(A,(行维度,列维度)) A沿各个维度重复的次数   # 点A 重复每一行 到 数据集大小行   differeMat = tile(inX, (dataSetSize,1)) - dataSet # 求 待分类点 与个个数据集点的 差值   sqDiffMat = differeMat**2  # 求 平方   sqDistances = sqDiffMat.sum(axis=1)         # 求 和(各行求和)   distances = sqDistances**0.5# 开方 得到 点A 与 数据集个点 的欧式距离   sortedDistIndicies = distances.argsort()      # 返回 递增排序后 的 原位置序列(不是值)     # 取得最近的 k个点 统计 标签类出现的频率   classCount={} # 字典   for i in range(k):     voteIlabel = labels[sortedDistIndicies[i]]#从小到大 对应距离 数据点 的标签     classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 # 对于类标签 字典单词 的 值 + 1       # 对 类标签 频率(字典的 第二列(operator.itemgetter(1))) 排序 从大到小排序 reverse=True   sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)   return sortedClassCount[0][0] # 返回 最近的 对应的标签   # 真实数据的处理  输入TXT文本文件 返回 数据集和标签(已转化成数字) 列表 list def file2matrix(filename):   fr = open(filename)         # 打开文件          numberOfLines = len(fr.readlines()) # 得到文件所有的行数   returnMat = zeros((numberOfLines,3))  # 创建一个用于存储返回数据的矩阵 数据集 每个数据的大小根据实际情况!! 即是 3 列数应根据 数据维度确定   classLabelVector = []        # 对应标签   fr = open(filename)   index = 0   for line in fr.readlines():     # 每一行     line = line.strip()       # 默认删除空白符(包括'\n', '\r', '\t', ' ')     listFromLine = line.split('\t') # 按 制表符(\t) 分割字符串 成 元素列表     returnMat[index,:] = listFromLine[0:3]     # 前三个为 数据集数据     classLabelVector.append(int(listFromLine[-1])) # 最后一个 为 标签 整形     index += 1   return returnMat,classLabelVector   # 真实数据的处理  输入TXT文本文件 返回 数据集和标签(为字符串) 列表 list def file2matrix2(filename):   fr = open(filename)         # 打开文件          numberOfLines = len(fr.readlines()) # 得到文件所有的行数   returnMat = zeros((numberOfLines,3))  # 创建一个用于存储返回数据的矩阵 数据集 每个数据的大小根据实际情况!! 即是 3 列数应根据 数据维度确定   classLabelVector = []        # 对应标签   fr = open(filename)   index = 0   for line in fr.readlines():     # 每一行     line = line.strip()       # 默认删除空白符(包括'\n', '\r', '\t', ' ')     listFromLine = line.split('\t') # 按 制表符(\t) 分割字符串 成 元素列表     returnMat[index,:] = listFromLine[0:3]     # 前三个为 数据集数据     classLabelVector.append(str(listFromLine[-1])) # 最后一个 为 标签 字符串型     index += 1   return returnMat,classLabelVector   # 数据集 各个类型数据归一化 平等化 影响权值 def dataAutoNorm(dataSet):   minVals = dataSet.min(0) # 最小值 每一列的 每一种属性 的最小值   maxVals = dataSet.max(0) # 最大值   ranges = maxVals - minVals # 数据范围   normDataSet = zeros(shape(dataSet)) # 初始化输出 数组   m = dataSet.shape[0]        # 行维度 样本总数   normDataSet = dataSet - tile(minVals, (m,1))  # 扩展 minVals 成 样本总数行m行 1列(属性值个数)   normDataSet = normDataSet/tile(ranges, (m,1))  # 矩阵除法 每种属性值 归一化 numpy库 为(linalg.solve(matA,matB))   return normDataSet, ranges, minVals       # 返回 归一化后的数组 和 个属性范围以及最小值  # 约会数据 KNN分类 测试 # 标签为 字符串型 def datingClassTest1(test_ret=0.1):   hoRatio = test_ret       # 测试的样本比例 剩下的作为 训练集   datingDataMat,datingLabels = file2matrix2('datingTestSet.txt')        #载入数据集   normMat, ranges, minVals = dataAutoNorm(datingDataMat)   m = normMat.shape[0]      # 总样本数量   numTestVecs = int(m*hoRatio)  # 总测试样本数   errorCount = 0.0        # 错误次数记录   for i in range(numTestVecs):  # 对每个测试样本     # KNN 分类测试样本    剩下的作为数据集        数据集对应的标签 最近 的三个     classifierResult = knnClassify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)     print "分类结果: %s,\t真实标签: %s" % (classifierResult, datingLabels[i])     if (classifierResult != datingLabels[i]): errorCount += 1.0     print "总错误次数: %d" % errorCount   print "测试总数:  %d" % numTestVecs   print "总错误率:  %f" % (errorCount/float(numTestVecs))  # 标签为 整形 int def datingClassTest2(test_ret=0.1):   hoRatio = test_ret       # 测试的样本比例 剩下的作为 训练集   datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')        #载入数据集   normMat, ranges, minVals = dataAutoNorm(datingDataMat)   m = normMat.shape[0]      # 总样本数量   numTestVecs = int(m*hoRatio)  # 总测试样本数   errorCount = 0.0        # 错误次数记录   for i in range(numTestVecs):  # 对每个测试样本     # KNN 分类测试样本    剩下的作为数据集        数据集对应的标签 最近 的三个     classifierResult = knnClassify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)     print "分类结果: %d, 真实标签: %d" % (classifierResult, datingLabels[i])     if (classifierResult != datingLabels[i]): errorCount += 1.0     print "总错误次数: %d" % errorCount   print "测试总数:  %d" % numTestVecs   print "总错误率:  %f" % (errorCount/float(numTestVecs))   # 根据用户输入的 样本的属性值 判断用户所倾向的类型(有点问题??) def classifyPerson():   resultList = ['讨厌','一般化','非常喜欢']   percent = float(raw_input("打游戏所花时间比例: "))   mile  = float(raw_input("每年飞行的里程数量: "))   ice   = float(raw_input("每周消费的冰淇淋量: "))   datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')        #载入数据集   normMat, ranges, minVals  = dataAutoNorm(datingDataMat)   # 新测试样本 归一化   print ranges, minVals   testSampArry   = array([mile, percent, ice])  # 用户输入的 测试样例   testSampArryNorm = (testSampArry-minVals)/ranges # 样例归一化   print testSampArry ,testSampArryNorm   # 分类   classifierResult = knnClassify0(testSampArryNorm,normMat,datingLabels,3)   print classifierResult   print "他是不是你的菜: ", resultList[classifierResult-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   # 手写字体的 KNN识别 每个数字图片被转换成 32*32 的 0 1 矩阵 def handwritingClassTest(k=3):   # 得到训练数据集   hwLabels = []    # 识别的标签   trainingFileList = listdir('trainingDigits') # 加载手写字体训练数据集 (所有txt文件列表)   m = len(trainingFileList)          # 总训练样本数   trainingMat = zeros((m,1024))        # 训练数据集   for i in range(m):     fileNameStr = trainingFileList[i]    # 每个训练数据样本文件 0_0.txt 0_1.txt 0_2.txt     fileStr = fileNameStr.split('.')[0]   # 以.分割 第一个[0]为文件名  第二个[1]为类型名 txt文件     classNumStr = int(fileStr.split('_')[0]) # 以_分割,第一个[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]) # 得到对应的真实标签     vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)        # 测试样本数据     classifierResult = knnClassify0(vectorUnderTest, trainingMat, hwLabels, k) # 分类     print "KNN分类标签: %d, 真实标签: %d" % (classifierResult, classNumStr)     if (classifierResult != classNumStr): errorCount += 1.0   print "\n总的错误次数: %d" % errorCount   print "\n总的错误比例: %f" % (errorCount/float(mTest)) 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    Python绘制3d螺旋曲线图实例代码
    下一条:
    python3.6 +tkinter GUI编程 实现界面化的文本处理工具(推荐)
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客