一份算法学习笔记~
亲爱的朋友,恭喜你点开神秘之门,哈哈哈哈!从这里开始,我们一起学习机器学习的经典算法吧。
这一次的主要内容是机器学习入门算法:k-近邻。理论相当好理解,下面我们正式开始啦!

算法简介

k-近邻算法是1968年,由Cover和Hart提出,主要用来对数据进行分类。其核心思想易于理解,已知数据集中所有样本的特征和标签,当输入新的样本a时,通过计算样本a与数据集中其他样本在特征空间的距离,选取最近的k个样本,由这k个样本投票决定样本a的标签,即这k个样本中,占比最高的类别,就作为样本a的标签。

主要步骤:
1、 依次计算已知样本点到待分类点的距离。
2、 对计算出的距离进行递增排序
3、 选取与待分类点最近的k个点。
4、 统计k个点对应的类别出现频率,返回出现频率最高的类别作为待分类点的类别。

常见的距离度量:LP距离、欧式距离、曼哈顿距离等。对概念不清楚的伙伴可以查阅百度百科,在此就不一一介绍了。

算法优点
1、简单好用、理论成熟。
2、精度高
3、对异常值不敏感

算法缺点:
1、计算量大,相应的对内存的需求也较大
2、样本不平衡问题,当数据集中某一类样本数量过多,对结果准确性有较大影响。
3、无法给出数据的内在含义
计算量大,相应的时间消耗就会增加,这一点在手写识别系统中可以感受到。

k值选取
k值是k-近邻算法的关键参数,k值取多少需要参考数据而定。当k值越大时,相应的模型的偏差会越大,对异常值就越不敏感。K值很大时,容易造成模型欠拟合。相反,当k值越小时,模型的方差就会越大,k值很小时,容易造成模型过拟合。

程序实现

假设数据集中样本有两个特征x和y,特征空间为二维,对应两种类别,A和B
数据集:四个样本 (1.0,0) (8.3,8) (1.2,3) (9.2,7)
类别:对应四个标签为 A,B,A,B
待分类样本:(10,9)

from numpy import *
import os
import operator
import numpy########构建数据集######################
'''
假设数据集中样本有两个特征x和y,特征空间为二维.对应两种类别,A和B
'''
def createDataSet():dataSet=array([[1.0,0],[8.3,8],[1.2,3],[9.2,7]])label=['A','B','A','B']return dataSet,label
dataSet,label=createDataSet()
#######knn算法#########################
'''
距离度量:欧氏距离
X_example:待分类点
dataSet:数据集
label:dataSet中样本的标签
k:算法参数
'''
def knn(X_example,dataSet,label,k):dataSize=len(dataSet)   ##计算数据集长度minus=tile(X_example,(dataSize,1))-dataSet  #重复X_example,行方向datasize次,列方向一次,得出的数组与数据集大小一致,再与数据集相减minus2=minus**2   #相减结果平方D_distance=(minus2.sum(axis=1))**0.5 #结果按行求和。index=D_distance.argsort()  #排序,返回的是D_distance中元素从小到大对应的索引值,数组[]classCount={}  #创建一个字典统计选择的k个点对应的标签出现次数for i in range(k):votelabel=label[index[i]]  #获取前k个近点的标签classCount[votelabel]=classCount.get(votelabel,0)+1 #首次出现则赋值0,加1sortedResult=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)  ##返回一个list, k行两列的   [('B', 2), ('A', 1)]return sortedResult[0][0]print('样本类别为:%s' %(knn([10,9],dataSet,label,2)))  #输入带分类点[10,9],,此处k值取2,执行knn算法

程序输出:

样本类别为:B

以上就是算法的基本实现,清晰简单。

经典应用:改进约会网站配对效果

问题描述
海伦一直师兄在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人,但是并不是每一个她都喜欢。经过一番总结,她发现自己曾交往过三种类型的人:1、不喜欢的人 ; 2、魅力一般的人;3、极具魅力的人。
尽管发现了上述规律,但海伦依然无法将约会网站推荐的匹配对象归入恰当的类别。海伦希望分类软件可以更好地帮助她将匹配对象划分到确切的分类中,此外海伦收集了一些约会网站未记录的数据信息,她认为这些数据有助于匹配对象的归类。

文本数据集:
数据集内有一千个样本,每个样本各占一行,样本中主要包括三种特征:
1、每年获得的飞行常客里程数 (第一列数据)
2、玩视频游戏所消耗的时间百分比 (第二列数据)
3、每周消费的冰淇淋公升数 (第三列数据)
最后一列为样本标签,对应三种类型的人。

数据预处理:从文件中解析数据,并绘制散点图、进行归一化

import matplotlib.pyplot as plt###############从文本文件中解析数据#########
'''
filename:存储数据集的文件
returnMat:从文件中解析出的数据特征
label:从文件中解析出的样本标签
'''
def file2matrix(filename):fr=open(filename) #打开文件AllLine=fr.readlines()  #读取所有行NumLine=len(AllLine)  #统计行数label=[]            #标签列表returnMat=zeros((NumLine,3))   #创建数组存储文件中数据index=0    for line in AllLine:line=line.strip()  #去除每一行后面的回车listfromLine=line.split('\t')  #取出的一行内容使用split函数分开,对应四个元素,存在列表listfromLine中returnMat[index,:]=listfromLine[0:3]  ##按行复制前三个元素,listfromLine[0]至listfromLine[2]index+=1   ##行标+1label.append(int(listfromLine[-1]))  #列表listfromLine最后一个元素对应样本标签return returnMat,label   ##########散点图展示样本分布##############
'''
取前两个特征
x轴:每年飞行里程数
y轴:玩视频游戏所耗时间百分比
'''
DatasetMat,datingLabels=file2matrix('datingTestSet2.txt')
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(DatasetMat[:,0],DatasetMat[:,1],10.0*array(datingLabels),90.0*array(datingLabels))
plt.xlabel(u'flying ')
plt.ylabel(u'playing game')
plt.title(u"KNN")
plt.legend(loc="upper left")
plt.show()###############归一化#####################
'''
datasetMat:数据特征
normMat:datasetMat归一化后的值
归一化:
newValue=(oldValue-min)/max-min
'''
def autoNorm(datasetMat): maxnum=datasetMat.max(0) #每一列最大值minNum=datasetMat.min(0) #每一列最小值range=maxnum-minNum   #每一个特征对应范围normMat=zeros(shape(datasetMat))minmat=tile(minNum,(normMat.shape[0],1))rangemat=tile(range,(normMat.shape[0],1))normMat=(datasetMat-minmat)/rangematreturn normMat,range,minNum

散点图绘制结果,x轴为每年飞行里程数,y轴为玩视频游戏所耗时间百分比,如图,展现的是三种类型的点在这两种特征下的分布情况。

算法测试

############算法测试#########################
'''
将normDataSet中的数据按比例划分为测试数据集和训练数据集
testData_num:测试数据集数量
normDataSet[i,:]:测试数据集样本
normDataSet[testData_num:m,:]:训练数据集样本
errorCount:分类错误数量统计
'''
def datingclasstest():dataset,label=file2matrix('datingTestSet2.txt')normDataSet,ranges,min=autoNorm(dataset)testData_num=int(normDataSet.shape[0]*0.1)m=normDataSet.shape[0]   errorCount=0  for i in range(testData_num):classResult=knn(normDataSet[i,:],normDataSet[testData_num:m,:],label[testData_num:m],3)if classResult!=label[i]:errorCount+=1print(errorCount/float(testData_num))
datingclasstest()

错误率输出结果:

0.05

构建完整应用,进行预测

###############构建完整可用系统#########################
'''
game、mile、icecream:待分类样本对应的特征
result:算法执行结果对应的文字标签
'''
def datingClassPerson():listlabel=['不喜欢的人','魅力一般的人','极具魅力的人']game=float(input('玩视频游戏所耗时间百分比:'))mile=float(input('每年飞行里程数:'))icecream=float(input("每周消费的冰淇淋公升数:"))inx=array([mile,game,icecream])dataset,datalabel=file2matrix('datingTestSet2.txt')  #读取文件,解析数据normMat,range,min=autoNorm(dataset)             #归一化classResult=knn(((inx-min)/range),normMat,datalabel,3)  #调用算法result=listlabel[classResult-1]print("分类结果为:%s" %(result))
datingClassPerson()

输入

玩视频游戏所耗时间百分比:90
每年飞行里程数:400
每周消费的冰淇淋公升数:3

输出

分类结果为:不喜欢的人

经典应用:手写识别系统

需要识别的数字已经过图形软件处理,长宽均为32x32像素的黑白图像。图示为三个数字0,6,9,均为32x32像素大小。

将图像转换为文本格式,以下每一个文本文件对应一个图像(篇幅限制,下图中仅截取部分文件)

程序

###############图片转向量##################################
'''
returnMat:返回分类器可接受的向量格式,存储图片中的01
'''
def img2Vector(filename):returnMat=zeros((1,1024))  #构建1*1024数组,存储一个数字对应的0 1内容fr=open(filename)for i in range(32):line=fr.readline()for j in range(32):returnMat[0,i*32+j]=int(line[j])return returnMat
#############构建手写识别系统############################
def handwrite():##处理训练集tr_labels=[]tr_data=os.listdir('trainingDigits')tr_Mat=zeros((len(tr_data),1024))for i in range(len(tr_data)):file_name=tr_data[i]file_str=file_name.split('.')[0]digits=int(file_str.split('_')[0]) #从文件名称中解析得到数字的标签tr_labels.append(digits)    #训练集的标签tr_Mat[i,:]=img2Vector('trainingDigits/%s' %(file_name))  #将训练集的文件依次转换为向量,存储到数组中##处理测试集errorcount=0test_data=os.listdir('testDigits')for i in range(len(test_data)):test_file_name=test_data[i]tfile_str=test_file_name.split('.')[0]test_digits=int(tfile_str.split('_')[0])test_vector=img2Vector('testDigits/%s' %(test_file_name))result=knn(test_vector,tr_Mat,tr_labels,3)  #print('the answer is %d ,the really is %d' %(result,test_digits))if result!=test_digits:errorcount+=1print('Total number of test cases is %d, the number of wrong classification cases is %d'  %(len(test_data),errorcount) )print('Classification error rate is :%f' %(errorcount/float(len(test_data))))handwrite()

输出:

Total number of test cases is 946, the number of wrong classification cases is 10
Classification error rate is :0.010571

以上就是k-近邻算法的主要内容,眼过千遍不如手过一遍,建议小伙伴们有时间的话动手实践一下。

独学无朋,则孤陋而难成,如果有不理解的地方,欢迎与我交流,我们可以共同学习!以上若有纰漏,欢迎道友指正,感激不尽

本文参考学习资料:《机器学习实战》(peter Harrington 著)

机器学习算法(一):k-近邻理论与python实现+经典应用(约会网站匹配、手写识别系统)相关推荐

  1. k邻近算法python代码_机器学习算法之K近邻法-Python实现

    一.算法简介 k近邻法(k-nearest neighbor,k-NN)是一种基本的分类方法,输入的是实例的特征向量,对应于特征空间的点,输出结果为实例的类别,可以取多类.对于训练集来说,每个实例的类 ...

  2. 机器学习算法之 K 近邻

    机器学习算法之 K 近邻 所谓"K 近邻(K-nearest neighbor,K-NN)",顾名思义,指的是"K 个最近的邻居",属于一种监督学习的方法. 1 ...

  3. 【机器学习实战】k近邻算法实战——手写识别系统

    文章目录 手写识别系统 步骤: 准备数据:将图像转换为测试向量 测试算法:使用k-近邻算法识别手写数字 [完整代码] 手写识别系统 为了简单起见,这里构造的系统只能识别数字0到9,参见图2-6.需要识 ...

  4. 【Python】基于kNN算法的手写识别系统的实现与分类器测试

    基于kNN算法的手写识别系统 1.      数据准备 使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件. 方法如下,使用画图工具,打开网格线,调整像素为32 ...

  5. Knn算法之手写识别系统

    knn值之手写识别系统 导入包 import numpy as np from os import listdir import operator 介绍 1.os模块 os.listdir() 方法用 ...

  6. 机器学习实战-手写识别系统

    在实现了K近邻算法后,书中给出了一个实例,今天来学习一下使用K近邻分类器的手写识别系统.书中原带的文件已经过处理转换为了文本格式,方便了许多. 先看一下原带文件 准备数据 #将图像转换为测试向量 de ...

  7. 【机器学习】手写识别系统

    [机器学习]手写识别系统 过程 ==准备数据:将图像转换为测试向量== ==测试算法:使用k-近邻算法识别手写数字== ==完整代码== 过程 收集数据:提供文本文件 准备数据:编写函数classif ...

  8. python实现手写识别系统

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.手写识别系统 二.主要步骤 1.准备数据:将图像转换为测试向量 2.测试算法:使用k-近邻算法识别手写数字 总结 ...

  9. knn算法测试手写识别系统准确率

    手写识别系统,KNN算法实现手写识别系统的准确率 (准确率=测试分对的样本数/总的样本数) import numpy as np from itertools import chain from os ...

最新文章

  1. 备份集过期时间_TiDB备份恢复方式你知多少?
  2. Python连接SQL Server数据库 - pymssql使用基础
  3. php7插件开发,php7.2.6 插件fileinfo的安装
  4. 前端异步对象的原理与使用方法
  5. FIREDAC连接SQLITE乱码的解决
  6. 【Lucene】Apache Lucene全文检索引擎架构之中文分词和高亮显示4
  7. JavaScript 插件的书页翻转效果
  8. java的的socket编程_javasocket编程
  9. origin2021绘图软件安装教程
  10. Pytorch构建Transformer实现英文翻译
  11. ubuntu16.04 安装Anbox
  12. 基于Java毕业设计爱心公益网站设计与制作源码+系统+mysql+lw文档+部署软件
  13. Jenkins拉取代码返回错误码128
  14. 面试官:什么是 Reactor 和 Proactor?
  15. Lucene关键字高亮显示
  16. 微信支付链接二维码生成
  17. 安卓禁止用户安装程序
  18. 利用SAH实现kD树快速分割模型实践
  19. 钉钉爆火背后,真正的在线教育机构过得怎么样?已有 1 家倒闭
  20. 详解 Logit/Probit 模型中的 completely determined 问题

热门文章

  1. 关于LINDO/LINGO的学习材料
  2. 杰理AC692X---添加串口打印调试
  3. PXIEBPMCx4载板转接卡
  4. 使用Adobe Acrobat设置pdf的页码
  5. 京东商城的融资诱惑与亏损陷阱
  6. vue引入luckysheet插入图表时报错Uncaught TypeError: h.createChart is not a function
  7. 2021年安全生产模拟考试(全国特种作业操作证电工作业-电气试验模拟考试题库一)安考星
  8. 树莓派局域网测速方法
  9. 科大讯飞:电信客户流失预测挑战赛baseline
  10. linux u盘 命令,制作U盘版linux系统安装盘(DD命令)