趋近智
许多机器学习 (machine learning)问题涉及具有固有空间特性的数据,例如地理坐标、图像中的像素位置或3D模拟中的点。高效处理此类数据通常需要专门设计用于处理多维空间的结构。对于查找特定半径内的所有点(范围查询)或定位查询点的最近邻等任务,标准列表甚至平衡二叉搜索树都变得效率低下,特别是当数据集增大时。
空间数据结构划分包含数据点的空间,从而在搜索过程中能够快速剪除不相关区域。本章的这一部分介绍两种基本的分层空间数据结构:用于二维空间的四叉树和用于三维空间的八叉树。
四叉树是一种树数据结构,其中每个内部节点恰好有四个子节点。它主要通过递归地将二维空间细分为四个象限或区域来划分空间。
考虑将点插入到四叉树中。我们从根节点开始。如果根节点有子节点,我们判断该点属于哪个象限,并递归地尝试插入到该子节点中。如果节点是叶节点且容量未满,我们添加该点。如果叶节点已满,我们细分该节点,创建四个新的空子节点,并将之前在该叶节点中的所有点(包括新点)重新分配到相应的新子节点中。
# 四叉树节点结构
class QuadTreeNode:
def __init__(self, boundary, capacity=4):
self.boundary = boundary # 表示矩形区域的对象
self.capacity = capacity # 细分前的最大点数
self.points = [] # 存储在该节点中的点(如果是叶节点)
self.is_leaf = True
self.nw = None # 子节点
self.ne = None
self.sw = None
self.se = None
def subdivide(self):
# 创建四个边界更小的子节点的逻辑
self.is_leaf = False
# ... create self.nw, self.ne, self.sw, self.se ...
# 将 self.points 重新分配给子节点
def insert(self, point):
if not self.boundary.contains(point):
return False # 点在该节点的边界之外
if self.is_leaf:
if len(self.points) < self.capacity:
self.points.append(point)
return True
else:
self.subdivide()
# 细分后,尝试插入到正确的子节点
# 继续处理非叶节点的情况
# 不是叶节点,或刚刚被细分
if self.nw.insert(point): return True
if self.ne.insert(point): return True
if self.sw.insert(point): return True
if self.se.insert(point): return True
# 如果边界检查正确,这不应该发生
return False
四叉树擅长空间查询:
一个四叉树结构划分二维空间。叶节点(蓝色)存储点,而内部节点(灰色)则进一步细分。
八叉树是四叉树在三维空间中的直接对应物。八叉树不将二维区域划分为四个象限,而是递归地将三维区域(通常是立方体或长方体)划分为八个八分体。
在Python中实现四叉树或八叉树时:
(min_x, min_y, max_x, max_y) 或专门的类)。(x, y) 或具有坐标属性的对象。Pyqtree(用于四叉树)或专门的几何处理库可能提供优化的实现。在机器学习中,这些结构特别适用于:
四叉树和八叉树的主要局限是它们在高维空间 (high-dimensional space)中的性能下降(“维度灾难”)。随着维度数 () 增加,每个节点子节点数 () 呈指数增长。此外,空间划分的有效性降低,因为点在高维空间中倾向于变得等距,使得有效剪枝搜索分支变得更困难。对于更高维度的数据(通常 ),像k-d树这样的结构(在“实现分层数据树”一节中介绍)或近似最近邻技术通常更合适。
理解四叉树和八叉树能帮助理解空间划分如何优化多维数据上的搜索和查询操作。虽然并非普遍适用于所有机器学习 (machine learning)数据,但它们在处理二维或三维的显式空间数据集时是不可或缺的工具,实现优于朴素方法的扩展性。
这部分内容有帮助吗?
scipy.spatial.KDTree and scipy.spatial.cKDTree Documentation, SciPy Developers, 2023 - SciPy中k-d树实现的官方文档,提供Python中高效的空间查询,与本文讨论的结构相关。© 2026 ApX Machine LearningAI伦理与透明度•