本文风格:以❤️简单易懂❤️的语言带你彻底搞懂KNN,了解什么是有监督学习算法。
认真看完这篇文章,彻底了解KNN、了解监督学习算法绝对是一样很简单的事情。
注:本篇文章非常详细,同时我也附加了Python代码,欢迎收藏后慢慢阅读。
本文主要介绍的有监督学习算法是KNN,后续会接着介绍决策树、线性回归等算法。
首先,第一个也是最主要的问题——KNN是如何对样本进行分类的呢?
它的本质是通过距离判断两个样本是否相似,如果距离够近就认为他们足够相似属于同一类别。
当然只对比一个样本是不够的,误差会很大,我们需要找到离其最近的 k 个样本,并将这些样本称之为「近邻」(nearest neighbor)。对这 k 个近邻,查看它们的都属于何种类别(这些类别我们称作「标签」 (labels))。
然后根据“少数服从多数,一点算一票”原则进行判断,数量最多的的标签类别就是新样本的标签类别。其中涉及到的原理是“越相近越相似”,这也是KNN的基本假设。
假设 X_test 待标记的数据样本,X_train 为已标记的数据集。
该算法的「距离」在二维坐标轴就表示两点之间的距离,计算距离的公式有很多。
我们常用欧拉公式,即“欧氏距离”。回忆一下,一个平面直角坐标系上,如何计算两点之间的距离?
应该不难会想起来吧,公式应该大致如下: d i s t a n c e ( A , B ) = ( x A − x B ) 2 + ( y A − y B ) 2 distance(A, B)=/sqrt[]{(x_A-x_B)^2+(y_A-y_B)^2} distance(A,B)=(xA−xB)2+(yA−yB)2那如果不是在一个平面直角坐标系,而是在立体直角坐标系上,怎么计算呢? d i s t a n c e ( A , B ) = ( x A − x B ) 2 + ( y A − y B ) 2 + ( z A − z B ) 2 distance(A, B)=/sqrt[]{(x_A-x_B)^2+(y_A-y_B)^2+(z_A-z_B)^2} distance(A,B)=(xA−xB)2+(yA−yB)2+(zA−zB)2那如果是n维空间呢? d i s t a n c e ( A , B ) = ( x 1 A − x 1 B ) 2 + ( x 2 A − x 2 B ) 2 + ( x 3 A − x 3 B ) 2 + . . . . . . + ( x n A − x n B ) 2 = ∑ i = 1 n ( x i A − x i B ) 2 distance(A, B)=/sqrt[]{(x_{1A}-x_{1B})^2+(x_{2A}-x_{2B})^2+(x_{3A}-x_{3B})^2+......+(x_{nA}-x_{nB})^2}=/sqrt[]{/sum_{i=1}^{n} {(x_{iA}-x_{iB})^2}} distance(A,B)=(x1A−x1B)2+(x2A−x2B)2+(x3A−x3B)2+......+(xnA−xnB)2=i=1∑n(xiA−xiB)2而在我们的机器学习中,坐标轴上的值 x 1 x_1 x1, x 2 x_2 x2 , x 3 x_3 x3 ,…… x n x_n xn正是我们样本数据上的 n 个特征。
算法参数是 k,k 可以理解为标记数据周围几个数作为参考对象,参数选择需要根据数据来决定。
默认情况下,在计算距离时,权重都是相同的,但实际上我们可以针对不同的邻居指定不同的距。离权重,比如距离越近权重越高。
使用一定半径内的点取代距离最近的 k 个点。
这里我还是先以上篇文章讲到的红酒分类为例子,待会还会有其他实例。
import numpy as npimport pandas as pdimport matplotlib.pyplot as plt# 解决坐标轴刻度负号乱码plt.rcParams["axes.unicode_minus"] = False# 解决中文乱码问题plt.rcParams["font.sans-serif"] = ["Simhei"]plt.style.use("ggplot")# plt.figure(figsize=(2,3),dpi=720)
首先随机设置十个样本点表示十杯酒,这里取了部分样本点。
为了方便验证,这里使用 Python 的字典 dict 构建数据集,然后再将其转化成 DataFrame 格式。
rowdata = {"颜色深度": [14.23,13.2,13.16,14.37,13.24,12.07,12.43,11.79,12.37,12.04], "酒精浓度": [5.64,4.38,5.68,4.80,4.32,2.76,3.94,3.1,2.12,2.6], "品种": [0,0,0,0,0,1,1,1,1,1]} # 0 代表 “黑皮诺”,1 代表 “赤霞珠” wine_data = pd.DataFrame(rowdata)wine_data
X = np.array(wine_data.iloc[:,0:2]) #我们把特征(酒的属性)放在X y = np.array(wine_data.iloc[:,-1]) #把标签(酒的类别)放在Y
我们先来画一下图。
#探索数据,假如我们给出新数据[12.03,4.1] ,你能猜出这杯红酒是什么类别么? new_data = np.array([12.03,4.1]) plt.scatter(X[y==1,0], X[y==1,1], color="red", label="赤霞珠") #画出标签y为1 的、关于“赤霞珠”的散点 plt.scatter(X[y==0,0], X[y==0,1], color="purple", label="黑皮诺") #画出标签y为0 的、关于“黑皮诺”的散点 plt.scatter(new_data[0],new_data[1], color="yellow") # 新数据点 new_data plt.xlabel("酒精浓度") plt.ylabel("颜色深度") plt.legend(loc="lower right") plt.savefig("葡萄酒样本.png")
讲道理,你应该一下就能看出来了。不过,如果是计算机,会这么分辨呢?
我们使用欧式距离公式,计算新数据点 new_data 与现存的 X 数据集每一个点的距离:
from math import sqrt distance = [sqrt(np.sum((x-new_data)**2)) for x in X ] distance
那现在,我们就已经得到黄点距离其它每个点的距离啦。
sort_dist = np.argsort(distance) # 这里是用到了argsort方法,可以返回数据对应的下标,如果直接用sort方法的话是返回打乱的数据,我们也不好区分对应是什么类别。sort_dist
array([6, 7, 1, 4, 5, 9, 2, 8, 3, 0], dtype=int64)
6、7、4为最近的3个“数据点”的索引值,那么这些索引值对应的原数据的标签是什么?
k = 3 topK = [y[i] for i in sort_dist[:k]] topK
[1,1,0]
这个时候我们就得到了离黄点最近的三个点对应的类别啦。
# 在numpy中有mean、median方法可以求平均数和中位数,不过没有方法直接求众数。pd.Series(topK).value_counts().index[0]
1
所以当我们的k取3时,分类结果为1,也就是赤霞珠。大家看一下是不是跟我们人脑分辨的结果是一样的呢?
那为了后续更好的操作,我们可以将上述过程封装成一个函数。
def KNN(new_data,dataSet,k): """ 函数功能:KNN分类器 参数说明: new_data: 需要预测分类的数据集 dataSet: 已知分类标签的数据集 k: k-近邻算法参数,选择距离最小的k个点 return: result: 分类结果 """ from math import sqrt from collections import Counter import numpy as np import pandas as pd result = [] distance = [sqrt(np.sum((x-new_data)**2)) for x in np.array(dataSet.iloc[:,0:2])] sort_dist = np.argsort(distance) topK = [dataSet.iloc[:,-1
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/119682.html
摘要:进入当前程序的学习系统的所有样本称作输入,并组成输入空间。结束语注意这篇文章仅仅是我接下来的机器学习系列的第一篇,后续还会有更多的内容。 往期回顾:统计学习方法第...
摘要:小栗子对于可乐来讲,只要是同一个品牌的可乐,他们就有着同样的成分,这被称之为配方。小栗子对于可乐来说,按照配方把可乐生产出来的过程就是实例化的过程。小栗子类的属性与正常的变量并无区别。 前言 我是栗子,带大家从零开始学习Python,希望每篇文章都能让你收获满满! 今天我们要说的是面向对象的...
阅读 3525·2021-09-22 10:52
阅读 1568·2021-09-09 09:34
阅读 1907·2021-09-09 09:33
阅读 737·2019-08-30 15:54
阅读 2571·2019-08-29 11:15
阅读 693·2019-08-26 13:37
阅读 1649·2019-08-26 12:11
阅读 2958·2019-08-26 12:00