机器学习实战python3 K近邻(KNN)算法实现
台大机器技法跟基石都看完了,但是没有编程一直,现在打算结合周志华的《机器学习》,撸一遍机器学习实战, 原书是python2 的,但是本人感觉python3更好用一些,所以打算用python3 写一遍。python3 与python2 不同的地方会在程序中标出。
代码及数据:https://github.com/zle1992/MachineLearningInAction
k-近邻算法
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。对K的取值敏感!!!
适用数据范围:数值型和标称型。
1 创建数据
def createDataSet():
group = np.array([
[1.0,1.1],
[1.0,1.0],
[0,0],
[0,0.1] ])
labels = ['A','A','B','B']
return group ,labels
2 算法
对未知类别属性的数据集中的每个点依次执行以下操作:
(1)计算已知类别数据集中的点与当前点之间的距离;
(2)按照距离递增次序排序;
(3)选取与当前点距离最小的k个点;
(4)确定前k个点所在类别的出现频率;
(5)返回前k个点出现频率最高的类别作为当前点的预测分类。
def classify0(intX,dataX,labels,k):
dataSize = dataX.shape[0] #行数,
diffMat = np.tile(intX,(dataSize,1)) - dataX #intX 复制4行,形成矩阵,并计算距离差
sqDiffMat = diffMat * diffMat # 等价于 diffMat ** 2
sqDistence = sqDiffMat.sum(axis = 1) #按行相加
distence = sqDistence ** 0.5 # 开根号 , distence是array
sortedDistenceIndicies = distence.argsort() # 返回排序后的下标
classCount = {} # 字典 key is label , val is count
for i in range(k):
voteIlabel = labels[sortedDistenceIndicies[i]] # 排名第i的label
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 # .get(voteIlabel,0) if no exit return 0
sortedClassCount = sorted(classCount.items(),key = operator.itemgetter(1),reverse = True)
# 根据iteritems 的第1个元素排序 即字典中的val ,第0个 是key #reverse定义为True时将按降序排列
#!!!!! 与py2 的差别!! python3 字典的item 就是迭代对象
return sortedClassCount[0][0] # 返回排序后的字典的前一个(从0开始)
3在约会网站上使用k近邻算法
(1)收集数据:提供文本文件。
(2)准备数据:使用Python解析文本文件。
(3)分析数据:使用Matplotlib画二维扩散图。
(4)训练算法:此步骤不适用于k-近邻算法。
(5)测试算法:使用海伦提供的部分数据作为测试样本。测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。
(6)使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。
约会数据存放在文本文件datingTestSet.txt中,每个样本数据占据一行,总共有1000行。主要包含以下3种特征:
口每年获得的飞行常客里程数
口玩视频游戏所耗时间百分比
口每周消费的冰淇淋公升数
3-1将文本记录到转换NumPy的解析程序
def file2matrix(filename):
with open(filename,mode = "r") as fr:
arrayOLines = fr.readlines()
numberOfLine = len(arrayOLines)
returnMat = np.zeros((numberOfLine,3))
labels = []
index = 0
for line in arrayOLines:
listFromLine = line.split("\t")
returnMat[index,:] = listFromLine[0:3]
labels.append(int(listFromLine[-1])) #-1 倒数第一个
index = index + 1
return returnMat,labels
3-2分析数据:使用Matplotlib创建散点图
k = 3
#读入数据
filename = "datingTestSet2.txt"
dataX,labels = file2matrix(filename)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(dataX[:,0],dataX[:,1],c = 15 *np.array(labels),s = 15*np.array(labels)) # c 是颜色序列!!!! s 是大小
ax = fig.add_subplot(121)
ax.scatter(dataX[:,0],dataX[:,2],c = 15 *np.array(labels),s = 15*np.array(labels)) # c 是颜色序列!!!! s 是大小
ax = fig.add_subplot(131)
ax.scatter(dataX[:,1],dataX[:,2],c = 15 *np.array(labels),s = 15*np.array(labels)) # c 是颜色序列!!!! s 是大小
3-3准备数据:归一化数值
def autoNorm(dataX):
# 归一化公式 newVal = (oldval-min)/(max - min)
minVals = dataX.min(axis=0)#返回的是最每一列中的最小的元素 min(1)#返回的是最每一行中的最小的元素
maxVals = dataX.max(0)#返回的是最每一列中的最大的元素
ranges = maxVals - minVals #
rows = dataX.shape[0]
newVal = dataX - tile(minVals,(rows,1)) #(oldval-min)
## tile(minVals,(rows,1))复制rows行 ,列数为minvals列数的一倍
newVal = newVal/tile(ranges,(rows,1)) #(oldval-min)/(max - min)
return newVal,ranges,minVals
3-4测试算法:作为完整程序验证分类器
def datingClassTest():
hoRatio = 0.1 # 10% of data as test
#读入数据
filename = "datingTestSet2.txt"
dataX ,labels = file2matrix(filename)
#归一化
normMat,ranges,minVals = autoNorm(dataX) m = dataX.shape[0] #numbers of rows
numTestVecs = int(m * hoRatio) #numbers of test
errorcount = 0 #initialize number of errors
for i in range(numTestVecs):
classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],labels[numTestVecs:m],5)#前10%作为测试数据
# print("the classifier predict %d, the real answer is :%d" %((classifierResult),labels[i]))
if(classifierResult != labels[i]):
errorcount = errorcount + 1.0
print("error rate :%f" %((errorcount)/(numTestVecs)))
3-5使用算法:构建完整可用系统
此程序需要在命令行下进行,因为要从命名行读入数据
def classifyPerson():
resultList = ["第一类","第二类","第三类"] #output lables percentTats = float(input("玩游戏消耗的时间"))###########!!!!!!! pyhton3 为input#####!!!!!!!!!!!!!!!!!
ffilm = float(input("每年获得的飞行里程数"))###########!!!!!!! pyhton2 为raw_input#####!!!!!!!!!!!!!!!!!
iceCream = float(input("每周消费冰淇淋"))
#读入数据
filename = "datingTestSet2.txt"
dataX ,labels = file2matrix(filename)
#归一化
normMat,ranges,minVals = autoNorm(dataX) test_list = np.array([percentTats,ffilm,iceCream])
classifierResult = classify0(test_list,dataX,labels,3)
print("你喜欢的类别:" + resultList[classifierResult])
4手写识别系统
(1)收集数据:提供文本文件。
(2)准备数据:编写函数classify0(),将图像格式转换为分类器使用的list格式。
(3)分析数据:在Python命令提示符中检查数据,确保它符合要求。
(4)训练算法:此步骤不适用于裕近邻算法。
(5)测试算法:编写函数使用提供的部分数据集作为测试样本,测试样本与非测试样本的区别在于测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。
(6)使用算法:本例没有完成此步骤,若你感兴趣可以构建完整的应用程序,从图像中提取数字,并完成数字识别,美国的邮件分拣系统就是一个实际运行的类似系统。
4-1准备数据:将图像转换为测试向量
def img2vector(filename):
returnVect = np.zeros((1,1024)) #initilize the vec
with open (filename,mode = "r") as fr: #########!!!!!!!!与python2 不同 !!!!!!!!
lineStr = fr.readlines() #########!!!!!!!!与python2 不同 !!!!!!!!
for i in range(32): #########!!!!!!!!与python2 不同 !!!!!!!!
for j in range(32): #########!!!!!!!!与python2 不同 !!!!!!!!
returnVect[0,i*32+j] = lineStr[i][j] #########!!!!!!!!与python2 不同 !!!!!!!!
return returnVect
4-2测试算法:使用k-近邻算法识别手写数字
def handwritingClassTest():
hwlables = []
trainingFileList = os.listdir("digits\\trainingDigits")######!!!!!!!!与python2 不同 !py3 need import os
m = len(trainingFileList) # number of trianfiles
trainMat = np.zeros((m,1024))
for i in range(m):
fileNameStr = trainingFileList[i] #循环操作 把每一个txt文件转换为矩阵
fileStr = fileNameStr.split(".")[0] # 把文件名与后缀名分开,提取文件名
classNumStr = fileStr.split("_")[0] #提取文件名中的标签
hwlables.append(classNumStr) #把类别标签添加到类别List
trainMat[i,:] = img2vector("digits\\trainingDigits\\%s" %fileNameStr) testFileList = os.listdir("digits\\testDigits") #处理测试文件
mtest = len(testFileList)
errorcount = 0.0
for i in range(mtest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split(".")[0]
classNumStr = fileStr.split("_")[0]
vectorUderTest = img2vector("digits\\testDigits\\%s" %fileNameStr)
classifierResult = classify0(vectorUderTest,trainMat,hwlables,3)
if(classifierResult != classNumStr) :
errorcount += 1.0
print("errorcount:%d" %errorcount)
print("error rate :%f" %float((errorcount/mtest)))
final 主程序
需要运行哪个程序就打开哪个程序的注释即可
if __name__ == '__main__':
#simpletest() # 测试createDataSet 和classify0 这2个函数
plot() #画datingTestSet2.txt这个数据的图像
#handwritingClassTest() #手写识别程序
#datingClassTest() #约会 识别程序
#classifyPerson() #从命令行读入数据
def simpletest(): # 测试createDataSet 和classify0 这2个函数
intX = [0.0,0.0]
k = 3
dataX,labels = createDataSet()
a = classify0(intX,dataX,labels,k)
print("dataX:" ,dataX)
print("labels:",labels)
print("predict:" ,a)
机器学习实战python3 K近邻(KNN)算法实现的更多相关文章
- 机器学习经典算法具体解释及Python实现--K近邻(KNN)算法
(一)KNN依旧是一种监督学习算法 KNN(K Nearest Neighbors,K近邻 )算法是机器学习全部算法中理论最简单.最好理解的.KNN是一种基于实例的学习,通过计算新数据与训练数据特征值 ...
- 02机器学习实战之K近邻算法
第2章 k-近邻算法 KNN 概述 k-近邻(kNN, k-NearestNeighbor)算法是一种基本分类与回归方法,我们这里只讨论分类问题中的 k-近邻算法. 一句话总结:近朱者赤近墨者黑! k ...
- 机器学习-K近邻(KNN)算法详解
一.KNN算法描述 KNN(K Near Neighbor):找到k个最近的邻居,即每个样本都可以用它最接近的这k个邻居中所占数量最多的类别来代表.KNN算法属于有监督学习方式的分类算法,所谓K近 ...
- 机器学习实战笔记--k近邻算法
#encoding:utf-8 from numpy import * import operator import matplotlib import matplotlib.pyplot as pl ...
- 机器学习实战(笔记)------------KNN算法
1.KNN算法 KNN算法即K-临近算法,采用测量不同特征值之间的距离的方法进行分类. 以二维情况举例: 假设一条样本含有两个特征.将这两种特征进行数值化,我们就可以假设这两种特种分别 ...
- 《机器学习实战》-k近邻算法
目录 K-近邻算法 k-近邻算法概述 解析和导入数据 使用 Python 导入数据 实施 kNN 分类算法 测试分类器 使用 k-近邻算法改进约会网站的配对效果 收集数据 准备数据:使用 Python ...
- 《机器学习实战》——K近邻算法
三要素:距离度量.k值选择.分类决策 原理: (1) 输入点A,输入已知分类的数据集data (2) 求A与数据集中每个点的距离,归一化,并排序,选择距离最近的前K个点 (3) K个点进行投票,票数最 ...
- 《机器学习实战》基于朴素贝叶斯分类算法构建文本分类器的Python实现
============================================================================================ <机器学 ...
- 机器学习实战 - python3 学习笔记(一) - k近邻算法
一. 使用k近邻算法改进约会网站的配对效果 k-近邻算法的一般流程: 收集数据:可以使用爬虫进行数据的收集,也可以使用第三方提供的免费或收费的数据.一般来讲,数据放在txt文本文件中,按照一定的格式进 ...
随机推荐
- MVC--布局--razor
ASP.NET MVC Razor视图引擎攻略 转自:http://www.cnblogs.com/John-Connor/archive/2012/05/08/2487200.html --引子 看 ...
- excel中,一系列单元格中包含某一个字段的单元格数量?
excel中,一系列单元格中包含某一个字段的单元格数量?这个怎么写公式?如:A列单元格A1-A7的内容分别为 A.AB.BC.AC.CD.AD.EA,怎么数这一列中几个单元格的内容包含A字母? 任意单 ...
- Android中Bitmap和Drawable详解
一.相关概念 1.Drawable就是一个可画的对象,其可能是一张位图(BitmapDrawable),也可能是一个图形(ShapeDrawable),还有可能是一个图层(LayerDrawable) ...
- stm32入门(从51过渡到32)
单片机对于我来说,就是一个超级大机器,上面有一排一排数不尽的开关,我需要做的,就是根据我的设计,拿着一张超级大的表(Datasheet),把需要的开关(reg)都开关(config)到对应功能的位置( ...
- EditPlus详解
如何让EditPlus支持LUA教程是本文要介绍的内容,这次主要介绍一下学习Lua之前的准备工作.关于在EditPlus中实现lua的安装,具体内容来看本文详解. (1) 下载Lua安装包,最新版本是 ...
- line-height和vertical-algin
项目中,经常会用到line-height和vertical-algin来解决垂直居中的问题,但对其原理和应用限制却很少了解.因此做了一下总结: line-height具有继承性,对inline元素.t ...
- Android Log.isLoggable方法异常:exceeds limit of 23 characters
AndroidRuntime: java.lang.IllegalArgumentException: Log tag "AccountSetupIncomingFragment" ...
- sencha touch 入门系列 (五)sencha touch运行及代码解析(上)
由于最近项目比较忙,加之还要转战原生开发,所以很久没更新了,今天我们接着上一次的内容往下讲: 首先我们打开index.html,这是我们整个程序的访问入口,也是整个项目的引入地: <!DOCTY ...
- 心脏滴血HeartBleed漏洞研究及其POC
一.漏洞原理: 首先声明,我虽然能看懂C和C++的每一行代码,但是他们连在一起我就不知道什么鬼东西了.所以关于代码说理的部分只能参考其他大牛的博客了. /* 据说源码中有下面两条语句,反正我也没看过源 ...
- Egret Wing4.1.0 断点调试
一 双击代码行号左侧打断点 二 选择调试视图工具栏. 三 点击开始调试 1 wing内置播放器调试 选择此项进行调试会打开Egret内置播放器,我这里这个版本该选项无法进行断点... 2 使用本机 ...