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


Posted in Python onDecember 20, 2017

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 相关文章推荐
python time模块用法实例详解
Sep 11 Python
python中的全局变量用法分析
Jun 09 Python
itchat-python搭建微信机器人(附示例)
Jun 11 Python
python3 tkinter实现点击一个按钮跳出另一个窗口的方法
Jun 13 Python
浅谈Python 敏感词过滤的实现
Aug 15 Python
python日志模块logbook使用方法
Sep 19 Python
pycharm运行scrapy过程图解
Nov 22 Python
OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现
Nov 25 Python
Selenium元素定位的30种方式(史上最全)
May 11 Python
python访问hdfs的操作
Jun 06 Python
关于Kotlin中SAM转换的那些事
Sep 15 Python
python 管理系统实现mysql交互的示例代码
Dec 06 Python
python3.6 +tkinter GUI编程 实现界面化的文本处理工具(推荐)
Dec 20 #Python
浅谈Python实现Apriori算法介绍
Dec 20 #Python
利用Python如何生成hash值示例详解
Dec 20 #Python
python 3.6 tkinter+urllib+json实现火车车次信息查询功能
Dec 20 #Python
python实现神经网络感知器算法
Dec 20 #Python
Python代码实现KNN算法
Dec 20 #Python
详解appium+python 启动一个app步骤
Dec 20 #Python
You might like
php array_slice函数的使用以及参数详解
2008/08/30 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
2013/04/26 PHP
php 发送带附件邮件示例
2014/01/23 PHP
php smarty模板引擎的6个小技巧
2014/04/24 PHP
使用PHP把HTML生成PDF文件的几个开源项目介绍
2014/11/17 PHP
thinkphp 抓取网站的内容并且保存到本地的实例详解
2017/08/25 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
CI框架网页缓存简单用法分析
2018/12/26 PHP
js removeChild 障眼法 可能出现的错误
2009/10/06 Javascript
jQuery与ExtJS之选择实例分析
2010/08/19 Javascript
调试Javascript代码(浏览器F12及VS中debugger关键字)
2013/01/25 Javascript
jquery的总体架构分析及实现示例详解
2014/11/08 Javascript
jQuery的观察者模式详解
2014/12/22 Javascript
快速学习jQuery插件 Form表单插件使用方法
2015/12/01 Javascript
JS使用正则表达式过滤多个词语并替换为相同长度星号的方法
2016/08/03 Javascript
js 公式编辑器 - 自定义匹配规则 - 带提示下拉框 - 动态获取光标像素坐标
2018/01/04 Javascript
详解Javascript中new()到底做了些什么?
2018/03/29 Javascript
JS实现继承的几种常用方式示例
2019/06/22 Javascript
Vue引入Stylus知识点总结
2020/01/16 Javascript
vue切换菜单取消未完成接口请求的案例
2020/11/13 Javascript
JavaScript实现复选框全选和取消全选
2020/11/20 Javascript
Python UnicodeEncodeError: 'gbk' codec can't encode character 解决方法
2015/04/24 Python
Python父目录、子目录的相互调用方法
2019/02/16 Python
django ModelForm修改显示缩略图 imagefield类型的实例
2019/07/28 Python
结合OpenCV与TensorFlow进行人脸识别的实现
2019/10/10 Python
使用IDLE的Python shell窗口实例详解
2019/11/19 Python
Pytorch 多维数组运算过程的索引处理方式
2019/12/27 Python
TensorFlow 输出checkpoint 中的变量名与变量值方式
2020/02/11 Python
linux系统都有哪些运行级别
2012/04/15 面试题
幼儿园教师考核制度
2014/02/01 职场文书
金融事务专业求职信
2014/04/25 职场文书
五四青年节演讲稿
2014/05/26 职场文书
2015年学校信息技术工作总结
2015/05/25 职场文书
创业计划书之牛肉汤快餐店
2019/10/08 职场文书
css3中2D转换之有趣的transform形变效果
2022/02/24 HTML / CSS
python的列表生成式,生成器和generator对象你了解吗
2022/03/16 Python