机器学习之KNN算法的详解(附鸢尾花分类的代码实现)

机器学习13_KNN算法(2021.05.26)

by demo

一. 解惑
  • KNN算法的全名是什么?
    KNN算法(K-NearestNeighbor)也称邻近算法,或者说K最近邻分类算法,该算法是数据挖掘分类技术中最简单的方法之一。
  • 什么是KNN算法?
    KNN算法其实就是根据数据之间的相似度来进行分类。简单地说,KNN算法通过测量待分类目标与已知分类目标之间的距离来进行分类。(近朱者赤近墨者黑)
  • 待分类的目标到已知分类目标之间的距离是怎样计算的呢?
    使用欧几里得距离公式,将每个待分类目标的每个特征值和已知分类目标的每个特征值当作各自的坐标,从而根据每个相对应的特征值而算出待分类目标与已知分类目标之间的距离。·
    欧几里得公式:点此查看
  • KNN算法中的K值又是什么?
    在计算完待分类目标与全部已知分类目标之间的距离之后,就需要来选取哪些已知分类的目标作为分类参考了。K值其实就是用于选出待分类的目标的周围有几个已知分类的邻居,之后再根据这k个邻居中,相应的分类情况的占比来判断待分类目标的分类情况。(注:K值选取的不同将会导致KNN分类结果的不同,如下图所示,实线部分K的值就为3,圆的分类将被划分为三角;虚线部分K的值就为5,而圆的分类将会被划分为方块。)
    by demo
二. 举个例子让你更轻松地理解KNN — 如何使用KNN对电影的类别进行分类
  • 前提:这个例子只是简单地根据打斗镜头的数量和亲吻镜头的数量将电影分为了动作电影和爱情电影两类。
  • 问题点:对于动作片来说,动作片有哪些共有的特征,使得动作片之间非常类似,而与爱情片存在着明显的差别呢?相反来说,对于爱情片,是有哪些特征,使得爱情片之间非常类似,而与动作片存在着明显的差别呢?
  • 答案:其实就是 – 打斗镜头和亲吻镜头的出现的数量! 也就是说,动作片有着更多的打斗镜头,而爱情片则有着更多的亲吻镜头。因此,根矩这两种镜头的数量貌似可以将电影进行一次简单地分类。
    也就是可以将亲吻镜头数量和打斗镜头数量分别作为x轴和y轴,根据电影中亲吻镜头和打斗镜头出现的次数,可以将每一部电影放入到该二维坐标系中(详见下图)有了这些点之后,当一部未知分类的电影想要进行分类时,就可以按照这部电影的打斗镜头出现次数和亲吻镜头出现次数将其也放入之前建好的二维坐标系中,在这之后再与已知类型的电影的坐标求距离,根据距离的远近,以及根据K值大小选取邻居的数量,以及K个邻居中的电影分类比例,就可以大致推断出想要分类的电影的类型。
  • 图解
    1. 提取出已知分类电影中的亲吻、打斗镜头的次数
    by demo
    2..将每一部电影根据其亲吻和打斗镜头出现的次数写入坐标系中。
    by demo
    3. 计算待分类电影到已分类电影坐标点之间的距离
    by demo
    4. 假设定义K的值为3,根据坐标之间的距离可以轻松地判断出电影《?》的分类为爱情电影。
三. 代码实现真实示例(鸢尾花的分类)中使用KNN算法
import sklearn.datasets as datasets  # 导入数据库
from sklearn.neighbors import KNeighborsClassifier  # 导入KNN分类算法
from sklearn.model_selection import train_test_split  # 导入数据集划分器

# 1.捕获鸢尾花数据
iris = datasets.load_iris()

# 2.提取样本数据
feature = iris['data']  # 特征数据
target = iris['target']  # 目标数据

# 3.对数据集进行拆分
x_train, x_test, y_train, y_test = train_test_split(feature, target, test_size=0.2, random_state=2021)

# 4.观察数据集:检查是否需要进行特征工程的处理
print(x_train)  # 第一检查特征数据是否都是数值型数据(特征抽取),第二检查特征数据之间大小的差距(特征预处理),第三检查特征数据的维度(特征选择)  一般情况下从datasets中捕获的数据是不需要做特征工程的处理的

# 5.实例化模型对象(在KNN中k取值的不同会直接导致模型的分类结果的不同,因此k也可以被称为模型的超参数)
knn = KNeighborsClassifier(n_neighbors=3)  # n_neighbors == k

# 6.使用训练集数据训练模型(参数内容:训练集的特征数据以及训练集的标签数据,其中要求训练集的特征数据必须是二维的)
# print(x_train.shape) # (120, 4)
knn = knn.fit(x_train, y_train)
print(knn)  # 打印训练的结果

# 7.使用测试数据,测试模型(参数内容:测试集的特征数据)  .predict表示使用训练好的模型实现分类或者预测
y_pred = knn.predict(x_test)  # 模型基于测试数据返回的分类结果
y_true = y_test  # 测试集真实的分类结果
print('模型的分类结果:', y_pred)
print('真实的分类结果:', y_true)

# 8.预测、分类结果的评分
print(knn.score(x_test, y_test))  # 0.9666666666666667


# 结果 (29/30)
# 模型的分类结果: [0 0 1 0 0 0 0 0 0 0 0 1 2 2 1 2 1 1 0 1 1 2 2 0 2 1 1 2 0 0]
# 真实的分类结果: [0 0 1 0 0 0 0 0 0 0 0 1 2 2 1 2 1 1 0 1 1 2 2 0 2 1 1 1 0 0]

# 注:在改变k值(n_neighbors)之后,不论是分类预测的结果还是评分都会发生改变

# 当出现一个未知分类的鸢尾花时,对其的分类进行预测
test1 = knn.predict([[6.1, 3.1, 4.7, 2.1]])
print(test1)

# 结果 [2] , 也就是将该未知分类的鸢尾花分为了第二类鸢尾花

如有问题,敬请指正。欢迎转载,但请注明出处。
  • 9
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值