k-近邻算法(KNN)算法概述(分类器)

KNN通过测量不同特征值之间的距离进行分类。大致思路:一个样本在k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别。那么该样本也属于这个类别。

参考书籍:《python经典学习实例》、《机器学习实战》
源码地址:https://github.com/Metatronxl/MachineLearning/tree/master/kNN
用图来举例子

kNN算法

算法实现

1.数据预处理

主要是将提供的数据集处理成函数可以处理的数据


def file2matrix(filename):
    fr = open(filename)
    arrayOfLines = fr.readlines()
    numberOfLines = len(arrayOfLines)
    returnMat = zeros((numberOfLines,3))
    classLabelVector = []

    index = 0
    for line in arrayOfLines:
        line = line.strip()
        listFromLine = line.split("\t")
        returnMat[index,:] = listFromLine[0:3] # 第index行的数据
        classLabelVector.append(int(listFromLine[-1]))
        index+=1
    return returnMat,classLabelVector

2.数据归一化

当多个维度的数据我们认为是同等重要的时候,通常采用的方法是将数值归一化,这样可以避免数字差值对计算结果造成的影响。

2.1归一化公式

newValue = (oldValue-min)/(max-min)

2.2 归一化(正则化)代码实现
## Normalization
def autoNorm(dataSet):
    minVals = dataSet.min(0) ## 0 means 数组的第二维(纵列)
    maxVals = dataSet.max(0)
    ranges = maxVals-minVals
    normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0]  #shape[1]为第二维的长度(横列),shape[0]为第一维的长度(纵列)

    ## newValue = (oldvalue-min)/(max-min)
    normDataSet = dataSet - tile(minVals,(m,1))
    normDataSet = normDataSet/tile(ranges,(m,1))


    return normDataSet,ranges,minVals

需要注意的是,sklearn提供了函数,也可以直接调用sklearn的api

  • L1正则化是指权值向量w中各个元素的绝对值之和,通常表示为||w||1
  • L2正则化是指权值向量w中各个元素的平方和然后再求平方根(可以看到Ridge回归的L2正则化项有平方符号),通常表示为||w||2
 from sklearn import preprocessing

 returnMat,classLabel = file2Metrix("datingTestSet2.txt")
 hoRatio = 0.10
 num_neighbors = 3

 normMat = preprocessing.normalize(returnMat,'l2')

3. KNN算法

算法的原理很简单就不赘述了,直接上代码吧

classify0()有四个输入参数:用于分类的输入向量inX,输入的训练样本集为dataSet,标签向量labels,最后的参数k表示选择最近邻居的数目

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    # axis代表的是第几维的数组 0为1维,1为2维
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    # argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引),然后输出到y
    sortedDistIndicies = distances.argsort()
    classCount={}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

采用sklearn的api实现kNN算法

from sklearn import neighbors

def testKNN():

   returnMat,classLabel = file2Metrix("datingTestSet2.txt")
   hoRatio = 0.10 ## 测试集的数量
   num_neighbors = 3 ##选择k的数量
   normMat = preprocessing.normalize(returnMat,'l2')
   m = normMat.shape[0]
   numTestVecs = int(m*hoRatio)
   classifier = neighbors.KNeighborsClassifier(num_neighbors,weights='distance')
   classifier.fit(returnMat[numTestVecs:,],classLabel[numTestVecs:])

    ### predict 来得到预测的结果
   error_count = 0
   for item,result in zip(returnMat[:numTestVecs],classLabel[:numTestVecs]):
       #告诉模型这是一个example,而不是多个
       test_value = item.reshape(1,-1)
       predict_result = classifier.predict(test_value)[0]
       print "predicted output:",classifier.predict(test_value)[0]
       if predict_result != result:
           error_count +=1
   print "error_rate is %f" % (error_count/float(m*0.9))
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Metatronxl/article/details/80692467
个人分类: 机器学习
想对作者说点什么? 我来说一句

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

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭