zoukankan      html  css  js  c++  java
  • 机器学习-分类算法-kNN

    机器学习-分类算法-kNN

    kNNk-Nearest Neighbor)算法:一种基于向量间相似度的分类算法。

    kNN原理

    k最近邻(k-Nearest Neighbor)算法是比较简单的机器学习算法。它采用测量不同特征之间的距离方法进行分类。

    如果一个样本在特征空间中的k个最近邻(最相似)的样本中的大多数都属于一个类别,则该样本也属于这个类别。k表示外部定义的近邻数量。

    实现步骤

    第一阶段:确定k值(就是指最近邻居的个数)。一般是奇数个

    第二阶段:确定距离度量公式。文本分类一般使用夹角余弦,得出待分类数据点和所有已知类别的样本点,从中选择距离最近的k个样本。

    夹角余弦:cos = AB/|A||B|

    第三阶段:统计这k个样本点中各个类别的数量。根据k个样本中数量最多的样本是什么类别,我们就把这个数据点定为什么类别。

    实现代码1(训练集为一组事件发生概率,测试集为事件发生概率,求类型)

    from numpy import *
    import operator
    
    # 夹角余弦距离公式
    def consdist(vector1, vector2):
        print("vecotr1:",vector1)
        print("vector2:",vector2)
        result = dot(vector1, vector2) / (linalg.norm(vector1) * linalg.norm(vector2))
        print("result:", result)
        return result
    
    
    # KNN分类器
    # testData:测试集  trainSet:训练集    listClasses:类别标签    k:k个邻居
    def classify(testData, trainSet, listClasses, k):
        dataSetSize = trainSet.shape[0] # 返回样本的行数
        distances = array(zeros(dataSetSize))
        print("dataSetSize:", dataSetSize)
        for indx in range(dataSetSize): # 计算测试集和训练集之间的距离:余弦夹角
            distances[indx] = consdist(testData, trainSet[indx])
        # 根据生成的余弦夹角按从大到小排序,结果为索引号
        sortedDistIndics = argsort(-distances)
        classCount = {}
        for i in range(k):  # 获得角度最小的前K项作为参考项
            # 按排序顺序返回样本集对应的类别标签
            voteIlabel = listClasses[sortedDistIndics[i]]
            # 为字典classCount赋值,相同key,其中value加1
            classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1  # 获得voteIlabel的value值,没有则默认为0
        # 对分类字典classCount按value重新排序
        # sorted(data.items(), key = operator.itemgetter(1), reverse = True)
        # 该句是按字典排序的固定用法
        # classCount.items()  # 字典迭代器函数
        # key:排序参数  operator.itemgetter(1):多级排序
        sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
        return sortedClassCount[0][0]   # 返回序最高的一项
    
    dataArr = np.array([[0.238, 0, 0.1905, 0.1905, 0.1905, 0.1905], [0, 0.177, 0, 0.294, 0.235, 0.294], [0.2, 0.16, 0.12, 0.12, 0.2, 0.2]])
    dataMat = mat(dataArr)
    print("dataMat:", dataMat.shape)
    print("dataMat type:", type(dataMat))
    testSet = [0.2174, 0.2174, 0.1304, 0, 0.2174, 0.2174]
    testMat = mat(testSet)
    classLabel = [0, 1, 2]
    k = 3
    print("result:",classify(testSet, dataArr, classLabel, k))

    实现代码2(文本测试)

    # K近邻分类
    from numpy import  *
    import numpy as np
    import operator
    
    from com.machineLearning.Bayes.NBayes import NBayes
    
    
    def loadDataSet():
        # 训练集文本
        postingList = [
            ['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
            ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
            ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him', 'my'],
            ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
            ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
            ['quit', 'buying', 'worthless', 'dog', 'food', 'stopid']
        ]
        # 每个文本对应的分类
        classVec = [0, 1, 0, 1, 0, 1]
        return postingList, classVec
    
    
    # 夹角余弦距离公式
    def consdist(vector1, vector2):
        return dot(vector1, vector2) / (linalg.norm(vector1) * linalg.norm(vector2))
    
    
    # KNN分类器
    # testData:测试集  trainSet:训练集    listClasses:类别标签    k:k个邻居
    def classify(testData, trainSet, listClasses, k):
        dataSetSize = trainSet.shape[0] # 返回样本的行数
        distances = array(zeros(dataSetSize))
        for indx in range(dataSetSize): # 计算测试集和训练集之间的距离:余弦夹角
            distances[indx] = consdist(testData, trainSet[indx])
        # 根据生成的余弦夹角按从大到小排序,结果为索引号
        sortedDistIndics = argsort(-distances)
        classCount = {}
        for i in range(k):  # 获得角度最小的前K项作为参考项
            # 按排序顺序返回样本集对应的类别标签
            voteIlabel = listClasses[sortedDistIndics[i]]
            # 为字典classCount赋值,相同key,其中value加1
            classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1  # 获得voteIlabel的value值,没有则默认为0
        # 对分类字典classCount按value重新排序
        # sorted(data.items(), key = operator.itemgetter(1), reverse = True)
        # 该句是按字典排序的固定用法
        # classCount.items()  # 字典迭代器函数
        # key:排序参数  operator.itemgetter(1):多级排序
        sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse=True)
        return sortedClassCount[0][0]   # 返回序最高的一项
    
    
    # 使用KNN算法实现文本分类
    k = 3
    dataSet, lisClasses = loadDataSet()
    nb = NBayes()
    nb.train_set(dataSet, lisClasses)
    # 使用之前的贝叶斯分类阶段的数据集及生成的TF向量进行分类
    print(classify(nb.tf[3], nb.tf, lisClasses, k))
    NBayes看上一篇。
  • 相关阅读:
    [ Scala ]关于scala环境搭建过程中,sbt编译中maven下载失败的解决方案(改成阿里的maven仓库)
    复习笔记:一个简单的动态代理实现
    复习笔记:一个简单的反射工厂Demo
    定时器Timer如何终止运行的问题
    Python RESTful接口开发02
    python 内置模块 logging的使用
    Django项目数据处理的流程是怎样的
    Django-Redis:在Django中使用redis作为缓存
    Python RESTful 接口开发01
    teamview
  • 原文地址:https://www.cnblogs.com/EnzoDin/p/12416656.html
Copyright © 2011-2022 走看看