1、KNN的例子
转换为坐标:
红色是爱情片、蓝色是动作片、黑色是需要判断的点。
1.1 KNN具体的做法:
其中,欧式距离(欧几里得距离)的计算方法:
2、KNN的缺点
3、KNN的实现
# -*- coding: utf-8 -*- #
"""
-------------------------------------------------------------------------------
FileName: knn_algorithm
Author: newlinfeng
Date: 2020/8/2 0002 14:57
Description: 使用python实现knn算法
-------------------------------------------------------------------------------
"""
import matplotlib.pyplot as plt
import numpy as np
import operator
#已知分类的数据
x1 = np.array([3, 2, 1])
y1 = np.array([104, 100, 81])
x2 = np.array([101, 99, 98])
y2 = np.array([10, 5, 2])
scatter1 = plt.scatter(x1, y1, c='r')
scatter2 = plt.scatter(x2, y2, c='b')
#未知数据
x = np.array([18])
y = np.array([90])
scatter3 = plt.scatter(x, y, c='k')
#画图例
plt.legend(handles=[scatter1, scatter2, scatter3], labels=['labelA', 'labelB', 'X'], loc='best')
plt.show()
#已知分类的数据
x_data = np.array([[3, 104],
[2, 100],
[1, 81],
[101, 10],
[99, 5],
[81, 2]])
y_data = np.array(['A', 'A', 'A', 'B', 'B', 'B'])
x_test = np.array([18, 90])
#计算样本数量
x_data_size = x_data.shape[0]
#复制x_test,在行的方向将x_test的数据复制了6次
# np.tile(x_test, (x_data_size, 1))
#计算x_test与每一个样本的差值
diffMat = np.tile(x_test, (x_data_size, 1)) - x_data
#对这六组数据再分别进行计算差值的平方
sqDiffMat = diffMat**2
#对这六组数据再分别进行求和,axis=1表示对每一行的数据进行求和
sqDistances = sqDiffMat.sum(axis=1)
#对这六个数据再分别进行开方
distances = sqDistances**0.5
print(distances)
#把数据的索引进行大小的编号
sortedDistances = distances.argsort()
classCount = {}
#设置k
k = 5
for i in range(k):
#获取标签
votelabel = y_data[sortedDistances[i]]
#统计标签数量
classCount[votelabel] = classCount.get(votelabel, 0) + 1
#根据operator.itemgetter(1)-第一个值对classCount排序,然后再取倒序
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
#获取数量最多的标签
knnclass = sortedClassCount[0][0]
print(knnclass)
4、使用KNN做Iris的分类
使用knn实现鸢尾花的分类:
# -*- coding: utf-8 -*- #
"""
-------------------------------------------------------------------------------
FileName: knn_iris
Author: newlinfeng
Date: 2020/8/2 0002 20:58
Description: 使用knn算法来对iris数据集进行分类
-------------------------------------------------------------------------------
"""
#导入算法包以及数据集
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report,confusion_matrix
import operator
import random
def knn(x_test, x_data, y_data, k):
#计算样本数量
x_data_size = x_data.shape[0]
#复制x_test
np.tile(x_test, (x_data_size, 1))
#计算x_test与每一个样本的差值
diffMat = np.tile(x_test, (x_data_size, 1))-x_data
#计算差值的平方
sqDiffMat = diffMat**2
#求和
sqDistances = sqDiffMat.sum(axis=1)
#开方
distances = sqDistances**0.5
#从小到大排序
sortedDistances = distances.argsort()
classCount = {}
for i in range(k):
#获取标签
votelabel = y_data[sortedDistances[i]]
#统计标签数量
classCount[votelabel] = classCount.get(votelabel, 0) + 1
#根据operator.itemgetter(1)-第1个值对classCount排序,然后再取倒序
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
#获取数量最多的标签
return sortedClassCount[0][0]
#载入数据
iris = datasets.load_iris()
#x_train,x_test,y_train,y_test=train_test_split(iris.data, iris.target.test_size=0.2)#分割数据0.2为测试数据,0.8为训练数据
#打乱数据
data_size = iris.data.shape[0] #计算一下,iris中一共有多少数据
index = [i for i in range(data_size)] #得到一个list,从0开始,到data_size-1结束
random.shuffle(index)
iris.data = iris.data[index]
iris.target = iris.target[index]
#切分数据集
test_size = 40 #设置测试集的个数为40个
x_train = iris.data[test_size:] #从第40个开始设置为训练集
x_test = iris.data[:test_size] #0——40设置为测试集
y_train = iris.target[test_size:] #标签也是一样
y_test = iris.target[:test_size]
predictions = []
for i in range(x_test.shape[0]):
predictions.append(knn(x_test[i], x_train, y_train, 5))
print(classification_report(y_test, predictions))
print(confusion_matrix(y_test, predictions))
2020-08-10 更新