KNN算法的python实现

1. 处理数据

# filename:文件路径  trainingSet:训练集  testSet:测试集 训练数据集数据量/测试数据集数据量的比值取67/33是一个经常使用的惯例。
def loadDataset(filename,split,trainingSet=[], testSet=[]):
    with open(filename,'r') as csvfile: #使用open方法打开文件
        lines = csv.reader(csvfile) #使用csv模块读取数据
        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:
            #random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0。
            #随机地切分训练数据集和测试数据集。训练数据集数据量/测试数据集数据量的比值取67/33是一个经常使用的惯例,因此split取值通常为0.66
                trainingSet.append(dataset[x])
            else:
                testSet.append(dataset[x])

测试代码算法

trainingSet=[]
testSet=[]
loadDataset('iris.data',0.66,trainingSet,testSet)
print('trainingSet',repr(len(trainingSet)))
print('testSet',repr(len(testSet)))

2. 类似度

咱们须要计算两个数据之间的类似度,便于获取最类似的N个实例来作出预测。数组

由于有关花的四个测量维度的数据都是数字形式的,而且具备相同的单位。咱们能够直接使用欧式距离来测量。app

二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离: 输入图片说明dom

# length:告诉函数前几个维度须要处理,忽略后面的维度
def euclideanDistance(instance1,instance2,length):
    distance = 0
    for x in range(length):
        distance += pow((instance1[x]-instance2[x]),2) #全部须要计算的维度距离相加
    return math.sqrt(distance)

测试代码:ide

data1 = [2,2,2,'a']
data2 = [4,4,4,'b']
# length=3只计算前面三个维度
distance = euclideanDistance(data1,data2,3)
print('distance',repr(distance))

3. 邻近类似度

有了类似度计算的方法,咱们能够获取与须要预测的数据最接近的N个数据实例了。函数

最直接的方法就是计算待预测数据到全部数据实例的距离,取其中距离最小的N个。测试

# testInstance:待预测数据
def getNeighbors(trainingSet, testInstance, k):
    distances = []
    length = len(testInstance)-1
    for x in range(len(trainingSet)):
        #testinstance
        dist = euclideanDistance(testInstance, trainingSet[x], length)
        distances.append((trainingSet[x], dist))
        #distances.append(dist)
    distances.sort(key=operator.itemgetter(1))
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
        return neighbors

测试代码:idea

trainSet = [[2,2,2,'a'],[4,4,4,'b']]
testInstance = [5,5,5]
k = 1
neighbors = getNeighbors(trainSet,testInstance,k)
print(neighbors)

测试结果(邻近元素): [[4, 4, 4, 'b']]code

4. 结果

接下来的任务就是基于最近的几个实例来获得预测结果了。图片

咱们能够让这些邻近元素来对预测属性进行投票,得票最多的选项做为预测结果

下面这个函数实现了投票的逻辑,它假设需预测的属性放在数据实例(数组)的最后。

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.items(), key=None, reverse=True)
    return sortedVotes[0][0] #

测试代码:

neighbors= [[1,1,1,'a'],[2,2,2,'a'],[3,3,3,'b']]
response = getResponse(neighbors)
print(response)

5. 准确度

简单的评估方法:计算在测试数据集中算法正确预测的比例,这个比例叫分类准确度。

# 假设predictions为测试集的预测结果集
def getAccuracy(testSet, predictions):
    correct = 0
    for x in range(len(testSet)):
        if testSet[x][-1] is predictions[x]:
            correct += 1
    return (correct/float(len(testSet))) * 100.0

测试代码:

testSet = [[1,1,1,'a'],[2,2,2,'a'],[3,3,3,'b']]
predictions = ['a','a','a']
accuracy = getAccuracy(testSet,predictions)
print(accuracy)
相关文章
相关标签/搜索