《机器学习实战》阅读笔记(二)

第二章 k-近邻算法(kNN)

2.1k-近邻算法概述

定义:采用测量不同特征值之间的距离方法进行分类

优点:精度高,对异常值不敏感、无数据输入假定。

缺点:计算复杂度高、空间复杂度高。

适用数据范围:数值型和标称型。

工作原理:存在一个训练样本集,样本集中的每个数据都存在标签,即我们知道每个数据属于哪个分类。输入没有标签的新数据之后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据的分类标签。一般来说,只选择前k个最相似的数据,所以叫做k-近邻算法。通常,k是不大于20的整数。最后选择k个相似数据中出现最多的分类,作为新数据的分类。

一般流程:

1.收集数据

2.准备数据:距离计算所需要的数值,最好是结构化的数据格式。

3.分析数据

4.训练算法:不适用于kNN。

5.测试算法:计算错误率。

6.使用算法:首先输入样本数据和结构化的输出结果,然后运行k近邻算法判定输入数据属于哪个分类,最后应用计算出的分类执行后续处理。

2.1.1准备:使用Python导入数据

首先创建一个kNN.py文件如下:

#kNN.py
#两个包分别是科学计算包和运算符模块,这个模块中有运行kNN所需要的函数
from numpy import *
import operator 
def createDataSet():
    group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels=['A','A','B','B']
    return group,labels

然后,打开Windows PowerShell,进入kNN.py所在目录,输入python进入python交互式开发环境,导入刚才编辑的程序模块

import kNN

创建数据集

group,labels=createDataSet()

可以检查一下是否准确。现在我们有四组数据,每组有两个特征值。

2.1.2实施kNN分类算法

伪代码:

对未知分类属性的数据集中的每个点依次执行以下操作:

1.计算已知类别数据集中的点与当前点的距离

2.按照距离递增次序排序

3.选取与当前点距离最小的k个点

4.确定前k个点所在类别的出现频率

5.返回前k个点出现频率最高的类别作为当前点的预测分类

代码解释

#定义了一个名为classify0的函数,有四个输入值:用于分类的新数据,训练样本,标签,近邻数目,标签数目和训练样本的行数应当相同
#dataSet 是一个array,其中的数据类型必须相同,array.shape 可以得到有几个实例以及每个实例有几个特征,此处得到的是实例的个数
#tile函数位于python模块 numpy.lib.shape_base中,他的功能是重复某个数组。比如tile(A,n),功能是将数组A重复n次,构成一个新的数组
#如果inX=[0,0],dataSetSize=4,tile(inX,(dataSetSize,1))=array([[0,0],[0,0],[0,0],[0,0]])
#dataSet=array([[1,1.1],[1,1],[0,0],[0,0.1]])
#.sum(axis=1)就是将一个矩阵的每一行向量相加,换句话说就是每个[]里面的数相加
#distances=array([1.49,1.41,0,0.1])
#.argsort()出现下标array([2,3,0,1])
#classCount={}字典
#classCount[voteIlabel]=classCount.get(voteIlabel,0)+1 具体解释https://blog.csdn.net/weixin_38705903/article/details/79231551

#第二个域的值进行排序,逆序,classCount.iteritems()返回迭代器,sortedClassCount[0][0]返回的第一个值的第一个域

def classify0(inX,dataSet,labels,k):
    dataSetSize=dataSet.shape[0]
    #计算距离
    diffMat=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.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]
注意:Python 3.6.0改为
sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)

然后在交互式界面中输入

kNN.classify0([0,0],group,labels,3)

运行结果为B。

2.1.3测试分类器

可以使用已知答案的数据,用分类器给出错误结果的次数除以测试执行次数,得到错误率。

2.2示例:使用k近邻算法改进约会网站的配对效果

步骤:

1.收集数据:准备文本文件

2.准备数据:使用Python解析文本文件

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

4.训练算法:此步骤不适用于k近邻算法。

5.测试算法:使用海伦提供的部分数据作为测试样本。

6.使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。

2.2.1准备数据:从文本文件中解析数据

datingTestSet.txt 1000个实例,3个特征 创建名为file2matrix的函数,加入kNN.py。

def file2matrix(filename):
    fr=open(filename)
	array0lines=fr.readlines()
	number0fLines=len(array0lines)
	#得到行数,创建空矩阵
	returnMat=zeros((number0fLines,3))
	classLabelVector=[]
	index=0
	for line in array0lines:
	    #移除回车
	    line=line.strip()
		listFormLine=line.split('\t')
		returnMat[index,:]=listFormLine[0:3]
		#取出最后一列的label
		classLabelVector.append(int(listFromLine[-1]))
		index +=1
	return returnMat,classLabelVector
	

TabError: inconsistent use of tabs and spaces in indentation

这个错误是混用了Tab键和四个空格

然后在交互式界面输入

import kNN
datingDataMat,datingLabels=kNN.file2matrix('datingTestSet2.txt')

2.2.2 分析数据:使用Matplotlib创建散点图

在交互式界面输入

>>> import matplotlib
>>> import matplotlib.pyplot as plt
>>> fig=plt.figure()
>>> ax=fig.add_subplot(111)
>>> ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15*array(datingLabels))
>>> plt.show()

得到

待续






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值