• k-近邻算法


    2.1 概述

    1) k-近邻算法采用测量不同特征值之间 距离 的办法进行分类。

       优点:精度高、对异常值不敏感、无数据输入假定;泛化错误率不超过不超过贝叶斯最优分类的两倍。

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

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

    2)k-近邻算法原理:

      1. 已知 训练样本集 和 样本集中数据的标签。

      2. 输入 没有标签的 数据集 并将 新数据集中的数据的特征 与 训练集 的 特征 进行比较

      3 算法提取最接近数据集的样本集的标签。

    3) python算法实现(py3.6)

    # coding:utf-8
    
    
    # 准备
    # 使用python导入数据
    
    # 导入科学计算包numpy 和 运算符模块
    #createDataSet 创建数据集 和 标签
    from numpy import * import operator def createDataSet(): group = array([[1.0,0.9], [1.1,0.8],[0.2,0.3],[0,0]]) labels = ('A','A','B','B') return group,labels

     验证模板是否创建成功

    #在cmd中输入以下代码验证上述模块是否插入成功
    >>>import
    kNN >>>group,labels = kNN.createDataSet() >>>group array([[1. , 0.9], [1.1, 0.8], [0.2, 0.3], [0. , 0. ]]) >>>labels ('A', 'A', 'B', 'B')

    程序清单2-1  k-近邻算法 

    # 程序清单2-1
    # k-近邻算法
    
    # 分类代码
    # 四个参数的意义:
    # inX:用来分类的测试集
    # dataSet : 用来训练的数据集属性
    # labels: 用来分类的数据集标签
    # k: k-近邻算法的k,表示选取k个有效数
    
    def classify0 (inX, dataSet, labels, k):
        # shape[0], 返回data的行数  0- 按0维变化方向shape[i][]
        dataSetSize = dataSet.shape[0]
        # tile函数实现矩阵重复,在列方向重复1次,行方向重复dataSetSize次;
        # 对应值相减存放在 列表 diffMat中
        diffMat = tile(inX, (dataSetSize,1)) - dataSet
        # 平方
        sqDiffMat = diffMat ** 2
        # sum求和,axis = 1为按1即维变化方向操作sum[][j],axis = 0 为按0维方向操作sum[i][]
        sqDistances = sqDiffMat.sum(axis=1)
        # 开方
        distances = sqDistances ** 0.5
        # distances.argsort(),将distances中元素即距离,从小到大排序,并返回索引值,存放在sortedDistIndicies
        sortedDistIndicies = distances.argsort()
        # 创建一个空字典
        ClassCount = {}
        for i in range(k):
            # 返回距离排名第i的标签
            voteIlabel = labels[sortedDistIndicies[i]]

    # 用字典记录 键(标签)出现的 次数
    # dict.get(key,default= None),字典中 get() 返回字典中指定 键 的 值
    # dict.get() 若字典中没有该标签则创建并将其值置为1,若已有标签则返回其值并将值加1 # 如果 key不在字典中,则返回默认值default的值 ClassCount[voteIlabel] = ClassCount.get(voteIlabel, 0) + 1 # 将 ClassCouNt 中的值进行排序 # sorted(iterable,cmp= None,key = None,reverse = false) # iterable 待排序的可迭代类型的容器 # cmp:用于比较函数;key = operator,itemgetter(1)根据字典的值进行排序 # key=operator.itemgetter(1)根据字典的键进行排序 # reverse = True 降序 or reverse = False 升序|(默认) sortedClassCount = sorted(ClassCount.items(), key=operator.itemgetter(1), reverse=True) # 返回要分类的类别的标签 return sortedClassCount[0][0]

     程序清单 2-2 将文本程序转化为Numpy的解析程序

    # 2.2.1
    # 准备数据:从文本中解析数据
    # 程序清单2-2
    # 将文本记录转化为Numpy的解析程序
    
    def file2matrix(filename):
        # 打开文件
        fr = open(filename)
        # readlines()方法用于读取所有行(直到结束符 EOF)并返回 列表 ;如果碰到结束符 EOF 则返回 空字符串
        arrayOLines = fr.readlines()
        # 返回文件行数
        numberOFLines = len(arrayOLines)
        # 创建返回特定形状的以0填充的 numpy 矩阵(n 行 * 每行 m 列)
        returnMat = zeros((numberOFLines, 3))
        # 创建空列表 存储标签
        classLabelVector = []
        index = 0
        for line in arrayOLines:
            # 去掉字符串前后的空格
            line = line.strip()
            #  split() 通过指定 分隔符("	") 对字符串进行切片,如果参数 num 有指定值,则仅分隔 num 个子字符串
            listFromLine = line.split("	")
            # 填充 returnMat 用切片好的 listFromLines
            returnMat[index, :] = listFromLine[0:3]
            # 将 listFromLines 中的标签输入字典 classLabelVetor 中
            classLabelVector.append(int(listFromLine[-1]))
            index += 1
        return returnMat, classLabelVector

    2.2.3 归一化数值

      当数据集和样本集中的 某一个属性的 数值差值过大时 会影响 到各个属性的权重值。所以采用归一化的方法来解决这个问题。

       公式: newValue = (oldValue - min) / (max - min)

    # 2.2.3
    # 数据归一化
    
    def autoNorm(dataSet):
        minVals = dataSet.min(0)
        maxVals = dataSet.max(0)
        ranges = maxVals - minVals
        normDataSet = zeros(shape(dataSet))
        m = dataSet.shape[0]
        normDataSet = dataSet - tile(minVals, (m, 1))
        normDataSet = normDataSet / tile(ranges, (m,1))
        return normDataSet, ranges, minVals

     遇到的一些问题

    Numpy 包的下载与安装:直接用的 Anaconda ,配置环境变量后可以直接使用

    kNN 模板路径问题 :1.可以直接放在 python.exe 所在的文件夹 如我的是 C:Anaconda3

                                      2.如上使用 import sys 方法

    datingTestSet.txt 路径问题 : 1. 引用时使用绝对路径   2.命名为 datingTestSet 而不是 datingTestSet.txt

  • 相关阅读:
    Java第四章课后整理
    java第三章课后作业1
    Java第三章整理
    JAVA第二章课后作业
    JAVA第二章整理
    java课后作业1
    JAVA第一章整理实验
    JAVA大道至简第一章伪代码
    文本数据特征选取的四种方法
    时域分析与频率分析的比较
  • 原文地址:https://www.cnblogs.com/jhdcjh/p/8969743.html
Copyright © 2020-2023  润新知