近临算法(个人总结版)

背景

近邻算法(Nearest Neighbor Algorithm)是一种基本但非常有效的分类和回归方法。最早由Fix和Hodges在1951年提出,经过几十年的发展和改进,已成为数据挖掘、模式识别和机器学习领域的重要工具。近邻算法基于相似性原则,通过查找最接近的样本进行预测。其核心思想是相似的样本具有相似的特征,因而在预测时可以参考相似样本的类别或数值。常见的近邻算法包括k近邻算法(k-Nearest Neighbors, k-NN)、KD树(KD-Tree)和球树(Ball Tree)。

一、近邻算法的基本概念

近邻算法通过比较样本之间的距离来进行分类或回归。其核心思想是相似的样本具有相似的特征,因而在预测时可以参考相似样本的类别或数值。

1.1 距离度量

常用的距离度量包括:

  • 欧氏距离(Euclidean Distance):最常用的距离度量,适用于连续型数据。公式为:

  • 曼哈顿距离(Manhattan Distance):适用于高维空间和稀疏数据。公式为:

  • 闵可夫斯基距离(Minkowski Distance):欧氏距离和曼哈顿距离的推广,适用于多种情况。公式为:

  • 余弦相似度(Cosine Similarity):用于度量两个向量之间的夹角,相似度越大,距离越小。公式为:

1.2 算法类型

  • 分类:将新样本分类到与其最相似的样本所属的类别。
  • 回归:预测新样本的数值为与其最相似的样本数值的加权平均。

二、k近邻算法(k-NN)

2.1 基本原理

k近邻算法通过查找与目标样本最近的k个样本进行预测。对于分类任务,k个邻居中的多数类作为预测结果;对于回归任务,k个邻居的平均值作为预测结果。k近邻算法无需训练过程,直接利用所有训练数据进行预测,因此也被称为懒惰学习算法(Lazy Learning)。

2.2 具体实现

以下是k近邻算法的分类实现:

import numpy as np
from collections import Counter
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

class KNN:
    def __init__(self, k=3):
        self.k = k

    def fit(self, X, y):
        self.X_train = X
        self.y_train = y

    def predict(self, X):
        predictions = [self._predict(x) for x in X]
        return np.array(predictions)

    def _predict(self, x):
        distances = [np.sqrt(np.sum((x - x_train)**2)) for x_train in self.X_train]
        k_indices = np.argsort(distances)[:self.k]
        k_nearest_labels = [self.y_train[i] for i in k_indices]
        most_common = Counter(k_nearest_labels).most_common(1)
        return most_common[0][0]

# 加载示例数据集
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.2, random_state=42)

# 训练和预测
knn = KNN(k=3)
knn.fit(X_train, y_train)
predictions = knn.predict(X_test)

# 计算准确率
print("Accuracy:", accuracy_score(y_test, predictions))

2.3 优劣势

优势

  • 简单易懂:k近邻算法的基本思想简单直观,易于理解和实现。
  • 无训练过程:无需训练过程,直接利用所有训练数据进行预测。

劣势

  • 计算复杂度高:对每个测试样本都需要计算与所有训练样本的距离,因此预测过程的计算复杂度较高,适合小规模数据集。
  • 对噪声数据敏感:k近邻算法对噪声数据较为敏感,可能影响预测结果。
  • 数据标准化要求:不同特征的量纲不同时,需对数据进行标准化处理,否则距离计算可能会受到影响。

三、KD树(KD-Tree)

3.1 基本原理

KD树是一种对k近邻算法进行优化的数据结构,通过将数据划分到k维空间中的子区域,实现高效的最近邻搜索。KD树通过递归地将数据空间划分为k维超矩形,适用于低维数据的最近邻搜索。

3.2 具体实现

以下是KD树的实现和最近邻搜索:

from scipy.spatial import KDTree

# 示例数据
X = np.random.rand(10, 2)

# 构建KD树
kd_tree = KDTree(X)

# 查询最近邻
point = np.random.rand(1, 2)
distance, index = kd_tree.query(point)

print("Nearest neighbor:", X[index])
print("Distance:", distance)

3.3 优劣势

优势

  • 提高了k近邻搜索的效率:KD树通过分割数据空间,实现了快速的最近邻搜索,特别适合低维数据。
  • 支持动态插入和删除操作:KD树允许动态插入和删除数据点,适用于数据集动态变化的场景。

劣势

  • 构建和维护树结构的复杂度较高:构建KD树需要较高的计算复杂度,插入和删除操作也较为复杂。
  • 维度灾难:随着维度增加,KD树的性能提升有限,高维数据的最近邻搜索效果不佳。

四、球树(Ball Tree)

4.1 基本原理

球树是一种替代KD树的结构,通过使用超球体代替超矩形来划分空间,适用于高维数据和度量空间。球树通过递归地将数据空间划分为球形区域,实现高效的最近邻搜索。

4.2 具体实现

以下是球树的实现和最近邻搜索:

from sklearn.neighbors import BallTree

# 示例数据
X = np.random.rand(10, 2)

# 构建球树
ball_tree = BallTree(X)

# 查询最近邻
point = np.random.rand(1, 2)
dist, ind = ball_tree.query(point)

print("Nearest neighbor:", X[ind])
print("Distance:", dist)

4.3 优劣势

优势

  • 适用于高维数据:球树在高维空间中表现良好,比KD树更适合高维数据。
  • 支持多种距离度量:球树支持多种距离度量,如欧氏距离、曼哈顿距离等。

劣势

  • 构建和维护树结构的复杂度较高:构建和维护球树需要较高的计算复杂度,插入和删除操作也较为复杂。
  • 构建时间较长:随着数据规模增加,构建球树的时间较长。

五、应用实例

5.1 手写数字识别

使用k-NN算法进行手写数字识别:

from sklearn.datasets import load_digits
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.neighbors import KNeighborsClassifier

# 加载数据
digits = load_digits()
X, y = digits.data, digits.target

# 预处理数据
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 训练k-NN分类器
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)

# 预测并计算准确率
predictions = knn.predict(X_test)
print("Accuracy:", accuracy_score(y_test, predictions))

5.2 图像检索

使用KD树进行图像特征的最近邻搜索:

from sklearn.decomposition import PCA
from sklearn.datasets import fetch_olivetti_faces
from scipy.spatial import KDTree

# 加载数据
faces = fetch_olivetti_faces()
X, y = faces.data, faces.target

# 降维
pca = PCA(n_components=50)
X_pca = pca.fit_transform(X)

# 构建KD树
kd_tree = KDTree(X_pca)

# 查询最近邻
query_image = X_pca[0].reshape(1, -1)
dist, ind = kd_tree.query(query_image, k=5)

# 输出最近邻结果
print("Nearest neighbors:", ind)
print("Distances:", dist)

5.3 文章推荐

使用球树进行文章推荐:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.neighbors import BallTree

# 示例文章
documents = [
    "The quick brown fox jumps over the lazy dog.",
    "Never jump over the lazy dog quickly.",
    "Bright vixens jump; dozy fowl quack.",
    "Jinxed wizards pluck ivy from the big quilt.",
    "The five boxing wizards jump quickly."
]

# 计算TF-IDF特征
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(documents).toarray()

# 构建球树
ball_tree = BallTree(X, metric='cosine')

# 查询最近邻
query = vectorizer.transform(["Jumping over dogs is fun."]).toarray()
dist, ind = ball_tree.query(query, k=3)

# 输出最近邻结果
print("Nearest neighbors:", ind)
print("Distances:", dist)

六、总结

近邻算法是一类基础且强大的分类和回归方法,广泛应用于图像识别、推荐系统等领域。本文详细介绍了k近邻算法(k-NN)、KD树(KD-Tree)、球树(Ball Tree)的基本原理、具体实现、优劣势及应用实例。通过这些算法的学习和应用,可以有效提高分类和回归任务的性能和精度。

拓展阅读与参考文献

  1. 《统计学习方法》 - 李航
  2. 《机器学习》 - 周志华
  3. 《模式分类》 - Duda, Hart, Stork
  4. Efficient Algorithms for Nearest Neighbor Search in High Dimensions - Arya, Mount, Netanyahu, Silverman, Wu (1998)
  5. Nearest Neighbors in High-Dimensional Data: The Efficiency-Accuracy Tradeoff - Indyk, Motwani (1998)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

get和post的区别,二者是幂等的吗?

一、什么是幂等 所谓幂等性通俗的将就是一次请求和多次请求同一个资源产生相同的副作用。 维基百科定义:幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中一个幂等操作的特点是其任意多次执…

git分支常用命令

最近在用git提交代码的时候&#xff0c;发现有些命令不是很会&#xff0c;先记录几个常用分支命令&#xff0c;后续再补充&#xff0c;在执行git push命令提交代码的时候遇到报错&#xff0c;一并记录下。 1.git常用命令 新建分支&#xff1a; git branch <分支名称> 比…

day16|二叉树的属性

相关题目 ● 104.二叉树的最大深度 559.n叉树的最大深度 ● 111.二叉树的最小深度 ● 222.完全二叉树的节点个数 二叉树的深度与高度 如图&#xff0c; 二叉树的深度表示&#xff1a;任意一个叶子节点到根节点的距离&#xff0c;是从上往下计数的&#xff0c;因此使用前序遍历…

Transformer详解(2)-位置编码

位置编码公式 偶数位置用sin,奇数位置用cos. d_model 表示token的维度&#xff1b;pos表示token在序列中的位置&#xff1b;i表示每个token编码的第i个位置&#xff0c;属于[0,d_model)。 torch实现 import math import torch from torch import nn from torch.autograd im…

blender 烘焙渲染图片,已经导出fbx,导出贴图。插件生成图片

1.新建一个模型。选择资产浏览器的材质&#xff0c;并拖动到模型身上&#xff0c;如下图。资产浏览器的材质可以网上找。 2.打开着色器面板。正下方着色器窗口中&#xff0c;点击空白取消选择&#xff0c;然后右击-添加-着色器-原理化BSDF&#xff0c;右击-添加-纹理-图像纹理。…

初阶数据结构之双向链表详解

目录 一&#xff1a;双向链表的概念 1.什么是双向链表&#xff1f; 2.双向链表的优点 3.双向链表的结构 二&#xff1a;双向链表的实现 1.定义链表结点 2.初始化双向链表 3.添加结点 4.尾插 5.头插 6.打印双向链表 7.查找链表结点 8.在指定结点后插入新结点 9.删…

力扣:92. 反转链表 II(Java)

目录 题目描述&#xff1a;示例 1&#xff1a;示例 2&#xff1a;代码实现&#xff1a; 题目描述&#xff1a; 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的…

TypeScript-搭建编译环境

搭建编译环境 TypeScript 编写的代码是无法直接在js引擎( 浏览器 / Nodejs )中运行的&#xff0c;最终还需要经过编译成js代码才可以正常运行 搭建手动编译环境 1️⃣ 全局安装 typescript 包&#xff08;编译引擎&#xff09; -> 注册 tsc 命令 npm i -g typescript 2…

如何解决vcruntime140.dll丢失问题,详细介绍5种靠谱的解决方法

vcruntime140.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;它为使用Visual C编译器开发的应用程序提供必要的运行时环境。该DLL文件包含了大量应用程序运行时需要调用的库函数&#xff0c;这些函数是实现C标准库、异常处理机制、RTTI&#xff08;运行…

2461. 长度为 K 子数组中的最大和(c++)

给你一个整数数组 nums 和一个整数 k 。请你从 nums 中满足下述条件的全部子数组中找出最大子数组和&#xff1a; 子数组的长度是 k&#xff0c;且子数组中的所有元素 各不相同 。 返回满足题面要求的最大子数组和。如果不存在子数组满足这些条件&#xff0c;返回 0 。 子数…

2024电工杯数学建模A题Matlab代码+结果表数据教学

2024电工杯A题保姆级分析完整思路代码数据教学 A题题目&#xff1a;园区微电网风光储协调优化配置 以下仅展示部分&#xff0c;完整版看文末的文章 %A_1_1_A % 清除工作区 clear;clc;close all;warning off; %读取参数%正常读取 % P_LOADxlsread(附件1&#xff1a;各园区典…

如何创建 Gala Games 账户:解决 Cloudflare 验证指南 2024

Gala Games 站在数字娱乐新时代的前沿&#xff0c;将区块链技术与游戏相结合&#xff0c;重新定义了所有权和奖励。本文将引导您创建 Gala Games 账户并使用 CapSolver 解决 Cloudflare 验证难题&#xff0c;确保您顺利进入这一创新的生态系统。 什么是 Gala Games&#xff1f…

debian nginx upsync consul 实现动态负载

1. consul 安装 wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_r…

微信小程序使用input标签遇到的问题

场景1&#xff1a;多个input标签切换无法聚焦问题 解决方案1&#xff1a; 在网上搜的用官方给的always-embed属性&#xff0c;但是也明确标注了只有ios可用 解决方案2&#xff1a; 使用focus属性&#xff1a;每次点击input标签都重新设置 wxml: <input adjust-position…

【YOLOv5/v7改进系列】替换激活函数为SiLU、ReLU、LeakyReLU、FReLU、PReLU、Hardswish、Mish、ELU等

一、导言 激活函数在目标检测中的作用至关重要&#xff0c;它们主要服务于以下几个关键目的&#xff1a; 引入非线性&#xff1a;神经网络的基本构建块&#xff08;如卷积层、全连接层等&#xff09;本质上是线性变换&#xff0c;而激活函数通过引入非线性&#xff0c;使得网络…

画图工具之PlantUML插件使用

文章目录 1 PlantUML插件1.1 引言1.2 什么是PlantUML1.3 PlantUML插件1.3.1 IntelliJ IDEA中插件1.3.2 VS Code中插件1.3.3 使用例子 1.4 PlantUML时序图语法1.4.1 声明参与者1.4.2 消息传递1.4.2.1 同步消息1.4.2.2 异步消息1.4.2.3 返回消息1.4.2.4 自调用 1.4.3 生命线&…

在Windows10中重命名文件和文件夹的6种方法,有你熟悉和不熟悉的

序言 你可以通过多种方式在Windows 10上重命名文件。如果每次你想更改文件名时仍右键单击并选择“重命名”,那么我们有一些技巧可以加快更改速度。 使用文件资源管理器重命名文件和文件夹 Windows 10的文件资源管理器是一个功能强大的工具。你知道吗,有四种不同的方法可以…

理解大语言模型(二)——从零开始实现GPT-2

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文涉及到的代码链接如下&#xff1a;regression2chatgpt/ch11_llm/char_gpt.ipynb1 本文将讨论如何利用PyTorch从零开始搭建G…

【Linux网络】端口及UDP

文章目录 1.再看四层2.端口号2.1引入linux端口号和进程pid的区别端口号是如何生成的传输层有了pid还设置端口号端口号划分 2.2问题2.3netstat 3.UDP协议3.0每学一个协议 都要讨论一下问题3.1UDP协议3.2谈udp/tcp实际上是在讨论什么&#xff1f; 1.再看四层 2.端口号 端口号(Po…

MyBatis-Plus介绍及Spring Boot 3集成指南

我们每个Java开发者都在使用springbootmybatis开发时&#xff0c;我们经常发现自己需要为每张数据库表单独编写XML文件&#xff0c;并且为每个表都需要编写一套增删改查的方法&#xff0c;较为繁琐。为了解决这一问题&#xff0c;MyBatis-Plus应运而生。在本文中&#xff0c;我…