python机器学习实战之最近邻kNN分类器
作者:大牙湾 发布时间:2021-11-11 14:55:52
标签: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))
来源:http://blog.csdn.net/xiaoxiaowenqiang/article/details/76726763
0
投稿
猜你喜欢
- 一、mysql自连接mysql有时在信息查询时需要进行对自身连接(自连接),所以我们需要为表定义别名。我们举例说明,下面是商品采购表,我们需
- 一、前置基础1. go 函数基础在Go语言中,函数的基本组成为:关键字func、函数名、参数列表、返回值、函数体和返回语句。func 函数名
- 前言:jieba是优秀的中文分词第三方库,由于中文文本之间每个汉字都是连续书写的,我们需要通过特定的手段来获得其中的每个词组,这种手段叫做分
- 可以查看mysql文件目录my.ini文件,可以找到类似于 datadir="D:/beeagle/Program Files/M
- 环境系统: Mac 工具: Alfred, git, homebrew, pngpaste. 语言: perl 其他: Gitee工具下载g
- 本文实例总结了微信小程序实现给嵌套template模板传递数据的方式。分享给大家供大家参考,具体如下:一、template模板调用的数据是单
- 前言SQL模式影响MySQL支持的SQL语法和执行的数据验证检查。MySQL服务器可以在不同的SQL模式下运行,并且可以针对不同的客户端以不
- 一、h5py模块介绍本文只是简单的对h5py库的基本创建文件,数据集和读取数据的方式进行介绍!如果读者需要进一步详细的学习h5py的更多知识
- 目录1、互斥锁Mutex1.1 Mutex介绍1.2 Mutex使用实例2、读写锁RWMutex2.1 RWMutex介绍2.2 RWMut
- 看过数据库的备份与还原。大多数都是用组件来完成的。其实可通过sql语句来完成。 由于时间关系,未对参数进行验证和界面美化。代码
- 1、numpy.array() 可以把列表转换为矩阵numpy.array(object, dtype=None, *,
- 假设有表tb_sku,其表结构如下:表中大约有200w条记录,执行如下的sql 语句大约 4.36s 返回数据select count(*)
- 本文来给大家介绍一个php版淘宝网查询商品接口代码的例子,下面要改成你的信息的在代码后面都有说明了,同时sdk包我们也要官方下载。下载SDK
- 这篇文章主要介绍了python DataFrame转dict字典过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- GO的条件变量一、条件变量与互斥锁条件变量是基于互斥锁的,它必须基于互斥锁才能发挥作用;条件变量并不是用来保护临界区和共享资源的,它是用来协
- 本文实例为大家分享了vue实现导航栏下拉菜单的具体代码,供大家参考,具体内容如下先看效果:下拉菜单铺满全屏<div class=&qu
- 1、获取对象类型,基本类型可以用type()来判断。>>> type(123)<class 'int'
- SQL Server Sa用户相信大家都有一定的理解,下面就为您介绍SQL Server 2000身份验证模式的修改方法及SQL Serve
- 一个申请单可以包含N个项目,添加申请单时就需要动态加入代码了。 动态Table表格 <table border="0&quo
- 复制一个文件夹的文件到指定目录下import osimport shutilimport timestart_time = time.tim