MachineLearning02_KNN(最近K邻算法)

本文介绍了kNN算法的基本原理,包括距离计算、邻居选择和类别判定等步骤,并通过一个实例展示了算法的具体应用过程。同时,文章还讨论了kNN算法的优点和缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kNN算法的指导思想是“近朱者赤,近墨者黑”,由你的邻居来推断出你的类别。

1、指导思想
kNN算法的指导思想是“近朱者赤,近墨者黑”,由你的邻居来推断出你的类别。

计算步骤如下:
    1)算距离:给定测试对象,计算它与训练集中的每个对象的距离(一般采用欧几里得距离)
    2)找邻居:圈定距离最近的k个训练对象,作为测试对象的近邻
    3)做分类:根据这k个近邻归属的主要类别,来对测试对象分类

2、距离或相似度的衡量
什么是合适的距离衡量?距离越近应该意味着这两个点属于一个分类的可能性越大。
觉的距离衡量包括欧式距离、夹角余弦等。
对于文本分类来说,使用余弦(cosine)来计算相似度就比欧式(Euclidean)距离更合适。

3、类别的判定
投票决定:少数服从多数,近邻中哪个类别的点最多就分为该类。
加权投票法:根据距离的远近,对近邻的投票进行加权,距离越近则权重越大(权重为距离平方的倒数)

优缺点

1、优点
简单,易于理解,易于实现,无需估计参数,无需训练
适合对稀有事件进行分类(例如当流失率很低时,比如低于0.5%,构造流失预测模型)
特别适合于多分类问题(multi-modal,对象具有多个类别标签),例如根据基因特征来判断其功能分类,kNN比SVM的表现要好

2、缺点
懒惰算法,对测试样本分类时的计算量大,内存开销大,评分慢
可解释性较差,无法给出决策树那样的规则。
注意:k值的选择一般小于样本的开放

example

下面模仿一下算法的过程

如上图所示 k=5
选取靠谱x的5个点,其中有4个点属于类别w1,1个属于类别w3,根据少数服从多数的原则,判断x的类型是w1

代码如下(python实现)
import csv
import random
import math
import operator

#导入数据集
def loadDataset(filename,split,trainingSet=[],testSet=[]):
    with open(filename,'rb') as csvfile:
        lines=csv.reader(csvfile)
        dataset=list(lines)
        print len(dataset)
        for x in range(len(dataset)-1):
            for y in range(4):
                dataset[x][y]=float(dataset[x][y])
                
            if random.random()<split:
                trainingSet.append(dataset[x])
            else:
                testSet.append(dataset[x])

#计算欧几里得距离
def euclideanDistance(instance1,instance2,length):
    distance=0
    for x in range(length):
        distance+=pow((instance1[x]-instance2[x]),2)
    return math.sqrt(distance)

#拿到要判断实例的k个最近的邻居
def getNeighbors(trainingSet,testInstance,k):
    distances=[]
    length=len(testInstance)-1
    for x in range(len(trainingSet)):
        dist=euclideanDistance(testInstance,trainingSet[x],length)
        distances.append((trainingSet[x],dist))
    distances.sort(key=operator.itemgetter(1))
    neighbors=[]
    for x in range(k):
        neighbors.append(distances[x][0])
    return neighbors

#根据拿到的k个邻居中根据少数服从多数的原则,判定这个实例的类型
def getResponse(neighbors):
    classVotes={}
    for x in range(len(neighbors)):
        response=neighbors[x][-1]
        if response in classVotes:
            classVotes[response]+=1
        else:
            classVotes[response]=1
    sortedVotes=sorted(classVotes.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedVotes[0][0]

def getAccuracy(testSet,predictions):
    correct=0
    for x in range(len(testSet)):
        if testSet[x][-1]==predictions[x]:
            correct+=1
    return (correct/float(len(testSet)))*100.0

def main():
    trainingSet=[]
    testSet=[]
    split=0.67
    loadDataset(r'F:\pythontest\KNN\iris.data.set.txt',split,trainingSet,testSet)
    print 'Train set:'+repr(len(trainingSet))
    print 'Test set:'+repr(len(testSet))

    predictions=[]
    k=3
    for x in range(len(testSet)):
        neighbors=getNeighbors(trainingSet,testSet[x],k)
        result=getResponse(neighbors)
        predictions.append(result)
        print('> predicted='+repr(result)+', actual='+repr(testSet[x][-1]))
    accuracy=getAccuracy(testSet,predictions)
    print('Accuracy:'+repr(accuracy)+'%')




main()



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值