- K-近邻算法(KNN)概述
这是分类算法的其中一种,基本思想就是给定一组训练数据或者叫已有数据,每条数据由几个特征值+分类组成,比如很有名的iris数据集,很多地方都可以下载到。前面四个参数是花萼花瓣的长宽,最后一个是所属的花种,数据集里包含了150个采集的数据。
我们的问题就在于如果给出一组新的参数,比如[7.2, 3.6, 5.1, 2.5],那么需要判断他属于哪个种类
算法的基本思想也很简单,就是拿新的参数去跟150个已有参数组做比较,分别得出差别值,差别值越小越排前面。
然后就是K发挥作用了,我们要预设一个K的值(一般是不大于20的整数),意思就是取前K个相似的参数组,然后统计这些参数组里哪个种类占多数,也就意味着我们的新参数是符合哪个种类的。
比如按下图理解,红色三角代表种类setosa,蓝色方块是versicolor,我们新的参数组是绿色小圆圈。这些图形和绿色小圆圈的距离就代表了他们的相似程度,越近越相似。
如果我们选择K=3,那么中间实线圈里就是被选上的三个参数组,红色三角有两个,占多数,那么我们就预测这个绿色小圆圈应该是红色三角。
K=5的时候就扩展到了虚线部分,蓝色方块占了多数,我们的预测就变成了蓝色方块versicolor
那么现在还有一个没解决的问题,怎么计算相似程度?我们一般用欧式距离或者曼哈顿距离。
都是去算每个参数之间的差别,再和起来
- Python实现基于iris数据集的分类算法
再概括一下上面说的算法:
a. 分别计算测试数据与各个训练数据之间的距离(欧氏距离)
b. 把这些距离按升序排序
c. 选取距离最小的K个点
d. 统计这K个点里面各种类型出现的次数
e. 返回出现频率最高的种类作为预测分类
python代码如下,选择的测试数据是[7.2, 3.6, 5.1, 2.5], 选取的K是5
import pandas as pd
import numpy as np
import math
import operator
# Import data
data = pd.read_csv("iris.csv")
print(data.head())
# Calculate Euclidean distance
def euclideanDistance(data1, data2, length):
distance = 0
for x in range(length):
distance += np.square(data1[x+1] - data2[x][0])
return np.sqrt(distance);
# Apply KNN algorithm
def knn(trainingSet, testInstance, k):
distances = {}
sort = {}
print(testInstance.shape)
length = testInstance.shape[1]
print(length)
for x in range(len(trainingSet)):
dist = euclideanDistance(trainingSet.iloc[x], testInstance, length)
distances[x] = dist
print(distances.items())
sort = sorted(distances.items(), key=lambda item:item[1])
neighbors = []
for x in range(k):
neighbors.append(sort[x][0])
classVotes = {}
for x in range(len(neighbors)):
response = trainingSet.iloc[neighbors[x]][-1]
if response in classVotes:
classVotes[response] += 1
else:
classVotes[response] = 1
sortedVotes = sorted(classVotes, key = operator.itemgetter(1), reverse=True)
return (sortedVotes[0], neighbors)
# Testing Block
testSet = [[7.2, 3.6, 5.1, 2.5]]
test = pd.DataFrame(testSet)
print(test)
k = 5
result, neighbor = knn(data, test, k)
print(result)
print(neighbor)