Python K近邻分析与应用

187 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

K近邻分析与应用

K近邻分类方法的基本思路是:不对预先的训练数据集进行任何处理,当测试一个新来的数据属于哪个类时,计算下它与训练集中所有实例的距离,从中选出K个距离最小(近)的实例,统计下这K个实例属于哪个类的最多,就将新来的数据归为哪一类。 谚语:“走路像鸭子,叫起来像鸭子,看起来像鸭子,那它很可能就是鸭子”。 举例来说,如果我们有下面的训练集,其中每个实例有5个属性,最后一列标出了它们属于哪一类?

编号 属性1 属性2 属性3 属性4 属性5 所属类 1 1.1 1.2 1.3 1.4 1.5 A 2 2.1 2.2 2.3 2.4 2.5 B 3 3.1 3.2 3.3 3.4 3.5 A 4 4.1 4.2 4.3 4.4 4.5 A 5 5.1 5.2 5.3 5.4 5.5 B

假设现在有一个新数据(2.11,2.21,2.22,2.23,2.24,2.25),我们取K = 3,在训练集中与它距离最近的三个实例肯定是实例1,2,3,其中两个属于A类,一个属于B类,那我们就将新数据归为A类。

Code

# -*- coding: utf-8 -*-
import csv
import random
import math
import operator
import numpy as np

def loadDataset(filename,split,trainingSet=[],testSet=[]):
    with open(filename,'r') as csvfile:
        lines = csv.reader(csvfile)
        dataset = list(lines)
        for x in range(len(dataset)-1):
            for y in range(np.array(dataset).shape[1]):
                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 distance

def getNeighbors(trainingSet,testInstance,k):
    distance=[]
    length = len(testInstance)-1
    for i in range(len(trainingSet)):
        dist = euclideanDistance(testInstance, trainingSet[i], length)#求每个训练样本的距离
        distance.append((trainingSet[i],dist))#将元组(每个训练数据,与测试数据的欧几里德距离)添加到距离集合
    distance.sort(key=operator.itemgetter(1))#进行升序排序
    neighbors=[]
    for i in range(k):
        neighbors.append(distance[i][0])#取k个与测试样本的最短距离
    return neighbors

def getResponse(neighbors):
    classVotes = {}
    for i in range(len(neighbors)):#分别统计k个最短距离的类别,取类别出现次数最多的
        response=neighbors[i][-1]
        if response in classVotes:
            classVotes[response]+=1
        else:
            classVotes[response]=1
    sortedVotes=sorted(classVotes.items(),key=operator.itemgetter(1),reverse=True)#进行降序排序
    return sortedVotes[0][0]

def getAccuracy(testSet,predictions):#求准确率
    correct = 0                      #由于每次测试集的样本是随机划分的,每次准确率也不是固定的
    for i in range(len(testSet)):
        if testSet[i][-1] == predictions[i]:
            correct +=1
    return (correct/float(len(testSet)))*100.0

def main():
    trainingSet=[]
    testSet=[]
    split=0.85
    loadDataset(r'C:\Users\lndx\Desktop\knn_data.csv', split,trainingSet,testSet)
    print('Train set:'+repr(len(trainingSet)))
    print('Test set:'+repr(len(testSet)))
    predictions=[]
    k=5
    for i in range(len(testSet)):
        neighbors = getNeighbors(trainingSet, testSet[i], k)
        result = getResponse(neighbors)
        predictions.append(result)
        print('prediction='+repr(result)+',actual='+repr(testSet[i][-1]))
    accuracy = getAccuracy(testSet, predictions)
    print('Accuracy:'+repr(accuracy)+'%')

if __name__ =='__main__':
    main()


结果 在这里插入图片描述