机器学习01-kNN邻近算法

Posted Qunar_尤雪萍

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习01-kNN邻近算法相关的知识,希望对你有一定的参考价值。

k-近邻算法

概述:k-近邻算法采用测量不同特征值之间的距离方法进行分类
优点:精度高、对于异常值不敏感,无数据输入假定
缺点:计算复杂度高,空间复杂度高,并且它没有办法各处基础数据的一些内部信息数据。
算法描述:存在一个准确的数据集合样本,称作训练样本集,样本集合中每个item都附带自己所属分类标签。当需要判断新数据的分类是,只需要计算特征数据和样本数据中最相似的分类标签,选择k个最相似的标签,k个标签中占比最多的即为目标标签。

具体分类算法

    #-*- coding=utf-8 -*-
    from numpy import *
    import operator

    ##简单的kNN算法实现
    #dataSet是训练数据集合,每行代表每个训练数据的每个特征值
    #labels 对应dataSet每个训练数据的class标签
    #inX 表示待分类的特征数据
    def classify0(inX, dataSet, labels, k):
        dataSetSize = dataSet.shape[0] # 获取测试集合大小
        #求每个输入特征值和每个测试集合总的特征值的超时
        #首先需要使用tile将特征值扩展为和测试集合相等大小的矩阵
        diffMat = tile(inX, (dataSetSize, 1)) - dataSet
        #取平方
        sqlDiffMat = diffMat ** 2
        sumMat = sqlDiffMat.sum(axis=1)
        distances = sumMat ** 0.5
        #获取排序信息
        #例如:array([9,1,3,0]) -> array([3,1,2,0]) 升序标签
        sortIndicies = distances.argsort()

        classCount = 
        #取距离最小的前k个对应的标签统计信息
        for i in range(k):
            label = labels[sortIndicies[i]]
            classCount[label] = classCount.get(label,0) + 1

        #取最大的

        sortedClassCount = sorted(classCount.iteritems(), key = operator.itemgetter(1), reverse=True) 
        return sortedClassCount[0][0]

关于特征数据

不同的特征,具体的数据值波动区间是不同的,例如特征A取值范围在[1000,10000],但是特征B取值范围在[0,10],如果直接使用这样的特征数据进行KNN算法运算,会出现的一个问题,高区间的特征对结果的影响远远大于低区间的特征值,因此我们需要对我们的特征数据做归一化处理,即将所有特征值处理到相同的区间范围中。
具体算法:((特征值-min)/(max - min)) -> [0,1]区间范围

    from numpy import *
    import operator
    #用于将一个不同范围域的特征值归一化到统一的[0,1]之间
    def normData(dataSet):
        #获取每个特征的最大值
        maxValue = dataSet.max(0)
        #获取每个特征的最小值
        minValue = dataSet.min(0)
        ranges=maxValue-minValue
        #将数据归一到同一个范围
        normalDataSet = zeros(shape(dataSet))
        m = dataSet.shape[0]
        normalDataSet = dataSet - tile(ranges,(m,1))
        #除于最大值
        normalDataSet = normalDataSet/tile(maxValue,(m,1))

        return normalDataSet, ranges, minValues

关于可视化特征数据

如何判别我们取得的特征数据集合适合使用knn进行分类训练?
在做数据观察时我们往往需要通过可视化方式去观察我们的特征数据和label的分布,这个时候就需要用到Python的一个图形工具matplotlib。
特征和分类数据:testSet.txt
3.542485 1.977398 -1
3.018896 2.556416 -1
7.551510 -1.580030 1
2.114999 -0.004466 -1
8.127113 1.274372 1
7.108772 -0.986906 1
8.610639 2.046708 1
2.326297 0.265213 -1
3.634009 1.730537 -1
0.341367 -0.894998 -1
3.125951 0.293251 -1
2.123252 -0.783563 -1
0.887835 -2.797792 -1
7.139979 -2.329896 1
1.696414 -1.212496 -1
8.117032 0.623493 1
8.497162 -0.266649 1
4.658191 3.507396 -1
8.197181 1.545132 1
1.208047 0.213100 -1
1.928486 -0.321870 -1
2.175808 -0.014527 -1
7.886608 0.461755 1
3.223038 -0.552392 -1
3.628502 2.190585 -1
7.407860 -0.121961 1
7.286357 0.251077 1

可视化脚本:


from numpy import *
import matplotlib
import matplotlib.pyplot as plt

##read file
fr = open('testSet.txt')
lines = fr.readlines()
dataSet = zeros((len(lines),1))
labels = []
index = 0
for line in lines:
    items = line.strip().split('\\t')
    dataSet[index:] = items[0:2]
    labels.append(items[-1])
#matplot
fx = plt.figure()
ax = fx.add_subplot(111)
#将数组转换为矩阵
dataSet = matrix(dataSet)
colora = tile(50, len(lines))
#这里的colora是为了通过颜色区分不同的labels, cmap代表颜色map,默认是yard, s是每个点的大小,alpha是每个点的透明度
ax.scatter(dataSet[:,0], dataSet[:,1], c=colora * labels, cmap='autum', s=50, alpha=0.3)

plt.show()

以上是关于机器学习01-kNN邻近算法的主要内容,如果未能解决你的问题,请参考以下文章

机器学习01-kNN邻近算法

01 KNN算法 - 概述

机器学习100天(二十六):026 k近邻分类算法-理论

机器学习100天(二十六):026 k近邻分类算法-理论

机器学习100天(二十六):026 k近邻分类算法-理论

机器学习 机器学习 分类算法--K近邻算法 KNN (下)