《机器学习实战》学习笔记 ch2 k-近邻算法

参考博文:

KNN算法:

http://blog.csdn.net/c406495762(非常详细,推荐)

https://www.cnblogs.com/ybjourney/p/4702562.html

函数相关:

https://blog.csdn.net/qq_18433441/article/details/54897250

https://www.cnblogs.com/jyxbk/p/8664817.html

https://www.cnblogs.com/yyxf1413/p/6253995.html

初学python 代码中很多函数不了解,自己进一步做了注释

# -*- coding: utf-8 -*-
import numpy as np
import operator
"""
函数说明:创建数据集

Parameters:
    无
Returns:
    group - 数据集
    labels - 分类标签
"""
def createDataSet():
    #四组二维特征
    group=np.array([[1,101],[5,89],[108,5],[115,8]])
    #分别表示四个点:爱情片,爱情片,动作片,动作片
    #四组特征标签
    labels=['爱情片','爱情片','动作片','动作片']
    return group,labels

"""
函数说明:kNN算法,分类器
算法描述:1)计算测试数据与各个训练数据之间的距离;

         2)按照距离的递增关系进行排序;

         3)选取距离最小的K个点;

         4)确定前K个点所在类别的出现频率;

         5)返回前K个点中出现频率最高的类别作为测试数据的预测分类。
Parameters:
    inX - 用于分类的数据(测试集)
    dataSet - 用于训练的数据(训练集)
    labes - 分类标签
    k - kNN算法参数,选择距离最小的k个点
Returns:
    sortedClassCount[0][0] - 分类结果
"""

def classify0(inX,dataSet,labels,k):
    #shape[0]返回dataSet的行数
    dataSetSize=dataSet.shape[0]
    """
    >>> b = np.array([[1, 2], [3, 4]])
    >>> np.tile(b, 2) #沿X轴复制2倍
    array([[1, 2, 1, 2],
           [3, 4, 3, 4]])
    >>> np.tile(b, (2, 1))#沿X轴复制1倍(相当于没有复制),再沿Y轴复制2倍
    array([[1, 2],
           [3, 4],
           [1, 2],
           [3, 4]])
    """
    
    #在列方向上重复inX共1次(横向),行方向重复inX共dataSetSize次(纵向)
    #将测试集大小扩展为与训练集一样大,相减的差即为点之间的距离
    diffMat=np.tile(inX,(dataSetSize,1))-dataSet
    
    #二维特征相减后平方
    sqDiffMat=diffMat**2
    
    #sum(0)列相加,sum(1)行相加
    sqDistances=sqDiffMat.sum(axis=1)
    """
    a = np.array([[0, 2, 1]])
    print a.sum()
    print a.sum(axis=0)
    print a.sum(axis=1)
    结果分别是:3, [0 2 1], [3]
    
    b = np.array([0, 2, 1])
    print b.sum()
    print b.sum(axis=0)
    print b.sum(axis=1)
    结果分别是:3, 3, 运行错误:'axis' entry is out of bounds
    可知:对一维数组,只有第0轴,没有第1轴

    c = np.array([[0, 2, 1], [3, 5, 6], [0, 1, 1]])
    print c.sum()
    print c.sum(axis=0)
    print c.sum(axis=1)
    结果分别是:19, [3 8 8], [ 3 14  2]
    """
    
    #开方,计算距离(欧氏距离)
    distances=sqDistances**0.5
    
    #返回distances中元素从小到大排序后的索引值
    sortedDistIndices=distances.argsort()
    """
    x=np.array([1,4,3,-1,6,9])
    y=x.argsort()
    >>>y=array([3,0,2,1,4,5])。
    argsort()函数是将x中的元素从小到大排列提取其对应的index(索引),
    然后输出到y。例如:x[3]=-1最小,所以y[0]=3,x[5]=9最大,所以y[5]=5
    """
    
    #定一个记录类别次数的字典
    classCount={}
    #取出前k个元素的类别(距离与测试集最近的k个类别)
    for i in range(k):
        #当前标签
        voteIlabel=labels[sortedDistIndices[i]]
        #计算类别次数
        #dice.get(k,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]
        
if __name__=='__main__':
    #当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当
    #.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。
    #创建数据集
    group,labels=createDataSet()
    #测试集
    test=[101,20]
    #KNN分类
    test_class=classify0(test,group,labels,3)
    #打印分类结果
    print(test_class)
    

猜你喜欢

转载自blog.csdn.net/cong427/article/details/84430761