NLP深入学习(九):KNN 算法及分类用法

news2024/9/27 21:19:44

文章目录

  • 0. 引言
  • 1. 什么是 KNN
  • 2. k 值的选择
  • 3. kd 树
    • 3.1 构建 kd 树:
    • 3.2 kd 树搜索:
    • 3.3 例子
  • 4. 参考


0. 引言

前情提要:
《NLP深入学习(一):jieba 工具包介绍》
《NLP深入学习(二):nltk 工具包介绍》
《NLP深入学习(三):TF-IDF 详解以及文本分类/聚类用法》
《NLP深入学习(四):贝叶斯算法详解及分类/拼写检查用法》
《NLP深入学习(五):HMM 详解及字母识别/天气预测用法》
《NLP深入学习(六):n-gram 语言模型》
《NLP深入学习(七):词向量》
《NLP深入学习(八):感知机学习》

1. 什么是 KNN

K 近邻(K-Nearest Neighbors, KNN)算法是一种基础且直观的监督学习方法,用于分类和回归任务。在处理新的数据点时,KNN 算法基于“物以类聚”的原则,通过计算新样本与已有训练样本之间的距离,找出最接近的 k 个邻居,并根据这些邻居的类别或属性来预测新样本的类别或数值。
在这里插入图片描述

工作原理:

  1. 训练阶段:

    • 在 KNN 中不存在明确的训练过程。算法仅存储整个训练集,不需要对训练数据进行任何模型拟合操作。KNN 算法的核心在于计算样本之间的距离,然后根据距离选择最近的邻居来进行分类或回归。以下是计算公式和步骤:
      • 对于欧式距离(最常用的距离度量方法),假设我们有新样本 x n e w x_{new} xnew 和训练集中的一个样本 x i x_i xi,它们都是 n 维向量,则两个样本之间的欧氏距离计算公式为:
        d ( x n e w , x i ) = ∑ j = 1 n ( x n e w , j − x i , j ) 2 d(x_{new}, x_i) = \sqrt{\sum_{j=1}^{n}(x_{new, j} - x_{i, j})^2} d(xnew,xi)=j=1n(xnew,jxi,j)2
      • 其他常见的距离度量包括曼哈顿距离、切比雪夫距离、马氏距离等。
  2. 找出k个最近邻

    • 计算新样本与训练集中所有样本的距离后,按照距离从小到大排序,并选择前k个最近的样本作为“邻居”。
  3. 分类决策规则(针对分类任务):

    • 多数表决:统计这k个邻居中属于各个类别的样本数量,将新样本预测为出现次数最多的类别。
    • 加权投票:赋予每个邻居以一定的权重(通常根据其与新样本的距离来加权,距离越近权重越大),然后对各类别进行加权投票决定新样本的类别。
  4. 回归预测规则(针对回归任务):

    • 平均值法:计算这k个邻居的目标变量(连续数值)的平均值作为新样本的预测值。

2. k 值的选择

k 值的选择是 KNN 算法的关键。较小的 k 值可能导致模型过拟合,而较大的k值可能会使模型过于保守导致欠拟合。一般使用交叉验证,通过交叉验证来评估不同k值对模型性能的影响。将数据集划分为训练集和验证集(或使用k折交叉验证),针对一系列不同的k值,在训练集上计算每个样本的k个最近邻,并在验证集上评估模型性能(如分类任务中的准确率、召回率、F1分数等)。

3. kd 树

KNN 算法在高维数据上的效率可能会受到严重的影响,因为在高维空间中计算距离的开销很大。为了加速 KNN 算法在高维空间的执行,可以使用 kd 树(k-dimensional tree)这种数据结构。

kd 树是一种二叉树结构,用于组织k维空间中的数据点。它的构建和搜索过程允许更有效地找到近邻点,从而提高了 KNN 算法的性能。

3.1 构建 kd 树:

  1. 选择轴: 在树的每一层,选择一个轴(特征维度)来进行划分。通常选择方差最大的轴作为划分轴。

  2. 选择划分点: 在选定的轴上,选择当前数据集中的中位数作为划分点,将数据分为两个子集。

  3. 递归构建: 对划分点两侧的数据集递归执行上述过程,构建子树。

在这里插入图片描述
例如,上面的各个点:
(1)第一次划分,x=7,分为两部分
(2)左边的矩形划分,y=4,分为两部分;上面的用 x=4,下面用 x=2划分
(3)左边的矩形划分,y=6,也分为两部分;下面用 x=8 划分
最终,得到的 kd 树如下:
在这里插入图片描述

3.2 kd 树搜索:

  1. 根据轴进行搜索: 从根节点开始,根据查询点在当前轴上的值比较,选择向左或向右子树移动。

  2. 递归搜索: 在选择的子树上递归执行搜索。

  3. 更新最近邻点: 在搜索的过程中,维护一个当前最近邻点的列表。如果发现更近的点,则更新最近邻点。

  4. 回溯: 在回溯过程中,检查是否需要在另一个子树中继续搜索。

kd 树的优点是在处理高维数据时可以减少搜索的计算开销,因为它在每一步都可以剪枝。然而,kd 树的构建和搜索过程相对复杂,适用于数据集较大、查询点较多的情况。

3.3 例子

下面我将提供一个简单的 Python 代码示例,演示如何构建一个二维数据集的 kd 树以及如何使用 kd 树进行最近邻搜索。请注意,这只是一个基本示例,实际应用中可能需要考虑更多的细节和优化。

import numpy as np

class Node:
    def __init__(self, point, axis, left=None, right=None):
        self.point = point
        self.axis = axis
        self.left = left
        self.right = right

def build_kdtree(points, depth=0):
    if len(points) == 0:
        return None

    k = len(points[0])  # 维度
    axis = depth % k  # 选择轴

    # 根据轴排序并选择中位数作为划分点
    points.sort(key=lambda x: x[axis])
    median = len(points) // 2

    return Node(
        point=points[median],
        axis=axis,
        left=build_kdtree(points[:median], depth + 1),
        right=build_kdtree(points[median + 1:], depth + 1)
    )

def closest_point(root, target, depth=0, best=None):
    if root is None:
        return best

    k = len(target)
    axis = depth % k

    next_best = None
    next_branch = None

    if target[axis] < root.point[axis]:
        next_branch = root.left
    else:
        next_branch = root.right

    next_best = closest_point(next_branch, target, depth + 1, next_best)

    # 更新最近邻点
    if best is None or np.linalg.norm([target[i] - root.point[i] for i in range(k)]) < np.linalg.norm([target[i] - best[i] for i in range(k)]):
        best = root.point

    # 检查另一个分支是否可能包含更近的点
    if abs(target[axis] - root.point[axis]) < np.linalg.norm([target[i] - best[i] for i in range(k)]):
        next_branch = root.right if next_branch == root.left else root.left
        next_best = closest_point(next_branch, target, depth + 1, next_best)

    return best

# 示例数据集
data_points = [(2,3), (5,4), (9,6), (4,7), (8,1), (7,2)]
query_point = (9,2)

# 构建kd树
kd_tree = build_kdtree(data_points)

# 查找最近邻点
nearest_neighbor = closest_point(kd_tree, query_point)

print("Data Points:", data_points)
print("Query Point:", query_point)
print("Nearest Neighbor:", nearest_neighbor)

在这个例子中,我们首先定义了一个 Node 类来表示 kd 树的节点,然后使用 build_kdtree 函数构建 kd 树。最后,使用 closest_point 函数来查找查询点的最近邻点。

4. 参考

《NLP深入学习(一):jieba 工具包介绍》
《NLP深入学习(二):nltk 工具包介绍》
《NLP深入学习(三):TF-IDF 详解以及文本分类/聚类用法》
《NLP深入学习(四):贝叶斯算法详解及分类/拼写检查用法》
《NLP深入学习(五):HMM 详解及字母识别/天气预测用法》
《NLP深入学习(六):n-gram 语言模型》
《NLP深入学习(七):词向量》
《NLP深入学习(八):感知机学习》

欢迎关注本人,我是喜欢搞事的程序猿; 一起进步,一起学习;

也欢迎关注我的wx公众号:一个比特定乾坤

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1408126.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】入门(二)

前言&#xff1a; c基础语法&#xff08;下&#xff09; 文章目录 五、引用5.1 引用概念5.2 引用使用规则5.3 常引用5.4 引用的使用场景5.5 引用和指针的区别 六、内联函数6.1 概念6.2 内联函数的特性 七、auto关键字&#xff08;C11&#xff09;7.1 概念7.2 使用规则7.3 用于f…

(M)unity2D敌人的创建、人物属性设置,遇敌掉血

敌人的创建 1.敌人添加与组件设置 1&#xff09;添加敌人后&#xff0c;刚体添加&#xff0c;碰撞体添加&#xff08;一个碰撞体使猪在地上走&#xff0c;不接触人&#xff0c;另一个碰撞体组件使人和猪碰在一起产生伤害&#xff09; ①刚体 ②碰撞体一 设置的只在脚下&a…

关于标准那些事——第十篇 分类标准

最近要赶一个极其重要的CANS认证项目&#xff0c;这会是全中国第一个完全数字化CNAS认证的实验室项目&#xff0c;内容分享进度会比较慢。其实&#xff0c;大多数情况也并不是没有时间&#xff0c;俗话说&#xff1a;时间嘛&#xff0c;挤挤总是有的&#xff01;其实影响进度更…

php低版本(7.4)配置过程中遇到的问题及基本解决手段

目前php不支持较低版本的安装&#xff0c;如果安装低版本必须借助第三方库shivammathur //将第三方仓库加入brewbrew tap shivammathur/php //安装PHPbrew install shivammathur/php/php7.4 可能出现的问题 像这样突然中止然后报错&#xff0c;一般是网络问题&#xff0c;或…

Socket实现服务器和客户端

Socket 编程是一种用于在网络上进行通信的编程方法&#xff0c;以下代码可以实现在不同主机之间传输数据。 Socket 编程中服务器端和客户端的基本步骤&#xff1a;服务器端步骤&#xff1a; 1.创建 Socket&#xff1a; int serverSocket socket(AF_INET, SOCK_STREAM, 0);…

git 对象压缩及垃圾对象清理

git 对象压缩及垃圾对象清理 这篇文章让我们来看看 git 的对象压缩机制&#xff0c;前面的几篇文章我们提到&#xff0c;在执行 git add 命令会会把文件先通过 zlib 压缩后放入到「暂存区」&#xff0c;我们先看看这个步骤&#xff1a; 我们这个实例中有一个 1.28m 的 index.…

网工内推 | 国企、合资公司IT专员,13薪,NA以上即可

01 上海新徐汇&#xff08;集团&#xff09;有限公司 招聘岗位&#xff1a;IT运维 职责描述&#xff1a; 1.负责制定网络体系搭建、IP地址分配、网络拓扑图、无线网络等&#xff1b; 2.负责桌面运维技术支持&#xff0c;确保各类系统和终端设备正常工作&#xff1b; 3.负责弱电…

信号量机制解决经典同步互斥问题

生产者 / 消费者问题、读者 / 写者问题和哲学家问题是操作系统的三大经典同步互斥问题。本文将介绍这三个问题的基本特点以及如何用信号量机制进行解决。 在分析这三个问题之前&#xff0c;我们首先需要了解用信号量机制解决同步互斥问题的一般规律&#xff1a; 实现同步与互斥…

IDCNBSAIS-财务报表功能范围取值管理费用、销售费用、研发费用排除指定科目的实现

IDCNBSAIS-财务报表功能范围取值管理费用、销售费用、研发费用排除指定科目的实现 公司遇到的一个问题&#xff0c;目前报表有些项目是按照功能范围取值的&#xff0c;发现取多了。需要排除某些科目。 下面这例子就是要排除6601010204/05/06 这3个对应的科目 研究了很多方法…

【立创EDA-PCB设计基础完结】7.DRC设计规则检查+优化与丝印调整+打样与PCB生产进度跟踪

前言&#xff1a;本文为PCB设计基础的最后一讲&#xff0c;在本专栏中【立创EDA-PCB设计基础】前面已经将所有网络布线铺铜好了&#xff0c;接下来进行DRC设计规则检查优化与丝印调整打样与PCB生产进度跟踪 目录 1.DRC设计规则检查 2.优化与丝印调整 1.过孔连接优化 2.泪滴…

巧学三极管

NPN型三极管&#xff0c;由三块半导体构成&#xff0c;其中两块N型和一块P型半导体组成&#xff0c;P型半导体在中间&#xff0c;两块N型半导体在两侧&#xff0c;三极管是电子电路中最重要的器件&#xff0c;他主要的功能是电流放大和开关的作用。 工作原理 实际上&#xff0…

QCustomPlot开源库使用

1.简介 QCustomPlot是用于绘图和数据可视化的Qt C 小部件。它没有进一步的依赖关系&#xff0c;并且有据可查。该绘图库专注于制作美观&#xff0c;出版质量的2D绘图&#xff0c;图形和图表&#xff0c;以及为实时可视化应用程序提供高性能。看一下“ 设置”和“ 基本绘图”教…

C++补充篇- C++11 及其它特性

目录 explicit 关键字 左值和右值的概念 函数返回值当引用 C11 新增容器 - array C的类型转换 static_cast reinterpret_cast dynamic_cast const_cast C智能指针 auto_ptr 使用详解 (C98) unique_ptr 使用详解 (C11) auto_ptr的弊端 unique_ptr严谨auto_ptr的弊端 unique_…

开始学习Vue2(组件的生命周期和数据共享)

一、组件的生命周期 1. 生命周期 & 生命周期函数 生命周期&#xff08;Life Cycle&#xff09;是指一个组件从创建 -> 运行 -> 销毁的整个阶段&#xff0c;强调的是一个时间段。 生命周期函数&#xff1a;是由 vue 框架提供的内置函数&#xff0c;会伴随着 组件…

luceda ipkiss教程 57:画微环调制器

案例分享&#xff1a;画微环调制器 全部代码如下&#xff1a; from si_fab import all as pdk from ipkiss3 import all as i3class DC(i3.PCell):straight_length i3.PositiveNumberProperty(default200)radius i3.PositiveNumberProperty(default50)spacing i3.Positive…

推荐系统算法 协同过滤算法详解(二)皮尔森相关系数

目录 前言 协同过滤算法(简称CF) 皮尔森(pearson)相关系数公式 算法介绍 算法示例1&#xff1a; 算法示例2 前言 理解吧同胞们&#xff0c;实在是没办发把wps公式复制到文章上&#xff0c;只能截图了&#xff0c;我服了&#xff01;&#xff01;&#xff01; 协同过滤算法…

基于中文垃圾短信数据集的经典文本分类算法实现

垃圾短信的泛滥给人们的日常生活带来了严重干扰&#xff0c;其中诈骗短信更是威胁到人们的信息与财产安全。因此&#xff0c;研究如何构建一种自动拦截过滤垃圾短信的机制有较强的实际应用价值。本文基于中文垃圾短信数据集&#xff0c;分别对比了朴素贝叶斯、逻辑回归、随机森…

数据结构——排序算法代码实现、包含注释易理解可运行(C语言,持续更新中~~)

一、排序 1.1 直接插入排序 1.1.1 思想 插入排序的核心操作是将待排序元素与已排序序列中的元素进行比较&#xff0c;并找到合适的位置进行插入。这个过程可以通过不断地将元素向右移动来实现。 插入排序的优势在于对于小规模或基本有序的数组&#xff0c;它的性能非常好。…

【经验分享】豆瓣小组的文章/帖子怎么删除?

#豆瓣小组的文章/帖子怎么删除&#xff1f;# 第一步&#xff1a; 手机登录豆瓣app ↓ 点右下角“我” ↓ 然后在页面点击我的小组 ↓ 点我发布的 ↓ ↓ 再任意点开一个帖子 ↓ 在文章和帖子的右上角有一个笔状的图标&#xff0c;切记不是右上角的横三点… ↓ ↓ 最后点下边的…

odoo 一日一技 owl Registry示例 在用户菜单增加开发者模式开关

# 示例介绍 在Odoo中&#xff0c;开发者模式是一个非常有用的工具&#xff0c;它允许开发人员对系统进行调试。如果每次都要去设置中打开调试模式将非常麻烦&#xff0c;上篇文章讲述了如何使用 owl registry&#xff0c;这篇我们来进行实操。 本文将介绍如何在Odoo的用户菜单…