一、KNN算法简介
1.1、定义
KNN(K-Nearest Neighbor)算法是一种基于实例的学习方法,通过测量数据点之间的间隔进行分类或回归分析。它是一种简单易懂的多分类技术,依赖于间隔近来的邻人来推断数据点的类别或数值,为许多现实应用提供了有效的办理方案。
k-近邻算法
邻近算法,大概说K近来邻(K-Nearest Neighbor,KNN)分类算法是数据发掘分类技术中最简单的方法之 一,是闻名的模式辨认统计学方法,在呆板学习分类算法中占据相当大的职位。它是一个理论上比较成 熟的方法。既是最简单的呆板学习算法之一。
所谓K近来邻,就是k个近来的邻人的意思,说的是每个样本都可以用它最靠近的k个邻人来代表。Cover 和Hart在1968年提出了最初的邻近算法。
KNN是一种分类(classification)算法,它输入基于实例的学习 (instance-based learning),属于懒惰学习(lazy learning)即KNN没有显式的学习过程,也就是说 没有训练阶段,数据集事先已有了分类和特征值,待收到新样本后直接进行处理处罚。与急切学习(eager learning)相对应。
KNN是一种惰性学习算法,它是基于实例的,并没有颠末大量的训练来学习模子大概特征,而是仅仅记 住了须要训练的干系实例,KNN是监督学习的一种。
KNN是给定测试实例,基于某种间隔度量找出训练会合与其最靠近的k个实例点,然后基于这k个近来邻 的信息来进行预测,简言之,须要预测的实例与哪一类离得更近,就属于哪一类。
1.2、原理
KNN算法的原理可以用“近朱者赤,近墨者黑”来概括,它是一种基于实例的学习方法,属于懒惰学习,因为没有显式的训练过程。KNN通过测量待预测样本与训练数据会合近来的K个样本之间的间隔来进行分类或回归分析。
在分类问题中,通过投票决定待预测样本的类别;
而在回归问题中,则盘算这K个样本的匀称值作为最终的预测结果。
1.3、特点
KNN算法简单易懂,易于实现;
无需训练阶段,直接进行分类或回归;
实用于多分类问题;
对数据集的大小和维度不敏感。
二、决策界限
2.1、定义
决策界限是分类算法中用于区分不同类别的虚拟边 界,即上一章节所指出的“房间”。
2.2、界限效果
决策界限是否合理,直接影响到分类效果的好坏。
2.3、KNN与决策界限
KNN算法通过盘算待分类样本与已知样本之间的距 离,找到近来的k个样本,并根据这些样本的类别 信息进行投票,以确定待分类样本的类别。
三、KNN的决策界限盘算
决策界限盘算
导入模块
- from sklearn.neighbors import KNeighborsClassifier
- import numpy as np
- from matplotlib import pyplot as plt
复制代码 定义数据集
- #定义数据集
- point1 = [[7.7, 6.1], [3.1, 5.9], [8.6, 8.8], [9.5, 7.3], [3.9, 7.4], [5.0, 5.3], [1.0, 7.3]]
- point2 = [[0.2, 2.2], [4.5, 4.1], [0.5, 1.1], [2.7, 3.0], [4.7, 0.2], [2.9, 3.3], [7.3, 7.9]]
- point3 = [[9.2, 0.7], [9.2, 2.1], [7.3, 4.5], [8.9, 2.9], [9.5, 3.7], [7.7, 3.7], [9.4, 2.4]]
- #特征合并
- np_train_data=np.concatenate(np.array((point1,point2,point3)),axis=0)
- #创建标签
- np_train_label=np.array([0]*7+[1]*7+[2]*7)
复制代码 构建KNN算法:实例化KNN算法,KNN训练
- knn_clf=KNeighborsClassifier(3)
- knn_clf.fit(np_train_data,np_train_label)
复制代码 设定未知点,设定坐标点网络
- x=np.linspace(0,10,100)
- y=np.linspace(0,10,100)
- x0,y0=np.meshgrid(x,y)
- axis_xy=np.c_[x0.ravel(),y0.ravel()]
复制代码 KNN的预测与绘制决策界限
- y_predict=knn_clf.predict(axis_xy)
- y_predit=y_predict.reshape(x0.shape)
- plt.contour(x0,y0,y_predit)
- plt.scatter(np_train_data[np_train_label==0,0],np_train_data[np_train_label==0,1],marker='^')
- plt.scatter(np_train_data[np_train_label==1,0],np_train_data[np_train_label==1,1],marker='*')
- plt.scatter(np_train_data[np_train_label==2,0],np_train_data[np_train_label==2,1],marker='s')
- plt.show()
复制代码 完整代码
- from sklearn.neighbors import KNeighborsClassifier # 从 scikit-learn 导入 K 最近邻分类器
- import numpy as np # 导入 NumPy 库以进行数组操作
- from matplotlib import pyplot as plt # 从 matplotlib 导入 pyplot 用于绘图
- # 定义数据集
- point1 = [[7.7, 6.1], [3.1, 5.9], [8.6, 8.8], [9.5, 7.3], [3.9, 7.4], [5.0, 5.3], [1.0, 7.3]] # 类别 0
- point2 = [[0.2, 2.2], [4.5, 4.1], [0.5, 1.1], [2.7, 3.0], [4.7, 0.2], [2.9, 3.3], [7.3, 7.9]] # 类别 1
- point3 = [[9.2, 0.7], [9.2, 2.1], [7.3, 4.5], [8.9, 2.9], [9.5, 3.7], [7.7, 3.7], [9.4, 2.4]] # 类别 2
- # 特征合并
- np_train_data = np.concatenate(np.array((point1, point2, point3)), axis=0) # 将三个类别的数据组合成一个训练数据集
- # 创建标签
- np_train_label = np.array([0] * 7 + [1] * 7 + [2] * 7) # 创建对应每个数据点的标签
- # 构建 KNN 算法,实例化,KNN 训练
- knn_clf = KNeighborsClassifier(3) # 创建 KNN 分类器,k=1 表示考虑最近的一个邻居
- knn_clf.fit(np_train_data, np_train_label) # 使用训练数据和标签来训练 KNN 模型
- # 定义未知点坐标网格
- x = np.linspace(0, 10, 100) # 创建 x 坐标的线性空间,从 0 到 10,包含 100 个点
- y = np.linspace(0, 10, 100) # 创建 y 坐标的线性空间,从 0 到 10,包含 100 个点
- x0, y0 = np.meshgrid(x, y) # 创建二维网格坐标
- axis_xy = np.c_[x0.ravel(), y0.ravel()] # 将网格坐标展平,以便于预测
- # KNN 的预测绘制决策边界
- y_predict = knn_clf.predict(axis_xy) # 对所有未知点进行分类预测
- y_predit = y_predict.reshape(x0.shape) # 将预测结果按原网格形状排列
- # 绘制决策边界
- plt.contour(x0, y0, y_predit) # 绘制决策边界
- plt.scatter(np_train_data[np_train_label == 0, 0], np_train_data[np_train_label == 0, 1], marker='^') # 绘制类别 0 的点
- plt.scatter(np_train_data[np_train_label == 1, 0], np_train_data[np_train_label == 1, 1], marker='*') # 绘制类别 1 的点
- plt.scatter(np_train_data[np_train_label == 2, 0], np_train_data[np_train_label == 2, 1], marker='s') # 绘制类别 2 的点
- plt.show() # 显示绘图结果
复制代码 K值选择
在KNN中,须要人为选择不同的K的不同取值,这 个参数是须要人为选择的。须要人为确定的参数称 为超参数(hyperparameter)。
选择太小:
优点:复杂的数据集,K值较小可能会提供更详细 的决策界限,因为模子更加机动。
缺点:容易受到局部布局的影响,模子对噪声和异 常值的影响更大。
选择太大:
优点:思量了更多的全局信息,对于平滑的数据集, 较大的K值可以提供更稳固的决策界限。
缺点:对于复杂的数据集,较大的K值可能会导致 模子过于简单,无法准确捕捉数据的局部特征。
四、交叉验证
步调
1、预备数据集:
预备好包罗特征和标签的 数据集。
2、K折交叉验证:
确定K的值,比方选择5或7 作为K值。
3、划分数据集:
将数据集划分为K个大小相似的子集
4、循环训练和评估:
使用K-1个子集作为训练集, 剩余的1个子集作为测试集。 在训练集上训练KNN模子。 使用训练好的模子对测试集进 行预测。 使用性能指标评估。
5、盘算匀称性能:
将K次验证的性能指标取 匀称值,作为KNN模子的 最终性能评估。
6、选择最佳K值:
可以尝试不同的K值,并 通过交叉验证选择性能最 好的K值。然后选择在交 叉验证中表现最佳的K值。
7、选定最终K值:
使用选择的最佳K值,在整 个训练集上重新训练KNN 模子,以获得最终的模子。
五、库函数
5.1、KNeighborsClassifier()
是 scikit-learn 库中的一个分类模子实现,属于 K 近来邻(KNN)算法。该模子通过盘算输入数据点与训练数据会合每个点的间隔,找出近来的 K 个邻人,来进行分类预测。
- class sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, *, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=None)
复制代码 方法形貌n_neighbors 默认值 = 5
默认环境下用于查询的邻人数。
weights 预测中使用的权重函数。可能的值:
- 'uniform' :匀称的权重。每个邻域中的所有点 的权重相等。
- 'distance' :按间隔的倒数对点进行加权。 在这种环境下,查询点的近邻将具有 比间隔较远的邻人有更大的影响力。
- [callable] :一个用户定义的函数,它接受 间隔数组,并返回相同形状的数组 包罗权重。
algorithm 用于盘算近来邻的算法:
- 'ball_tree' 将使用
- 'kd_tree' 将使用
- 'brute' 将使用暴力搜索。
- 'auto' 将尝试决定最合适的算法 基于传递给 method 的值。
注意:拟合稀疏输入将覆盖 this 参数,使用蛮力。
leaf_size传递给 BallTree 或 KDTree 的叶大小。这可能会影响 构造和查询的速率以及内存 须要来存储树。最佳值取决于 问题的性质。pMinkowski 度量的 Power 参数。当 p = 1 时,这是等效的 使用 manhattan_distance (L1) 和 euclidean_distance (L2) 表现 p = 2。 对于任意 p,使用 minkowski_distance (l_p)。此参数是预期的 要积极。metric 用于间隔盘算的公制。默认值为 “minkowski”,它 当 p = 2 时,得到标准欧几里得间隔。请参阅 scipy.spatial.distance 和 Valid metric 中列出的量度 值。
如果度量是“预先盘算的”,则假定 X 是一个间隔矩阵,而且 拟适时必须为方形。X 可以是稀疏图,其中 只有 “nonzero” 元素才能被视为邻人。
如果 metric 是一个可调用函数,它须要两个表现 1D 的数组 vectors 作为输入,而且必须返回一个表现间隔 在这些向量之间。这实用于 Scipy 的指标,但效果较弱 服从高于将指标名称作为字符串传递。
metric_paramsmetric 函数的其他关键字参数。n_jobs要为邻人搜索运行的并行作业数。 表现 1,除非在上下文中。 表现使用所有处理处罚器。有关更多详细信息,请参阅 术语表 。 不影响 method。None-1 5.2、concatenate()
是 NumPy 库中的一个函数,用于将两个或多个数组沿特定轴(通常是行或列)合并。
- numpy.concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind")
复制代码 方法形貌a1, a2, …数组必须具有相同的形状,但维度 对应于 axis (默认环境下是第一个)。axis数组将沿其连接的轴。如果 axis 为 None,则 数组在使用前被展平。默认值为 0。out如果提供,则为放置结果的目标。形状必须为 correct,匹配 concatenate 在 no out 参数。dtype如果提供,目标数组将具有此 dtype。不能 与 out 一起提供。casting控制可能发生的数据范例转换。默认为 'same_kind'。 有关选项的形貌,请参阅铸造。 - import numpy as np
- array1 = np.array([[1, 2], [3, 4]])
- array2 = np.array([[5, 6], [7, 8]])
- result = np.concatenate((array1, array2), axis=0) # 沿行合并
- # result: [[1, 2], [3, 4], [5, 6], [7, 8]]
复制代码 5.3、meshgrid()
是 NumPy 函数,用于天生二维网格坐标,通常用于函数画图或参数化曲面画图。meshgrid 接受两个一维数组(通常为 x 和 y 轴的坐标),并返回两个矩阵,分别表现每个坐标点的 x 和 y 值。
- numpy.meshgrid(*xi, copy=True, sparse=False, indexing='xy')
复制代码 方法形貌x1, x2,…, xn表现网格坐标的 1-D 数组。indexing输出的笛卡尔 ('xy', default) 或矩阵 ('ij') 索引。 有关更多详细信息,请参阅 Notes。sparse 如果为 True,则返回的维度 i 坐标数组的形状将从 淘汰到 。这些稀疏坐标格网是 旨在与 Broadcasting 一起使用。当所有 坐标,则广播仍然会导致 全尺寸结果数组。(N1, ..., Ni, ... Nn)(1, ..., 1, Ni, 1, ..., 1)
默认值为 False。
copy如果为 False,则返回原始数组的视图,以便 节省内存。默认值为 True。请注意,可能会返回非连续的 阵 列。此外,广播数组的多个元素 可能是指单个内存位置。如果须要写入 数组中,请先制作副本。sparse=False, copy=False - import numpy as np
- x = np.linspace(0, 5, 5) # x 轴的线性空间
- y = np.linspace(0, 5, 5) # y 轴的线性空间
- X, Y = np.meshgrid(x, y) # 生成网格坐标
- # X, Y: 网格中的每个点的坐标
- '''
- (array([[0. , 1.25, 2.5 , 3.75, 5. ],
- [0. , 1.25, 2.5 , 3.75, 5. ],
- [0. , 1.25, 2.5 , 3.75, 5. ],
- [0. , 1.25, 2.5 , 3.75, 5. ],
- [0. , 1.25, 2.5 , 3.75, 5. ]]),
- array([[0. , 0. , 0. , 0. , 0. ],
- [1.25, 1.25, 1.25, 1.25, 1.25],
- [2.5 , 2.5 , 2.5 , 2.5 , 2.5 ],
- [3.75, 3.75, 3.75, 3.75, 3.75],
- [5. , 5. , 5. , 5. , 5. ]]))
- '''
复制代码 5.4、ravel()
是 NumPy 的一个方法,用于将多维数组展平为一维数组。它返回一个连续的一维数组,表现原数组中的所有元素。与 flatten 方法不同的是,ravel 返回的是原数组的视图,不会复制数据。
- numpy.ravel(a, order='C')
复制代码 方法形貌aInput 数组。a 中的元素按照 order 指定的顺序读取,并打包为 1-D 数组。order使用此索引顺序读取 a 的元素。“C” 表现 以行优先、C 样式顺序为元素体例索引, 最后一个轴索引变化最快,返回到第一个 轴索引变化最慢。'F' 表现为元素体例索引 以 column-major、Fortran 样式的顺序,使用 第一个索引更改最快,最后一个索引更改 慢。请注意,'C' 和 'F' 选项不思量 底层数组的内存布局,而且仅引用 轴索引的顺序。“A” 表现读取 如果 a 是 Fortran 连续的,则为雷同 Fortran 的索引顺序 memory,否则雷同 C 的顺序。'K' 表现读取 元素(按它们在内存中出现的顺序排列),但 当步幅为负数时反转数据。默认环境下,'C' 使用索引顺序。 - import numpy as np
- array = np.array([[1, 2, 3], [4, 5, 6]])
- flattened = array.ravel() # 将二维数组展平为一维
- # flattened: [1, 2, 3, 4, 5, 6]
复制代码 5.5、contour()
是 Matplotlib 画图库中的一个函数,用于绘制等高线图,显示一个二维数组的值在平面上的分布。常用于可视化函数的值在不同坐标下的变化。
- contour(X, Y, Z, levels=None, **kwargs)
复制代码 方法形貌X, Y坐标网格的矩阵,通常由 meshgrid 天生。Z X 和 Y 有关的值矩阵,决定绘制哪条等高线levels可选参数,指定要绘制的等高线的高度值。如果不提供,函数会自动选择kwargs其他可选参数,用于控制线条样式、颜色、标签等,比方 colors、linestyles、alpha(透明度)等 - import matplotlib.pyplot as plt
- import numpy as np
- x = np.linspace(-3.0, 3.0, 100)
- y = np.linspace(-3.0, 3.0, 100)
- X, Y = np.meshgrid(x, y)
- Z = np.sin(np.sqrt(X**2 + Y**2)) # 计算 Z 值
- plt.contour(X, Y, Z) # 绘制等高线
- plt.colorbar() # 添加色条
- plt.show()
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |