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中的二维数组的操作方法
May 02 Python
九步学会Python装饰器
May 09 Python
浅谈Python中的闭包
Jul 08 Python
python下10个简单实例代码
Nov 15 Python
使用python实现knn算法
Dec 20 Python
python如何将图片转换为字符图片
Aug 19 Python
tensorflow 加载部分变量的实例讲解
Jul 27 Python
Python数据可视化教程之Matplotlib实现各种图表实例
Jan 13 Python
python 一篇文章搞懂装饰器所有用法(建议收藏)
Aug 23 Python
python系列 文件操作的代码
Oct 06 Python
Python 日期时间datetime 加一天,减一天,加减一小时一分钟,加减一年
Apr 16 Python
Python如何读写二进制数组数据
Aug 01 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
谈一谈收音机的高放电路
2021/03/02 无线电
PHP 面向对象 PHP5 中的常量
2010/05/05 PHP
php从右向左/从左向右截取字符串的实现方法
2011/11/28 PHP
php中的PHP_EOL换行符详细解析
2013/10/26 PHP
php连接与操作PostgreSQL数据库的方法
2014/12/25 PHP
laravel实现前后台路由分离的方法
2019/10/13 PHP
ASP中用Join和Array,可以加快字符连接速度的代码
2007/08/22 Javascript
javascript 循环读取JSON数据的代码
2010/07/17 Javascript
JS解析json数据并将json字符串转化为数组的实现方法
2012/12/25 Javascript
js使用eval解析json(js中使用json)
2014/01/17 Javascript
使用javascript实现监控视频播放并打印日志
2015/01/05 Javascript
AngularJS监听路由变化的方法
2017/03/07 Javascript
Angularjs 与 bower安装和使用详解
2017/05/11 Javascript
利用vueJs实现图片轮播实例代码
2017/06/03 Javascript
详解在Angular项目中添加插件ng-bootstrap
2017/07/04 Javascript
JavaScript设计模式之调停者模式实例详解
2018/02/03 Javascript
vue项目关闭eslint校验
2018/03/21 Javascript
用vue2.0实现点击选中active其他选项互斥的效果
2018/04/12 Javascript
nodejs前端模板引擎swig入门详解
2018/05/15 NodeJs
vue.js绑定事件监听器示例【基于v-on事件绑定】
2018/07/07 Javascript
解决vuex数据异步造成初始化的时候没值报错问题
2019/11/13 Javascript
关于vue利用postcss-pxtorem进行移动端适配的问题
2019/11/20 Javascript
小程序实现投票进度条
2019/11/20 Javascript
Python实现给qq邮箱发送邮件的方法
2015/05/28 Python
Python实现多条件筛选目标数据功能【测试可用】
2018/06/13 Python
python中pika模块问题的深入探究
2018/10/13 Python
python 字符串追加实例
2019/07/20 Python
泰国网上购物:Shopee泰国
2018/09/14 全球购物
沙特阿拉伯家用电器和电子产品购物网站:Sheta and Saif
2020/04/03 全球购物
几道数据库的面试题或笔试题
2014/05/31 面试题
财经学院自荐信范文
2014/02/02 职场文书
入党积极分子评语
2014/05/04 职场文书
演讲稿的格式及范文
2014/08/22 职场文书
幸福终点站观后感
2015/06/04 职场文书
幼儿园卫生保健制度
2015/08/05 职场文书
十一月早安语录:把心放轻,人生就是一朵自在的云
2019/11/04 职场文书