目录

一、改进约会网站

1、项目背景

2、数据收集

3、在约会网站中使用k-近邻算法的流程

4、代码实现

二、手写体数字识别

1.了解手写体数字识别

2、手写体数字识别思路

3.1、导入模块

3.2、引入训练样本文件和测试样本文件,定义一个读取数据的转换数据的函数

3.3、定义一个字段转列表的函数

3.4、定义相似度函数

3.5、编写识别函数

3.6、调用

3.7、运行结果


一、改进约会网站

1、项目背景

我的朋友海伦一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但她并不是喜欢每一个人。经过一番总结,她发现自己交往过的人可以进行如下分类:

  • 不喜欢的人
  • 魅力一般的人
  • 极具魅力的人

海伦认为,尽管发现了这些规律,仍无法将约会网站推荐的匹配对象归入恰当的分类,她希望借助我们的分类软件更好的帮助她将匹配的对象划分到确切的分类中。

2、数据收集

海伦收集约会数据已经有了一段时间,她把这些数据存放在文本文件datingTestSet.txt中,每个样本数据占据一行,总共有1000行。

海伦收集的样本数据主要包含以下3种特征:

每年获得的飞行常客里程数
玩视频游戏所消耗时间百分比
每周消费的冰淇淋公升数

3、在约会网站中使用k-近邻算法的流程

(1)收集数据:提供文本文件,即datingTestSet.txt。

(2)准备数据:使用Python解析文本文件。

(3)分析数据:使用Matplotlib画二维扩散图。

(4)测试算法:使用文本文件的部分数据作为测试样本,计算错误率。

(5)使用算法:错误率在可接受范围内,就可以运行k-近邻算法进行分类。

4、代码实现

#-*- coding:utf-8 -*-import matplotlib.lines as mlines
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
import operator'''
#准备数据,从文本文件中解析数据
'''
def file2matrix(filename):#打开文件with open(filename,'r') as fr:# 读取文件所有内容arrayOLines = fr.readlines()# 得到文件行数numberOfLines = len(arrayOLines)# 返回的NumPy矩阵,解析完成的数据:numberOfLines行,3列returnMat = np.zeros((numberOfLines, 3))# 返回的分类标签向量classLabelVector = []# 行的索引值index = 0for line in arrayOLines:# s.strip(rm),当rm空时,默认删除空白符(包括'\n','\r','\t',' ')line = line.strip()# 使用s.split(str="",num=string,cout(str))将字符串根据'\t'分隔符进行切片。listFromLine = line.split('\t')# 将数据前三列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵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 += 1return returnMat, classLabelVector'''
#分析数据,数据可视化,使用Matplotlib创建散点图
'''
def showdatas(datingDataMat, datingLabels):#设置汉字格式# sans-serif就是无衬线字体,是一种通用字体族。# 常见的无衬线字体有 Trebuchet MS, Tahoma, Verdana, Arial, Helvetica, 中文的幼圆、隶书等等mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体 SimHei为黑体mpl.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号#将fig画布分隔成2行2列,不共享x轴和y轴,fig画布的大小为(13,8)#当nrow=2,nclos=2时,代表fig画布被分为四个区域,axs[0][0]表示第一行第一个区域fig, axs = plt.subplots(nrows=2, ncols=2,sharex=False, sharey=False, figsize=(13,9))LabelsColors = []for i in datingLabels:if i == 1:LabelsColors.append('green')if i == 2:LabelsColors.append('red')if i == 3:LabelsColors.append('blue')#画出散点图,以datingDataMat矩阵的第一(飞行常客例程)、第二列(玩游戏)数据画散点数据,散点大小为15,透明度为0.5axs[0][0].scatter(x=datingDataMat[:,0], y=datingDataMat[:,1], color=LabelsColors,s=15, alpha=.5)#设置标题,x轴label,y轴labelaxs0_title_text = axs[0][0].set_title('每年获得的飞行常客里程数与玩视频游戏所消耗时间占比')axs0_xlabel_text = axs[0][0].set_xlabel('每年获得的飞行常客里程数')axs0_ylabel_text = axs[0][0].set_ylabel('玩视频游戏所消耗时间占')plt.setp(axs0_title_text, size=12, weight='bold', color='red')plt.setp(axs0_xlabel_text, size=10, weight='bold', color='black')plt.setp(axs0_ylabel_text, size=10, weight='bold', color='black')#画出散点图,以datingDataMat矩阵的第一(飞行常客例程)、第三列(冰激凌)数据画散点数据,散点大小为15,透明度为0.5axs[0][1].scatter(x=datingDataMat[:,0], y=datingDataMat[:,2], color=LabelsColors,s=15, alpha=.5)#设置标题,x轴label,y轴labelaxs1_title_text = axs[0][1].set_title('每年获得的飞行常客里程数与每周消费的冰激淋公升数',)axs1_xlabel_text = axs[0][1].set_xlabel('每年获得的飞行常客里程数')axs1_ylabel_text = axs[0][1].set_ylabel('每周消费的冰激淋公升数')plt.setp(axs1_title_text, size=12, weight='bold', color='red')plt.setp(axs1_xlabel_text, size=10, weight='bold', color='black')plt.setp(axs1_ylabel_text, size=10, weight='bold', color='black')#画出散点图,以datingDataMat矩阵的第二(玩游戏)、第三列(冰激凌)数据画散点数据,散点大小为15,透明度为0.5axs[1][0].scatter(x=datingDataMat[:,1], y=datingDataMat[:,2], color=LabelsColors,s=15, alpha=.5)#设置标题,x轴label,y轴labelaxs2_title_text = axs[1][0].set_title('玩视频游戏所消耗时间占比与每周消费的冰激淋公升数')axs2_xlabel_text = axs[1][0].set_xlabel('玩视频游戏所消耗时间占比')axs2_ylabel_text = axs[1][0].set_ylabel('每周消费的冰激淋公升数')plt.setp(axs2_title_text, size=12, weight='bold', color='red')plt.setp(axs2_xlabel_text, size=10, weight='bold', color='black')plt.setp(axs2_ylabel_text, size=10, weight='bold', color='black')#设置图例didntLike = mlines.Line2D([], [], color='green', marker='.', markersize=6, label='不喜欢')smallDoses = mlines.Line2D([], [], color='red', marker='.',markersize=6, label='魅力一般')largeDoses = mlines.Line2D([], [], color='blue', marker='.',markersize=6, label='极具魅力')#添加图例axs[0][0].legend(handles=[didntLike,smallDoses,largeDoses])axs[0][1].legend(handles=[didntLike,smallDoses,largeDoses])axs[1][0].legend(handles=[didntLike,smallDoses,largeDoses])#显示图片plt.show()'''
#准备数据,数据归一化处理
'''
def autoNorm(dataSet):#获得每列数据的最小值和最大值minVals = dataSet.min(0)maxVals = dataSet.max(0)#最大值和最小值的范围ranges = maxVals - minVals#shape(dataSet)返回dataSet的矩阵行列数#normDataSet = np.zeros(np.shape(dataSet))#返回dataSet的行数m = dataSet.shape[0]#原始值减去最小值normDataSet = dataSet - np.tile(minVals, (m, 1))#除以最大和最小值的差,得到归一化数据normDataSet = normDataSet / np.tile(ranges, (m, 1))#返回归一化数据结果,数据范围,最小值return normDataSet, ranges, minVals'''
KNN算法分类器
#  inX - 用于分类的数据(测试集)
#  dataSet - 用于训练的数据(训练集)
#  labes - 训练数据的分类标签
#  k - kNN算法参数,选择距离最小的k个点
#  sortedClassCount[0][0] - 分类结果
'''
def classify0(inX, dataSet, labels, k):#numpy函数shape[0]返回dataSet的行数dataSetSize = dataSet.shape[0]#在列向量方向上重复inX共1次(横向),行向量方向上重复inX共dataSetSize次(纵向)diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet#二维特征相减后平方sqDiffMat = diffMat**2#sum()所有元素相加,sum(0)列相加,sum(1)行相加sqDistances = sqDiffMat.sum(axis=1)#开方,计算出距离distances = sqDistances**0.5#返回distances中元素从小到大排序后的索引值sortedDistIndices = distances.argsort()#定一个记录类别次数的字典classCount = {}for i in range(k):#取出前k个元素的类别voteIlabel = labels[sortedDistIndices[i]]#dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。#计算类别次数classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#python3中用items()替换python2中的iteritems()#key=operator.itemgetter(1)根据字典的值进行排序#key=operator.itemgetter(0)根据字典的键进行排序#reverse降序排序字典sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)#返回次数最多的类别,即所要分类的类别return sortedClassCount[0][0]'''
#测试算法,计算分类器的准确率,验证分类器
'''
def datingClassTest():#打开的文件名filename = "datingTestSet.txt"#将返回的特征矩阵和分类向量分别存储到datingDataMat和datingLabels中datingDataMat, datingLabels = file2matrix(filename)#取所有数据的百分之十hoRatio = 0.10#数据归一化,返回归一化后的矩阵,数据范围,数据最小值normMat, ranges, minVals = autoNorm(datingDataMat)#获得normMat的行数m = normMat.shape[0]#百分之十的测试数据的个数numTestVecs = int(m * hoRatio)#分类错误计数errorCount = 0.0for i in range(numTestVecs):#前numTestVecs个数据作为测试集,后m-numTestVecs个数据作为训练集classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m,:],datingLabels[numTestVecs:m], 4)print("分类结果:%d\t真实类别:%d" % (classifierResult, datingLabels[i]))if classifierResult != datingLabels[i]:errorCount += 1.0print("错误率:%f%%" %(errorCount/float(numTestVecs)*100))'''
#使用算法,构建完整可用系统
'''
def classifyPerson():#输出结果resultList = ['不喜欢','有些喜欢','非常喜欢']#三维特征用户输入ffMiles = float(input("每年获得的飞行常客里程数:"))precentTats = float(input("玩视频游戏所耗时间百分比:"))iceCream = float(input("每周消费的冰激淋公升数:"))#打开的文件名filename = "datingTestSet.txt"#打开并处理数 据datingDataMat, datingLabels = file2matrix(filename)#训练集归一化normMat, ranges, minVals = autoNorm(datingDataMat)#生成NumPy数组,测试集inArr = np.array([ffMiles,precentTats, iceCream])#测试集归一化norminArr = (inArr - minVals) / ranges#返回分类结果classifierResult = classify0(norminArr, normMat, datingLabels, 3)#打印结果print("你可能%s这个人" % (resultList[classifierResult-1]))'''
#主函数,测试以上各个步骤,并输出各个步骤的结果
'''
if __name__ == '__main__':#打开的文件名filename = "datingTestSet.txt"#打开并处理数据datingDataMat, datingLabels = file2matrix(filename)#数据可视化showdatas(datingDataMat, datingLabels)#验证分类器datingClassTest()#使用分类器classifyPerson()

项目运行结果:

(1)数据可视化:

(2) 验证分类器计算错误率结果

(3)使用分类器根据输入数据获得预测结果

二、手写体数字识别

1.了解手写体数字识别

我们通过画图,或者在纸上写上数字或字母,将照片进行处理,得到固定的照片规格,将照片转换为文本0,1表示的内容。例如下图:

2、手写体数字识别思路

将测试数据转换成只有一列的0-1矩阵形式 将所有(N个)训练数据也都用上方法转换成只有一列的0-1矩阵形式

把N个单列数据存入新矩阵A中——矩阵A每一列存储一个字的所有信息

用测试数据与矩阵A中的每一列求距离,求得的N个距离存入距离数组中

从距离数组中取出最小的K个距离所对应的训练集的索引 拥有最多索引的值就是预测值

3.1、导入模块

import os,time,operator             #导入os内置库来读取文件名     导入time来测试效率
import pandas as pd                 #导入数据处理库pandas        安装方法pip install pandas
import numpy as np                  #导入科学计算库numpy         安装方法pip install numpy
import matplotlib.pyplot as plt     #导入绘图库matplotlib        安装方法pip install matplotlib

3.2、引入训练样本文件和测试样本文件,定义一个读取数据的转换数据的函数

trainingDigits =r'D:\机器学习代码\MLiA_SourceCode\machinelearninginaction\Ch02\digits\trainingDigits'
testDigits = r'D:\机器学习代码\MLiA_SourceCode\machinelearninginaction\Ch02\digits\testDigits'## ↑数据路径
tarining = (os.listdir(trainingDigits))                 ## 读取训练集
test = (os.listdir(testDigits))                        ## 读取测试集
def read_file(doc_name):                             ## 定义一个把32x32格式转为1行的函数data=np.zeros((1,1024))                         ## 创建1个zero数组f=open(doc_name)                               ## 打开文件for i in range(32):                          ## 已知每个文件中有32行32列hang=f.readline()                       ## 取行for j in range(32):                   ## 取每行中的每一列data[0,32*i+j]=int(hang[j])      ## 给data值# print(pd.DataFrame(data))             ## 不要在这里转换成DataFrame。return data                           ## 否则测试集效率会降低7倍## 读取训练集效率会降低12倍

3.3、定义一个字段转列表的函数

def dict_list(dic:dict):               ## 定义函数将字典转化为列表keys = dic.keys()                 ## dic.keys()就是字典的kvalues = dic.values()            ## dic.values()就是字典的Vlst = [(key,val) for  key,val in zip(keys, values)] ## for k,v in zip(k,v)return lst                        ## zip是一个可迭代对象## 返回一个列表

3.4、定义相似度函数

def xiangsidu(tests,xunlians,labels,k):    ## tests:测试集 # xulians:训练样本集 # labels:标签 # k: 邻近的个数data_hang=xunlians.shape[0]              ## 获取训练集的行数data_hangzu=np.tile(tests,(data_hang,1))-xunlians   ## 用tile把测试集tests重构成一个 data_hang行、1列的1维数组q=np.sqrt((zu**2).sum(axis=1)).argsort()     ## 计算完距离后从低到高排序,argsort返回的是索引my_dict = {}                                   ## 设置一个dictfor i in range(k):                              ## 根据我们的k来统计出现频率,样本类别votelabel=labels[q[i]]                         ## q[i]是索引值,通过labels来获取对应标签my_dict[votelabel] = my_dict.get(votelabel,0)+1   ## 统计每个标签的次数sortclasscount=sorted(dict_list(my_dict),key=operator.itemgetter(1),reverse=True)## 获取votelabel键对应的值,无返回默认return sortclasscount[0][0]                        ## 返回出现频次最高的类别

3.5、编写识别函数

def shibie():                                        ## 定义一个识别手写数字的函数label_list = []                                    ## 将训练集存储到一个矩阵并存储他的标签train_length = len(tarining)                        ## 直接一次获取训练集长度train_zero = np.zeros((train_length,1024))           ## 创建(训练集长度,1024)维度的zeros数组for i in range(train_length):                         ## 通过遍历训练集长度doc_name = tarining[i]                              ## 获取所有的文件名file_label = int(doc_name[0])                         ## 取文件名第一位文件的标签label_list.append(file_label)                           ## 将标签添加至handlabel中train_zero[i,:] = read_file(r'%s\%s'%(trainingDigits,doc_name))## 转成1024的数组## 下面是测试集errornum = 0                                                  ## 记录error的初值testnum = len(test)                                         ## 同上 获取测试集的长度errfile = []                                              ## 定义一个空列表for i in range(testnum):                               ## 将每一个测试样本放入训练集中使用KNN进行测试testdoc_name = test[i]                           ## 通过i当作下标来获取测试集里面的文件test_label = int(testdoc_name[0])              ## 拿到测试文件的名字 拿到我们的数字标签testdataor = read_file(r'%s\%s' %(testDigits,testdoc_name)) ## 调用read_file操作测试集result = xiangsidu(testdataor, train_zero, label_list, 3)  ## 调用xiangsidu返回了resultprint("正在测试 %d, 内容是 %d" % (test_label,result))    ## 输出result和标签if (result != test_label):                               ## 判断标签是否等于测试名errornum += 1                                       ## 不是则+1 记录次数errfile.append(testdoc_name)                       ## 并把错误的文件名加入错误列表print("错误数量有 :%d" % errornum)                       ## 输出错误的数量print("错误的有 :%s"%[i for i in errfile])             ## 输出错误的列表中的名字print("准确率 %.2f%%" % ((1 - (errornum / float(testnum))) * 100)) ## 计算准确率

3.6、调用

if __name__ == '__main__':                                        ## 声明主函数a = time.time()                                              ## 设置起始时间shibie()                                                   ## 调用测试函数b= time.time() - a                                       ## 计算运行时间print("运行时间:",b)                                   ## 输出运行时间

3.7、运行结果

【机器学习实验二】k-NN算法—改进约会网站以及手写体数字识别相关推荐

  1. 【机器学习】机器学习从零到掌握之三 -- 教你使用K近邻算法改进约会网站

    本文是<机器学习从零到掌握>系列之第3篇 机器学习从零到掌握之一 -- 教你理解K近邻算法 机器学习从零到掌握之二 -- 教你实现K近邻算法 本篇使用的数据存放在文本文件datingTes ...

  2. k-近邻算法1(kNN)使用kNN算法改进约会网站的配对效果

    最近边看NG老师的机器学习课程和西瓜书,无奈交织着各种数学推导,有些晦涩难懂,看到网上推荐了<machine learning in action>比较适合新手入门, 书中数据和源码在此  ...

  3. 使用k-近邻算法改进约会网站的配对效果

    2.2 使用k-近邻算法改进约会网站的配对效果 Helen交往过三种类型的人: 不喜欢的人 魅力一般的人 极具魅力的人 示例:在约会网站上使用k-近邻算法 (1)收集数据:提供文本文件: dating ...

  4. KNN算法改进约会网站匹配效果

    文章目录 实验 一.示例:KNN改进约会网站配对 二.实验过程 1.准备数据:从文本文件中解析数据 2.分析数据:使用Matplotlib创建散点图 3.准备数据:归一化数值 4.测试算法:作为完整程 ...

  5. KNN算法学习-实现海伦约会网站与手写体识别实验

    文章目录 前言 一.实验介绍 二:实验过程: 1.数据准备 2.分析数据 3.归一化数值 4.测试算法 5.使用算法 三.实验:实现手写识别系统 sklearn数据集 总结 前言 一.K-近邻算法是什 ...

  6. 机器学习实战之K近邻算法

    k近邻算法概述 简单地说,K近邻算法采用测量不同特征值之间的距离方法进行分类. 优 点 :精度高.对异常值不敏感.无数据输入假定. 缺点:计算复杂度高.空间复杂度高. 适用数据范围:数值型和标称型. ...

  7. 《机器学习实战》kNN算法及约会网站代码详解

    使用kNN算法进行分类的原理是:从训练集中选出离待分类点最近的kkk个点,在这kkk个点中所占比重最大的分类即为该点所在的分类.通常kkk不超过202020 kNN算法步骤: 计算数据集中的点与待分类 ...

  8. 《机器学习实战》K邻近算法

    K邻近算法 存在一个样本数据集合,样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系.输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样 ...

  9. Python机器学习实验二:1.编写代码,实现对iris数据集的KNN算法分类及预测

    Python机器学习实验二:编写代码,实现对iris数据集的KNN算法分类及预测 1.编写代码,实现对iris数据集的KNN算法分类及预测,要求: (1)数据集划分为测试集占20%: (2)n_nei ...

最新文章

  1. 在《糖豆人》身上,我们看到了竞技游戏火爆的六大因素
  2. 阿里云服务器安全设置
  3. RocketMq 事务消息使用
  4. Coolite Toolkit学习笔记一:AjaxEvent、AjaxMethod和Listeners
  5. Gink掉过的坑(一):将CCTableView导入到lua中
  6. Matlab滤波函数
  7. php pdo连接oracle乱码,PHP编程:php pdo oracle中文乱码的快速解决方法
  8. 制造业智能工厂车间无线工业物联网解决方案
  9. 科学研究设计五:实验设计
  10. 关于移动端H5获取微信非静默授权被拦截进入【微信快照页】问题及解决方案
  11. 如何使用Xcode的Targets来管理开发和生产版本的构建( 还不懂,复制过来后面再看)
  12. 订阅号服务器消息推送数量,微信服务号一个月4次的推文次数用完了,怎么增加推送数量?...
  13. iPad的屏幕大小是多少?
  14. android 中文冒号,Kotlin中双冒号::使用方法
  15. java标识符命名规范之驼峰命名法
  16. Linux安装aria2,并使用AriaNg图形管理
  17. 为什么选择软件测试这个岗位?(面经)
  18. RatingBar详解
  19. 高等数学(导数的应用)
  20. 【BZOJ2288】[POJ Challenge]生日礼物(线段树)

热门文章

  1. 方差分析——单因素方差分析
  2. python123监考系统_2020-2021学年第1学期 期末考试监考安排
  3. 用html css实现五角星,用CSS画五角星
  4. 华为8c系统语言切换,华为荣耀畅玩8C双清教程_怎么清理缓存和恢复出厂设置
  5. Python3中的可迭代类型
  6. DevOps在证券互联网研发中的应用与实践
  7. 授人以渔:分享我的算法学习经验
  8. Android Activity 生命周期和重要的相关函数(基础一)
  9. 有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王 猜数游戏:从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】 要求: 如果找到了,就提示找到,并给出下标值
  10. sigmod 函数与softmax 函数对比