机器学习实战 - python3 学习笔记(一) - k近邻算法
一. 使用k近邻算法改进约会网站的配对效果
k-近邻算法的一般流程:
- 收集数据:可以使用爬虫进行数据的收集,也可以使用第三方提供的免费或收费的数据。一般来讲,数据放在txt文本文件中,按照一定的格式进行存储,便于解析及处理。
- 准备数据:使用Python解析、预处理数据。
- 分析数据:可以使用很多方法对数据进行分析,例如使用Matplotlib将数据可视化。
- 测试算法:计算错误率。
- 使用算法:错误率在可接受范围内,就可以运行k-近邻算法进行分类。
实战内容:
海伦女士一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的任选,但她并不是喜欢每一个人。经过一番总结,她发现自己交往过的人可以进行如下分类:
- 不喜欢的人
- 魅力一般的人
- 极具魅力的人
海伦收集约会数据已经有了一段时间,她把这些数据存放在文本文件datingTestSet.txt中,每个样本数据占据一行,总共有1000行。
海伦收集的样本数据主要包含以下3种特征:
- 每年获得的飞行常客里程数
- 玩视频游戏所消耗时间百分比
- 每周消费的冰淇淋公升数
完整代码:
- import numpy as np
- import operator
- import matplotlib
- import matplotlib.pyplot as plt
- def classify0(inX, dataSet, labels, k):
- '''距离计算'''
- dataSetSize = dataSet.shape[0]
- diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
- sqDiffMat = diffMat ** 2
- sqDistances = sqDiffMat.sum(axis=1)
- distances = sqDistances ** 0.5
- sortedDistIndicies = distances.argsort()
- classCount = {}
- '''选择距离最小的k个点'''
- for i in range(k):
- voteIlabel = labels[sortedDistIndicies[i]]
- classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
- '''排序'''
- sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
- return sortedClassCount[0][0]
- def file2matrix(filename):
- fr = open(filename) # 打开文件
- arrayOfLines = fr.readlines() # 读取文件所有内容
- numberOfLines = len(arrayOfLines) # 返回文件的行数
- returnMat = np.zeros((numberOfLines, 3))
- classLabelVector = []
- index = 0
- for line in arrayOfLines:
- line = line.strip()
- listFromLine = line.split('\t')
- returnMat[index, :] = listFromLine[0:3]
- # 根据文本中标记的喜欢的程度进行分类,1代表不喜欢,2代表魅力一般,3代表极具魅力
- if listFromLine[-1] == 'didntLike':
- classLabelVector.append(1)
- elif listFromLine[-1] == 'smallDoses':
- classLabelVector.append(2)
- elif listFromLine[-1] == 'largeDoses':
- classLabelVector.append(3)
- index += 1
- return returnMat, classLabelVector
- datingDataMat, datingLabels = file2matrix('datingTestSet.txt')
- fig = plt.figure()
- ax = fig.add_subplot(111)
- ax.scatter(datingDataMat[:, 1], datingDataMat[:, 2], 15.0 * np.array(datingLabels), 15.0 * np.array(datingLabels))
- plt.show()
- def autoNorm(dataSet):
- '''归一化特征值:利用公式 newValue = (oldValue - min) / (max - min), 这个公式可以将任意取值范围的特征值转化为0到1区间的值'''
- normDataSet = np.zeros(np.shape(dataSet))
- m = dataSet.shape[0]
- minVals = dataSet.min(0) # min(0) 表示返回矩阵中所有列的最小值,当min(1)时,则返回矩阵中所有行的最小值
- maxVals = dataSet.max(0)
- ranges = maxVals - minVals
- normDataSet = dataSet - np.tile(minVals, (m, 1))
- normDataSet = normDataSet / np.tile(ranges, (m, 1))
- return normDataSet, ranges, minVals
- normMat, ranges, minVals = autoNorm(datingDataMat)
- def datingClassTest():
- hoRatio = 0.10 # 取所有数据的百分之10
- filename = 'datingTestSet.txt'
- datingDataMat, datingLabels = file2matrix(filename)
- normMat, ranges, minVals = autoNorm(datingDataMat)
- m = normMat.shape[0]
- numTestVes = int(m * hoRatio) # 测试集数量
- errorCount = 0.0 # 错误的次数
- for i in range(numTestVes):
- # 前100个数据作为测试集,后900个数据作为训练集
- classifierResult = classify0(normMat[i, :], normMat[numTestVes:m, :], datingLabels[numTestVes:m], 4)
- print('分类结果: %d, 真实类别: %d'%(classifierResult, datingLabels[i]))
- if (classifierResult != datingLabels[i]):
- errorCount += 1.0
- print('错误率: %f%%' % (errorCount / float(numTestVes) * 100))
- datingClassTest()
- def classifyPerson():
- resultList = ['讨厌', '有些喜欢', '非常喜欢']
- percentTats = float(input('玩视频游戏所耗时间百分比:'))
- ffMiles = float(input('每年获得的飞行常客里程数:'))
- iceCream = float(input('每周消费的冰淇淋公升数:'))
- filename = 'datingTestSet.txt'
- datingDataMat, datingLabels = file2matrix(filename)
- normMat, ranges, minVals = autoNorm(datingDataMat)
- inArr = np.array([ffMiles, percentTats, iceCream])
- classifierResult = classify0((inArr - minVals) / ranges, normMat, datingLabels, 4)
- print('你可能%s这个人' % (resultList[classifierResult - 1]))
- classifyPerson()
运行结果:
二. sklearn手写数字识别系统
- 为了简单起见,这里构造的系统只能识别数字0到9,需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小①:宽高是32像素×32像素的黑白图像。尽管采用文本格式存储图像不能有效地利用内存空间,但是为了方便理解,我们还是将图像转换为文本格式。
接下来,我们将使用强大的第三方Python科学计算库Sklearn构建手写数字系统。
- import numpy as np
- import operator
- from os import listdir
- from sklearn.neighbors import KNeighborsClassifier as KNN
- def img2Vector(filename):
- '''将32*32的二进制图像转换为1*1024向量'''
- # 创建1*1024 的零向量
- returnVect = np.zeros((1, 1024))
- # 打开文件
- fr = open(filename)
- # 按行读取
- for i in range(32):
- # 读一行数据
- lineStr = fr.readline()
- # 每一行的前32个元素依次添加到returnVect中
- for j in range(32):
- returnVect[0, 32 * i + j] = int(lineStr[j])
- # 返回转换后的1*1024向量
- return returnVect
- def handwritingClassTest():
- '''手写数字分类测试'''
- # 测试集的Labels
- hwLabels = []
- # 返回trainingDigits目录下的文件名
- trainingFileList = listdir('trainingDigits')
- # 返回文件夹下文件的个数
- m = len(trainingFileList)
- # 初始化训练的Mat矩阵,测试集
- trainingMat = np.zeros((m, 1024))
- # 从文件名中解析出训练集的类别
- for i in range(m):
- # 获得文件的名字
- fileNameStr = trainingFileList[i]
- # 获得分类的数字
- classNumber = int(fileNameStr.split('_')[0])
- # 将获得的类别添加到hwLabels中
- hwLabels.append(classNumber)
- # 将每一个文件的1*1024数据存储到trainingMat矩阵中
- trainingMat[i, :] = img2Vector('trainingDigits/%s' % (fileNameStr))
- # 构建KNN分类器
- neigh = KNN(n_neighbors=3, algorithm='auto')
- # 拟合模型,trainingMat为训练矩阵,hwLabels为对应的标签
- neigh.fit(trainingMat,hwLabels)
- # 返回testDigits目录下的文件列表
- testFileList = listdir('testDigits')
- # 错误检测计数
- errorCount = 0.0
- # 测试集的数量
- mTest = len(testFileList)
- # 从文件中解析出测试集的类别并进行分类
- for i in range(mTest):
- # 获得文件的名字
- fileNameStr = testFileList[i]
- # 获得分类的数字
- classNumber = int(fileNameStr.split('_')[0])
- # 获得测试集的1*1024向量,用于训练
- vectorUnderTest = img2Vector('testDigits/%s' % (fileNameStr))
- # 获得预测结果
- classifierResult = neigh.predict(vectorUnderTest)
- print('分类返回结果为:%d\t真是结果为:%d' % (classifierResult, classNumber))
- if classifierResult != classNumber:
- errorCount += 1.0
- print('总共错了 %d 个数据\n错误率为:%f%%' % (errorCount, errorCount / mTest * 100))
- handwritingClassTest()
运行结果:
机器学习实战 - python3 学习笔记(一) - k近邻算法的更多相关文章
- 《机器学习实战》学习笔记一K邻近算法
一. K邻近算法思想:存在一个样本数据集合,称为训练样本集,并且每个数据都存在标签,即我们知道样本集中每一数据(这里的数据是一组数据,可以是n维向量)与所属分类的对应关系.输入没有标签的新数据后,将 ...
- 《机器学习实战》学习笔记第十四章 —— 利用SVD简化数据
相关博客: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) <机器学习实战>学习笔记第十三章 —— 利用PCA来简化数据 奇异值分解(SVD)原理与在降维中的应用 机器学习( ...
- 《机器学习实战》学习笔记第九章 —— 决策树之CART算法
相关博文: <机器学习实战>学习笔记第三章 —— 决策树 主要内容: 一.CART算法简介 二.分类树 三.回归树 四.构建回归树 五.回归树的剪枝 六.模型树 七.树回归与标准回归的比较 ...
- 《机器学习实战》学习笔记第二章 —— K-近邻算法
主要内容: 一.算法概述 二.距离度量 三.k值的选择 四.分类决策规则 五.利用KNN对约会对象进行分类 六.利用KNN构建手写识别系统 七.KNN之线性扫描法的不足 八.KD树 一.算法概述 1. ...
- 《机实战》第2章 K近邻算法实战(KNN)
1.准备:使用Python导入数据 1.创建kNN.py文件,并在其中增加下面的代码: from numpy import * #导入科学计算包 import operator #运算符模块,k近邻算 ...
- [转]Python3《机器学习实战》学习笔记(一):k-近邻算法(史诗级干货长文)
转自http://blog.csdn.net/c406495762/article/details/75172850 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 一 简 ...
- 《机器学习实战》学习笔记第十三章 —— 利用PCA来简化数据
相关博文: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) 主成分分析(PCA)的推导与解释 主要内容: 一.向量內积的几何意义 二.基的变换 三.协方差矩阵 四.PCA求解 一.向量內 ...
- 《机器学习实战》学习笔记——第13章 PCA
1. 降维技术 1.1 降维的必要性 1. 多重共线性--预测变量之间相互关联.多重共线性会导致解空间的不稳定,从而可能导致结果的不连贯.2. 高维空间本身具有稀疏性.一维正态分布有68%的值落于正负 ...
- Python3《机器学习实战》学习笔记(一):k-近邻算法(史诗级干货长文)
https://blog.csdn.net/c406495762/article/details/75172850
随机推荐
- Rgb2Gray
GPU上运行的函数又称为Kernel,用__global__修饰 调用Kernel函数时,用FunctionCall<<<block_shape, thread_shape, int ...
- Javascript高级编程学习笔记(4)—— JS中的数据类型(2)
接着昨天的文章,今天这篇文章主要讲述JS中剩余的两种数据类型String,和Object String类型 对于该类型,书中给出的解释为:由0或多个16为Unicode字符组成的字符序列. 对于JS中 ...
- Redis 分布式锁进化史(解读 + 缺陷分析)
Redis分布式锁进化史 近两年来微服务变得越来越热门,越来越多的应用部署在分布式环境中,在分布式环境中,数据一致性是一直以来需要关注并且去解决的问题,分布式锁也就成为了一种广泛使用的技术,常用的分布 ...
- Go标准库之读写文件(File)
Go标准库之读写文件(File) 创建一个空文件 package main import ( "log" "os" ) func main() { file, ...
- Cannot determine embedded database driver class for database type NONE
springboot+jpa使用自定义配置文件连接数据库报错:Cannot determine embedded database driver class for database type NON ...
- ZolltyMVC配置-说明文档
目前XML里支持的一级元素如下: <!-- 配置 --> <xsd:element ref="mvc"/> <xsd:element ...
- mysql 开发进阶篇系列 28 数据库二进制包安装(centos系统准备)
1. centos 7安装工作 对于mysql二进制安装,我这里在使用一台新的centos系统.准备好VMware,Xftp-6.0, Xshell-6.0.在VMware中网络使用桥接模式,分配20 ...
- 从零开始学 Web 之 DOM(二)对样式的操作,获取元素的方式
大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...
- Java 8 新特性-菜鸟教程 (6) -Java 8 Optional 类
Java 8 Optional 类 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容 ...
- C# 匿名类型序列化、反序列化
前言 现在提倡前后端分离,分离后服务全部采用接口的方式给前端提供服务,当我们处理自定义查询时必定会多表查询,而处理多表查询时我们又懒的去建view model,建的过多项目也凌乱的很,所以在dao层处 ...