机器学习笔记3-k近邻法

机器学习笔记3-k近邻法

k近邻法输入为实例的特征向量,对应于特征空间中的点;输出为实例的类别。分类时,会根据其k个最近邻的训练实例的类别,通过多数表决等方式进行预测。因此,k近邻法不具有显示的学习过程。它包括三个基本要素:k值的选择、距离度量以及分类决策规则。

  • k值的选择会对算法结果产生重要影响。当选择较小的k值时,只有与实例点较近的训练实例会对预测结果起作用,近似误差会减小。但预测结果会对近邻的训练实例非常敏感,估计误差会增大。如果邻近训练实例恰好是噪声,预测就会出错。换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合;如果选择较大的k值,可以减少学习的估计误差,但近似误差会增大。这时与实例较远的训练实例也会对预测起作用。k值的增大意味着模型变得简单。在应用中,k值一般取一个比较小的数值,可以用grid_search来找一个最佳k值。
  • 距离度量,能反映出特征空间中两个实例点的相似程度。这里距离一般用欧式距离,也可以用更一般的 L p L_p Lp距离。 L p ( x i , x j ) = ( ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ p ) 1 p {L_p}({x_i},{x_j}) = {\left( {\sum\limits_{l = {\rm{1}}}^n {{{\left| {x_i^{{\rm{(}}l{\rm{)}}} - x_j^{{\rm{(}}l{\rm{)}}}} \right|}^p}} } \right)^{\frac{{\rm{1}}}{p}}} Lp(xi,xj)=(l=1nxi(l)xj(l)p)p1这里 p ≥ 1 p \ge 1 p1。当 p = 2 p=2 p=2时,为欧氏距离;当 p = 1 p=1 p=1时,为曼哈顿距离;当 p = ∞ p=\infty p=时,为各个坐标距离的最大值。
  • 分类决策规则一般会采用多数表决

k近邻法的实现:kd树
k近邻法最简单的实现方法是线性扫描,这时要计算实例与每个训练实例的距离。这种方法非常耗时。为了提高算法效率,可以用特殊的结构存储训练数据,进而基于这个数据结构进行搜索。比如构建kd树的方法。kd树有点类似于二叉搜索树,两者都满足对于一个根节点,其值不小于左子树的任何节点,且不大于右子树的任何节点。所不同的是构造过程,kd树是基于 R n R^n Rn空间,会直接对特征空间每一维进行划分;二叉搜索树是将元素一个一个添加的过程,与堆的构建一样。

  1. 如何构造kd树
    输入:k维空间数据集T={ x 1 , x 2 . . . x n x_1,x_2...x_n x1,x2...xn},其中 x i = ( x i ( 1 ) , x i ( 2 ) , ⋯   , x i ( k ) ) T {x_i} = {(x_i^{(1)},x_i^{(2)}, \cdots ,x_i^{(k)})^T} xi=(xi(1),xi(2),,xi(k))T
    (1)选择 x ( 1 ) x^{(1)} x(1)为坐标轴,以T中所有实例的 x ( 1 ) x^{(1)} x(1)坐标的中位数为切分点(根结点),将 x ( 1 ) x^{(1)} x(1)这一维分成两个子树,左子树对应坐标 x ( 1 ) x^{(1)} x(1)小于根节点的坐标,右子树对应坐标 x ( 1 ) x^{(1)} x(1)大于根节点的坐标。
    (2)重复:对深度为 j j j的结点,选择 x ( l ) x^{(l)} x(l)这一维进行切分, l = j / / k + 1 l=j//k+1 l=j//k+1,以 x ( l ) x^{(l)} x(l)这一维的中位数作为切分点(根结点),将该结点所包含的数据集划分到左右两个子树中。
    (3)直到所有叶结点只包括一个样本,则停止划分。
  2. 如何搜索kd树
    从根结点出发,向下访问kd树。若目标点当前维的坐标小于切分点的坐标,则移动到左子结点,否则移到右子结点,直到子结点为叶结点。以此叶结点为当前最近点,递归地向上回退,在每个结点进行以下操作:
    (1)若该结点保存的实例点距离目标点更近,则以该实例点为当前最近点
    (2)检查该结点的另一子结点所包含的数据集是否有更近的点。如果有,则移到该子结点区域递归地进行最近邻搜索,否则向上回退
    (3)当回退到根结点,搜索结束。(此处写的比较粗糙,具体可参考李航《统计学习方法》,从划分区域和球体相交的角度更好理解)

在python的机器学习库scikit-learn中,有能直接拿来用的knn函数KNeighborsClassifier,其参数n_neighbors即为k值。以下是利用KNeighborsClassifier实现的一小段代码,数据集是sklearn中的内置数据集:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.neighbors import KNeighborsClassifier 

iris = load_iris()
x, y = iris.data, iris.target
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25,random_state=33)
scaler=preprocessing.StandardScaler()
x_train=scaler.fit_transform(x_train)
x_test=scaler.transform(x_test)
knn=KNeighborsClassifier(n_neighbors=3) 
knn.fit(x_train,y_train)
y_train_predict=knn.predict(x_train)
from sklearn import metrics
print(metrics.accuracy_score(y_train,y_train_predict))
y_predict=knn.predict(x_test)
print(metrics.accuracy_score(y_test,y_predict))

参考
李航《统计学习方法》
https://mlnote.wordpress.com/2015/12/16/python机器学习实践与kaggle实战-machine-learning-for-kaggle-competition-in-python/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语简单直观,易于学习和使用。它避免了复杂的语特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语简单直观,易于学习和使用。它避免了复杂的语特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值