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

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)) 

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

(0)

相关推荐

  • python机器学习之神经网络(一)

    python有专门的神经网络库,但为了加深印象,我自己在numpy库的基础上,自己编写了一个简单的神经网络程序,是基于Rosenblatt感知器的,这个感知器建立在一个线性神经元之上,神经元模型的求和节点计算作用于突触输入的线性组合,同时结合外部作用的偏置,对若干个突触的输入求和后进行调节.为了便于观察,这里的数据采用二维数据. 目标函数是训练结果的误差的平方和,由于目标函数是一个二次函数,只存在一个全局极小值,所以采用梯度下降法的策略寻找目标函数的最小值. 代码如下: import numpy

  • python机器学习之决策树分类详解

    决策树分类与上一篇博客k近邻分类的最大的区别就在于,k近邻是没有训练过程的,而决策树是通过对训练数据进行分析,从而构造决策树,通过决策树来对测试数据进行分类,同样是属于监督学习的范畴.决策树的结果类似如下图: 图中方形方框代表叶节点,带圆边的方框代表决策节点,决策节点与叶节点的不同之处就是决策节点还需要通过判断该节点的状态来进一步分类. 那么如何通过训练数据来得到这样的决策树呢? 这里涉及要信息论中一个很重要的信息度量方式,香农熵.通过香农熵可以计算信息增益. 香农熵的计算公式如下: p(xi)

  • python机器学习库常用汇总

    汇总整理一套Python网页爬虫,文本处理,科学计算,机器学习和数据挖掘的兵器谱. 1. Python网页爬虫工具集 一个真实的项目,一定是从获取数据开始的.无论文本处理,机器学习和数据挖掘,都需要数据,除了通过一些渠道购买或者下载的专业数据外,常常需要大家自己动手爬数据,这个时候,爬虫就显得格外重要了,幸好,Python提供了一批很不错的网页爬虫工具框架,既能爬取数据,也能获取和清洗数据,也就从这里开始了: 1.1 Scrapy 鼎鼎大名的Scrapy,相信不少同学都有耳闻,课程图谱中的很多课

  • Python最火、R极具潜力 2017机器学习调查报告

    数据平台 Kaggle 近日发布了 2017 机器学习及数据科学调查报告,这也是 Kaggle 首次进行全行业调查.调查共收到超过 16000 份回复,受访内容包括最受欢迎的编程语言.不同国家数据科学家的平均年龄.不同国家的平均年薪等. 下面主要看看工具使用方面的结果.请注意,该报告包含多个国家的数据,可能存在收集不够全面的情况,仅供参考. 年龄 从全球范围来看,本次调查对象的平均年龄在 30 岁左右.当然,各个国家的数值会有差异,中国的机器学习从业者年龄的中位数是 25 岁. 全球全职工作者为

  • python机器学习实战之K均值聚类

    本文实例为大家分享了python K均值聚类的具体代码,供大家参考,具体内容如下 #-*- coding:utf-8 -*- #!/usr/bin/python ''''' k Means K均值聚类 ''' # 测试 # K均值聚类 import kMeans as KM KM.kMeansTest() # 二分K均值聚类 import kMeans as KM KM.biKMeansTest() # 地理位置 二分K均值聚类 import kMeans as KM KM.clusterClu

  • Python机器学习之决策树算法实例详解

    本文实例讲述了Python机器学习之决策树算法.分享给大家供大家参考,具体如下: 决策树学习是应用最广泛的归纳推理算法之一,是一种逼近离散值目标函数的方法,在这种方法中学习到的函数被表示为一棵决策树.决策树可以使用不熟悉的数据集合,并从中提取出一系列规则,机器学习算法最终将使用这些从数据集中创造的规则.决策树的优点为:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据.缺点为:可能产生过度匹配的问题.决策树适于处理离散型和连续型的数据. 在决策树中最重要的就是如何选取

  • python机器学习之神经网络(二)

    由于Rosenblatt感知器的局限性,对于非线性分类的效果不理想.为了对线性分类无法区分的数据进行分类,需要构建多层感知器结构对数据进行分类,多层感知器结构如下: 该网络由输入层,隐藏层,和输出层构成,能表示种类繁多的非线性曲面,每一个隐藏层都有一个激活函数,将该单元的输入数据与权值相乘后得到的值(即诱导局部域)经过激活函数,激活函数的输出值作为该单元的输出,激活函数类似与硬限幅函数,但硬限幅函数在阈值处是不可导的,而激活函数处处可导.本次程序中使用的激活函数是tanh函数,公式如下: tan

  • python机器学习实战之树回归详解

    本文实例为大家分享了树回归的具体代码,供大家参考,具体内容如下 #-*- coding:utf-8 -*- #!/usr/bin/python ''''' 回归树 连续值回归预测 的 回归树 ''' # 测试代码 # import regTrees as RT RT.RtTreeTest() RT.RtTreeTest('ex0.txt') RT.RtTreeTest('ex2.txt') # import regTrees as RT RT.RtTreeTest('ex2.txt',ops=(

  • 机器学习的框架偏向于Python的13个原因

    13个机器学习的框架偏向于Python的原因,供大家参考,具体内容如下 前言 主要有以下原因: 1. Python是解释语言,程序写起来非常方便 写程序方便对做机器学习的人很重要. 因为经常需要对模型进行各种各样的修改,这在编译语言里很可能是牵一发而动全身的事情,Python里通常可以用很少的时间实现. 举例来说,在C等编译语言里写一个矩阵乘法,需要自己分配操作数(矩阵)的内存.分配结果的内存.手动对BLAS接口调用gemm.最后如果没用smart pointer还得手动回收内存空间.Pytho

  • python机器学习之神经网络(三)

    前面两篇文章都是参考书本神经网络的原理,一步步写的代码,这篇博文里主要学习了如何使用neurolab库中的函数来实现神经网络的算法. 首先介绍一下neurolab库的配置: 选择你所需要的版本进行下载,下载完成后解压. neurolab需要采用python安装第三方软件包的方式进行安装,这里介绍一种安装方式: (1)进入cmd窗口 (2)进入解压文件所在目录下 (3)输入 setup.py install 这样,在python安装目录的Python27\Lib\site-packages下,就可

随机推荐