【机器学习】3.最邻近规则分类KNN算法

本文详细介绍K近邻(KNN)算法的基本原理,包括算法步骤、关键参数设置如K值选择及距离度量方法,并探讨了算法的优点与局限性。此外,还提供了使用Python实现KNN的具体代码示例。

1.KNN是一种基本分类与回归方法、K近邻法的输入为实例的特征向量,对应于特征空间的点;输出为实例的类别,可以取多类,K近邻法假设给定一个训练数据集,其中的实例类别已定。分类时根据其K个最近邻的训练实例的类别。通过多数表决等方式进行预测。


2.K近邻法三要素:K值的选择,距离度量,分类决策规则。


3.算法详述

    3.1步骤:

        为了判断未知实例的类别,以所有已知类别的实例作为参考。

        选择参数K。

        计算未知实例与所有已知实例的距离。

        选择最近K个已知实例

        根据少数服从多数的投票法则,让未知实例归类为k个最邻近样本中最多数的类别。

    3.2细节

        关于K

        关于距离的衡量方法

            3.2.1Euclidean Distance定义

            

            

            其他距离衡量:余弦值,相关度,曼哈顿距离。

import math
def ComputerEuclideanDistance(x1,y1,x2,y2):
    d=math.sqrt(math.pow((x1-x2),2)+math.pow((y1-y2),2))
    return d

d_ag=ComputerEuclideanDistance(3,104,18,90)
print(d_ag)

    

4.算法优缺点

    优点:

            简单,易于理解,容易实现,通过对K的选择可具备丢噪音数据的健壮性。

    缺点:

            

            需要大量空间储存所有已知实例。

            算法复杂度高(需要比较所有已知实例与要分类的实例)

            当其样本分布不平衡时,比如其中一类样本过大(实例数量过多)占主导的时候,新的未知实例容易被归类为这个主导样本,因为这类样本实例的数量过大,但这个新的未知实例实际并不接近目标样本。


5.改进版本

        考虑距离,根据距离加上权重

        比如:1/d(d:距离)


6.python中用sklearn调用knn算法

# -*- coding: utf-8 -*-

from sklearn import neighbors
from sklearn import datasets

knn=neighbors.KNeighborsClassifier()        #调用knn的分类器

iris=datasets.load_iris()       #返回datasets里面的一个数据库

print iris
knn.fit(iris.data,iris.target)      #建模,传入特征值矩阵,和类别矩阵
predictedLabel=knn.predict([[0.1,0.2,0.3,0.4]])
print predictedLabel


7.程序算法实现

# -*- coding: utf-8 -*-

import csv
import random
import math
import operator
from networkx.classes.function import neighbors

#装载数据集
def loadDataset(filename,split,trainingSet=[],testSet=[]):    #数据里面分成训练集和测试集
    with open(filename,'rb') as csvfile:
        lines=csv.reader(csvfile)   #按行内容读取
        dataset=list(lines)
        for x in range(len(dataset)-1):
            for y in range(4):
                dataset[x][y]=float(dataset[x][y])
            if random.random()<split:               #如果产生的随机值小于给定的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])           #取前k个距离
    return neighbors



#根据少数服从多数原则预测实例属于哪一类
def getResponse(neighbors):
    classVotes={}
    for x in range(len(neighbors)):
        response=neighbors[x][-1]       #-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'irisdata.txt',split,trainingSet,testSet) #字符串r的意思是把传入的字符串当做原始字符串,忽略里面特殊符号。
    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、付费专栏及课程。

余额充值