《机器学习实战》个人学习记录笔记(一)———K-近邻算法

第二章 k-近邻算法

PS:个人笔记 根据《机器学习实战》这本书,Jack-Cui的博客,以及深度眸的视频进行学习

1 KNN原理

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


2 优缺点及适用数据范围

优点:

精度高(将测试数据与训练数据根据不同特征值算出其距离,然后设置选取K值,选取的K值中按照vote规则将该数据分类)

对异常值不敏感 (因为是要设置K值,也就是选取最近的K个数据,所以对于存在的一些极端值异常值,很好的忽略了)   

无数据输入假定 (类比NB算法,该算法要假设样本间是独立的,而对于KNN算法则无需这些假定)

缺点:

计算复杂度高(虽然是取K值,但是算距离时测试样本要和每个训练样本进行计算,然后进行排序,得出距离最近的K个样本,所以如果训练样本的量是1000,或者更高,就会造成很大的计算)

空间复杂度高()

最大的缺点是无法给出数据的内在含义()

适用数据范围:

①数值型

②标称型

3 KNN算法的向量距离度量准则

欧式距离——欧几里得度量(euclidean metric)是一个通常采用的距离定义,指在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离。

计算公式:

4 代码实现(代码是Jack-Cui博客中的代码)

4.1 准备数据集

import numpy as np

def createDataSet():   #定义一个函数,函数作用是创建数据集,返回特征列表和标签列表
    group = np.array([[1,101],[5,89],[108,5],[115,8]])   #四个数据  np.array()是数组功能即创建数组
    labels = ['爱情片','爱情片','动作片','动作片']         #四个数据对应的标签分类
    return group, labels
if __name__ == '__main__':
    group, labels = createDataSet()        #创建数据集
    print(group)                           #打印显示
    print(labels)


4.2 k-近邻算法

import numpy as np
import operator

"""
Parameters:
    inX - 用于分类的数据(测试集)
    dataSet - 用于训练的数据(训练集)
    labes - 分类标签
    k - kNN算法参数,选择距离最小的k个点
Returns:
    sortedClassCount[0][0] - 分类结果
"""
def classify0(inX, dataSet, labels, k):                 #KNN算法,分类器
    dataSetSize = dataSet.shape[0]                      #np.shape()函数返回的是数组的行和列;这里shape[0]返回的行数
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet  #np.tile()函数是数组进行复制,第一个参数是数组,第二个参数则是复制的规则,行列分别复制几次;这里是在列向量方向上重复inX共1次(横向),行向量方向上重复inX共dataSetSize次(纵向);这里也就是将一个数据inX与所有的训练数据进行二维特征相减,得到一个shape[0]行,1列的数组  
    sqDiffMat = diffMat**2                              #二维特征相减后平方
    sqDistances = sqDiffMat.sum(axis=1)                 #sum()所有元素相加,sum(0)列相加,sum(1)行相加;这里就是行相加
    distances = sqDistances**0.5                        #开方,计算出距离,这里就得出了距离了
    sortedDistIndices = distances.argsort()             #argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引),然后输出到y
    classCount = {}                                     #定一个记录类别次数的字典
    for i in range(k):
        voteIlabel = labels[sortedDistIndices[i]]       #取出前k个元素的类别,这里其实就是要vote,因为前面已经按照从大到小排列了
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1    #dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。这里key肯定存在,然后计算类别次数
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)      #items()方法以列表返回可遍历的(键, 值) 元组数组。key=operator.itemgetter(1)根据字典的值进行排序,key=operator.itemgetter(0)根据字典的键进行排序,reverse降序排序字典
    return sortedClassCount[0][0]                       #返回次数最多的类别,即所要分类的类别


4.3 整体代码

import numpy as np
import operator

def createDataSet():
    group = np.array([[1,101],[5,89],[108,5],[115,8]])
    labels = ['爱情片','爱情片','动作片','动作片']
    return group, labels

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndices = distances.argsort()
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistIndices[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

if __name__ == '__main__':
    group, labels = createDataSet()
    test = [101,20]                                  #测试集
    test_class = classify0(test, group, labels, 3)   #KNN分类
    print(test_class)                                #打印分类结果


⭐⭐⭐k-近邻算法没有进行数据的训练,直接使用未知的数据与已知的数据进行比较,得到结果。因此,可以说k-邻近算法不具有显式的学习过程。


















阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页