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处理cookie详解
Feb 07 Python
python sort、sorted高级排序技巧
Nov 21 Python
python 生成器协程运算实例
Sep 04 Python
python ansible服务及剧本编写
Dec 29 Python
pycharm+PyQt5+python最新开发环境配置(踩坑)
Feb 11 Python
python文件写入write()的操作
May 14 Python
Python编程快速上手——Excel到CSV的转换程序案例分析
Feb 28 Python
Python3创建Django项目的几种方法(3种)
Jun 03 Python
python中线程和进程有何区别
Jun 17 Python
Python urlopen()参数代码示例解析
Dec 10 Python
详解python的xlwings库读写excel操作总结
Feb 26 Python
Python通用验证码识别OCR库ddddocr的安装使用教程
Jul 07 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关于IE下的iframe跨域导致session丢失问题解决方法
2013/10/10 PHP
PHP循环结构实例讲解
2014/02/10 PHP
PHP 5.6.11 访问SQL Server2008R2的几种情况详解
2016/08/08 PHP
JavaScript中的原型链prototype介绍
2014/12/30 Javascript
jquery获取url参数及url加参数的方法
2015/10/26 Javascript
AngularJS中的$watch(),$digest()和$apply()区分
2016/04/04 Javascript
微信小程序 教程之列表渲染
2016/10/18 Javascript
JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
2017/05/30 Javascript
理解 Node.js 事件驱动机制的原理
2017/08/16 Javascript
纯javascript前端实现base64图片下载(兼容IE10+)
2018/09/14 Javascript
js自定义input文件上传样式
2018/10/26 Javascript
Nodejs中怎么实现函数的串行执行
2019/03/02 NodeJs
微信小程序使用字体图标的方法
2019/05/23 Javascript
vue-cli 项目打包完成后运行文件路径报错问题
2019/07/19 Javascript
解决layer.prompt无效的问题
2019/09/24 Javascript
js实现贪吃蛇小游戏(加墙)
2020/07/31 Javascript
Python 随机生成中文验证码的实例代码
2013/03/20 Python
python处理大数字的方法
2015/05/27 Python
通过mod_python配置运行在Apache上的Django框架
2015/07/22 Python
理想高通滤波实现Python opencv示例
2019/01/30 Python
Python 仅获取响应头, 不获取实体的实例
2019/08/21 Python
Python如何计算语句执行时间
2019/11/22 Python
解决pyecharts运行后产生的html文件用浏览器打开空白
2020/03/11 Python
python调用jenkinsAPI构建jenkins,并传递参数的示例
2020/12/09 Python
NBA德国官方网上商店:NBA Store德国
2018/04/13 全球购物
美国迪克体育用品商店:DICK’S Sporting Goods
2018/07/24 全球购物
戴森英国官网:Dyson英国
2019/05/07 全球购物
园林毕业生自我鉴定范文
2013/12/29 职场文书
产品包装策划方案
2014/05/18 职场文书
公司财务会计主管应聘求职信
2014/09/26 职场文书
出差报告格式模板
2014/11/06 职场文书
公司清洁工岗位职责
2015/04/15 职场文书
2016教师给学生的毕业寄语
2015/12/04 职场文书
学习nginx基础知识
2021/09/04 Servers
剧场版《转生恶役只好拔除破灭旗标》公开最新视觉图 2023年上映
2022/04/02 日漫
MySQL中的全表扫描和索引树扫描
2022/05/15 MySQL