Python实现机器学习算法:K近邻算法
'''
数据集:Mnist
训练集数量:60000
测试集数量:10000(实际使用:200)
'''
import numpy as np
import time
def loadData(fileName):
'''
加载文件
:param fileName:要加载的文件路径
:return: 数据集和标签集
'''
print('start read file')
# 存放数据及标记
dataArr = []
labelArr = []
# 读取文件
fr = open(fileName)
# 遍历文件中的每一行
for line in fr.readlines():
# 获取当前行,并按“,”切割成字段放入列表中
# strip:去掉每行字符串首尾指定的字符(默认空格或换行符)
# split:按照指定的字符将字符串切割成每个字段,返回列表形式
curLine = line.strip().split(',')
# 将每行中除标记外的数据放入数据集中(curLine[0]为标记信息)
# 在放入的同时将原先字符串形式的数据转换为整型
dataArr.append([int(num) for num in curLine[1:]])
# 将标记信息放入标记集中
# 放入的同时将标记转换为整型
labelArr.append(int(curLine[0]))
# 返回数据集和标记
return dataArr, labelArr
def calcDist(x1, x2):
'''
计算两个样本点向量之间的距离
使用的是欧氏距离,即 样本点每个元素相减的平方 再求和 再开方
欧式举例公式这里不方便写,可以百度或谷歌欧式距离(也称欧几里得距离)
:param x1:向量1
:param x2:向量2
:return:向量之间的欧式距离
'''
return np.sqrt(np.sum(np.square(x1 - x2)))
# 马哈顿距离计算公式
# return np.sum(x1 - x2)
def getClosest(trainDataMat, trainLabelMat, x, topK):
'''
预测样本x的标记。
获取方式通过找到与样本x最近的topK个点,并查看它们的标签。
查找里面占某类标签最多的那类标签
(书中3.1 3.2节)
:param trainDataMat:训练集数据集
:param trainLabelMat:训练集标签集
:param x:要预测的样本x
:param topK:选择参考最邻近样本的数目(样本数目的选择关系到正确率,详看3.2.3 K值的选择)
:return:预测的标记
'''
# 建立一个存放向量x与每个训练集中样本距离的列表
# 列表的长度为训练集的长度,distList[i]表示x与训练集中第
## i个样本的距离
distList = [0] * len(trainLabelMat)
# 遍历训练集中所有的样本点,计算与x的距离
for i in range(len(trainDataMat)):
# 获取训练集中当前样本的向量
x1 = trainDataMat[i]
# 计算向量x与训练集样本x的距离
curDist = calcDist(x1, x)
# 将距离放入对应的列表位置中
distList[i] = curDist
# 对距离列表进行排序
# argsort:函数将数组的值从小到大排序后,并按照其相对应的索引值输出
# 例如:
# >>> x = np.array([3, 1, 2])
# >>> np.argsort(x)
# array([1, 2, 0])
# 返回的是列表中从小到大的元素索引值,对于我们这种需要查找最小距离的情况来说很合适
# array返回的是整个索引值列表,我们通过[:topK]取列表中前topL个放入list中。
# ----------------优化点-------------------
# 由于我们只取topK小的元素索引值,所以其实不需要对整个列表进行排序,而argsort是对整个
# 列表进行排序的,存在时间上的浪费。字典有现成的方法可以只排序top大或top小,可以自行查阅
# 对代码进行稍稍修改即可
# 这里没有对其进行优化主要原因是KNN的时间耗费大头在计算向量与向量之间的距离上,由于向量高维
# 所以计算时间需要很长,所以如果要提升时间,在这里优化的意义不大。
topKList = np.argsort(np.array(distList))[:topK] # 升序排序
# 建立一个长度时的列表,用于选择数量最多的标记
# 3.2.4提到了分类决策使用的是投票表决,topK个标记每人有一票,在数组中每个标记代表的位置中投入
# 自己对应的地方,随后进行唱票选择最高票的标记
labelList = [0] * 10
# 对topK个索引进行遍历
for index in topKList:
# trainLabelMat[index]:在训练集标签中寻找topK元素索引对应的标记
# int(trainLabelMat[index]):将标记转换为int(实际上已经是int了,但是不int的话,报错)
# labelList[int(trainLabelMat[index])]:找到标记在labelList中对应的位置
# 最后加1,表示投了一票
labelList[int(trainLabelMat[index])] += 1
# max(labelList):找到选票箱中票数最多的票数值
# labelList.index(max(labelList)):再根据最大值在列表中找到该值对应的索引,等同于预测的标记
return labelList.index(max(labelList))
def accuracy(trainDataArr, trainLabelArr, testDataArr, testLabelArr, topK):
'''
测试正确率
:param trainDataArr:训练集数据集
:param trainLabelArr: 训练集标记
:param testDataArr: 测试集数据集
:param testLabelArr: 测试集标记
:param topK: 选择多少个邻近点参考
:return: 正确率
'''
print('start test')
# 将所有列表转换为矩阵形式,方便运算
trainDataMat = np.mat(trainDataArr)
trainLabelMat = np.mat(trainLabelArr).T
testDataMat = np.mat(testDataArr)
testLabelMat = np.mat(testLabelArr).T
# 错误值技术
errorCnt = 0
# 遍历测试集,对每个测试集样本进行测试
# 由于计算向量与向量之间的时间耗费太大,测试集有6000个样本,所以这里人为改成了
# 测试200个样本点,如果要全跑,将行注释取消,再下一行for注释即可,同时下面的print
# 和return也要相应的更换注释行
# for i in range(len(testDataMat)):
for i in range(200):
# print('test %d:%d'%(i, len(trainDataArr)))
print('test %d:%d' % (i, 200))
# 读取测试集当前测试样本的向量
x = testDataMat[i]
# 获取预测的标记
y = getClosest(trainDataMat, trainLabelMat, x, topK)
# 如果预测标记与实际标记不符,错误值计数加1
if y != testLabelMat[i]:
errorCnt += 1
# 返回正确率
# return 1 - (errorCnt / len(testDataMat))
return 1 - (errorCnt / 200)
if __name__ == "__main__":
start = time.time()
# 获取训练集
trainDataArr, trainLabelArr = loadData('../Mnist/mnist_train.csv')
# 获取测试集
testDataArr, testLabelArr = loadData('../Mnist/mnist_test.csv')
# 计算测试集正确率
accur = accuracy(trainDataArr, trainLabelArr, testDataArr, testLabelArr, 25)
# 打印正确率
print('accur is:%d' % (accur * 100), '%')
end = time.time()
# 显示花费时间
print('time span:', end - start)
Python实现机器学习算法:K近邻算法的更多相关文章
- 机器学习之K近邻算法(KNN)
机器学习之K近邻算法(KNN) 标签: python 算法 KNN 机械学习 苛求真理的欲望让我想要了解算法的本质,于是我开始了机械学习的算法之旅 from numpy import * import ...
- 第4章 最基础的分类算法-k近邻算法
思想极度简单 应用数学知识少 效果好(缺点?) 可以解释机器学习算法使用过程中的很多细节问题 更完整的刻画机器学习应用的流程 distances = [] for x_train in X_train ...
- python 机器学习(二)分类算法-k近邻算法
一.什么是K近邻算法? 定义: 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别. 来源: KNN算法最早是由Cover和Hart提 ...
- 【机器学习】k近邻算法(kNN)
一.写在前面 本系列是对之前机器学习笔记的一个总结,这里只针对最基础的经典机器学习算法,对其本身的要点进行笔记总结,具体到算法的详细过程可以参见其他参考资料和书籍,这里顺便推荐一下Machine Le ...
- 机器学习(四) 分类算法--K近邻算法 KNN (上)
一.K近邻算法基础 KNN------- K近邻算法--------K-Nearest Neighbors 思想极度简单 应用数学知识少 (近乎为零) 效果好(缺点?) 可以解释机器学习算法使用过程中 ...
- 第四十六篇 入门机器学习——kNN - k近邻算法(k-Nearest Neighbors)
No.1. k-近邻算法的特点 No.2. 准备工作,导入类库,准备测试数据 No.3. 构建训练集 No.4. 简单查看一下训练数据集大概是什么样子,借助散点图 No.5. kNN算法的目的是,假如 ...
- 机器学习(四) 机器学习(四) 分类算法--K近邻算法 KNN (下)
六.网格搜索与 K 邻近算法中更多的超参数 七.数据归一化 Feature Scaling 解决方案:将所有的数据映射到同一尺度 八.scikit-learn 中的 Scaler preprocess ...
- 分类算法----k近邻算法
K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一.该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的 ...
- 机器学习之K近邻算法
K 近邻 (K-nearest neighbor, KNN) 算法直接作用于带标记的样本,属于有监督的算法.它的核心思想基本上就是 近朱者赤,近墨者黑. 它与其他分类算法最大的不同是,它是一种&quo ...
- 最基础的分类算法-k近邻算法 kNN简介及Jupyter基础实现及Python实现
k-Nearest Neighbors简介 对于该图来说,x轴对应的是肿瘤的大小,y轴对应的是时间,蓝色样本表示恶性肿瘤,红色样本表示良性肿瘤,我们先假设k=3,这个k先不考虑怎么得到,先假设这个k是 ...
随机推荐
- 【2017-2-21】C#分支语句,分支嵌套,变量的作用域
分支语句 句式:if else(必须是if开头,可以是else if或者else结束,也可以直接结束) if(bool型比较表达式) { 如果上面的条件成立,则执行这里面的代码 } else if(b ...
- 【Hive学习之五】Hive 参数&动态分区&分桶
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-3.1.1 apache-hive-3.1.1 ...
- 关于JS的几个基础题目
1.截取字符串abcdefg的efg alert("abcdefg".substring(4)); 2.判断一个字符串中出现次数最多的字符,统计这个次数 var str = 'as ...
- [转载]FileStream读写文件
FileStream读写文件 FileStream类:操作字节的,可以操作任何的文件 StreamReader类和StreamWriter类:操作字符的,只能操作文本文件. 1.FileStream类 ...
- Linux 查看端口使用情况
之前查询端口是否被占用一直搞不明白,问了好多人,终于搞懂了,现在总结下: 1.netstat -anp |grep 端口号 如下,我以3306为例,netstat -anp |grep ...
- php 一个文件搞定支付宝支付,微信支付
博客:https://me.csdn.net/jason19905 支付宝支付:https://github.com/dedemao/alipay 微信支付:https://github.com/de ...
- Golang并发编程有缓冲通道和无缓冲通道(channel)
无缓冲通道 是指在接收前没有能力保存任何值得通道.这种类型的通道要求发送goroutine和接收goroutine同时准备好,才能完成发送和接收操作.如果两个goroutine没有同时准备好,通道会导 ...
- SSL/TLS代理(termination proxy)
A TLS termination proxy (or SSL termination proxy) is a proxy server that is used by an institution ...
- python简说(七)元组,集合
一.元组 元组也是一个list,但是它的值不能改变 定义元组的时候,只有一个元素,后面得加逗号 oracle_info = (123,) 二.集合 1.集合天生就可以去重,集合是无序的 2.#交集 r ...
- Codeforces 917F Substrings in a String - 后缀自动机 - 分块 - bitset - KMP
题目传送门 传送点I 传送点II 传送点III 题目大意 给定一个字母串,要求支持以下操作: 修改一个位置的字母 查询一段区间中,字符串$s$作为子串出现的次数 Solution 1 Bitset 每 ...