如何在 Python 中使用聚类
Aspose.PDF FOSS for Python 捆绑了一个小型、通用的层次聚合聚类工具——独立于任何单一的 PDF 操作——用于将相关的 DataPoint 对象分组为 Cluster 实例并计算聚类的质心。您决定每个数据点代表什么并自行提供其坐标;该工具不会自动填充坐标。可以使用下面的命令安装此库。
分步指南
步骤 1:安装软件包
安装 Aspose.PDF FOSS 包:
git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .通过导入 Cluster 并打印确认信息来验证安装:
from aspose_pdf import Cluster
print("aspose-pdf-foss-for-python is ready.")步骤 2:导入所需类
导入构成聚类工具的三个类:
from aspose_pdf import Cluster, ClusterCollection, DataPoint步骤 3:创建数据点
一个 DataPoint 将 name 字符串与 value 浮点数列表配对——这些坐标或特征向量由您自行决定,以适用于您自己的分组逻辑:
from aspose_pdf import DataPoint
point_a = DataPoint("item-1", [12.0, 45.0])
point_b = DataPoint("item-2", [13.5, 44.0])
point_c = DataPoint("item-3", [98.0, 5.0])
print(point_a.name, point_a.value)DataPoint 并不将 value 与任何特定的 PDF 概念绑定——页面坐标、字体度量或任何其他数值特征向量都同样适用。
步骤 4:将数据点分组为一个簇
将完整的成员列表传递给 Cluster 构造函数。构建后没有向 Cluster 添加项的方法,因此请先决定成员资格:
from aspose_pdf import Cluster
nearby = Cluster([point_a, point_b])
print(nearby.count) # 2
print(nearby.contains(point_a)) # Truecontains() 通过相等性匹配——DataPoint 在 name 和 value 共同上定义相等性,所以具有相同名称和值的不同 DataPoint 实例也会被报告为已包含。
步骤 5:计算聚类中心
DataPoint.get_centroid(cluster) 是一个静态方法,对聚类中每个 DataPoint.value 的每个维度求平均,并将结果作为名为 "centroid" 的新 DataPoint 返回:
from aspose_pdf import DataPoint
centroid = DataPoint.get_centroid(nearby)
print(centroid.name) # "centroid"
print(centroid.value) # per-dimension average across the cluster聚类中的每个 DataPoint.value 列表必须具有相同的长度——get_centroid 按位置逐个求平均,并不验证长度是否匹配。对 Cluster.empty() 或任何包含 count == 0 的聚类调用它时,会抛出 ValueError。
步骤 6:克隆聚类或复用共享的空实例
clone() 返回一个独立的 Cluster,其中包含相同的项;Cluster.empty() 总是返回相同的已缓存空聚类实例,而不是分配新的实例:
from aspose_pdf import Cluster
backup = nearby.clone()
print(backup is nearby) # False -- independent copy
print(backup.contains(point_a)) # True -- same items
placeholder = Cluster.empty()
print(placeholder.count) # 0步骤 7:将多个聚类分组到一个 ClusterCollection 中
ClusterCollection 将多个 Cluster 对象打包在一个支持 len() 的容器后面:
from aspose_pdf import Cluster, ClusterCollection
outliers = Cluster([point_c])
collection = ClusterCollection([nearby, outliers])
print(len(collection)) # 2ClusterCollection 没有提供方法将其聚类取回——如果需要事后遍历聚类,请保留传入构造函数的列表引用。
常见问题与解决方案
没有方法向现有的添加项目 Cluster
Cluster 只能在构造时接受其成员列表(Cluster(items))。先构建完整的 DataPoint 对象列表,然后再构造 Cluster——之后没有 add() 或 append() 可调用。
DataPoint.get_centroid() raises ValueError
当传入的集群为空(count == 0),包括 Cluster.empty() 时会出现此情况。在调用 get_centroid 之前检查 cluster.count,或者如果空集群在你的工作流中是合法输入,则捕获并处理该异常。
质心值看起来不正确
get_centroid 对每个 DataPoint.value 的每个位置求和并除以点的数量——它不会检查集群中每个 value 列表的长度是否相同。将维度不匹配的 DataPoint 对象混合使用会静默产生不正确的平均值,而不是抛出异常。
Expecting Cluster.empty() 每次创建一个全新的空集群
Cluster.empty() 是单例访问器 — 每次调用都会返回相同的缓存实例。如果您需要一个独立的、全新的空集群,请改用 Cluster()(不带参数)。
期望库能够自动对点进行分组
DataPoint、Cluster 和 ClusterCollection 是用于表示点、集群以及质心计算的数据结构 — 该模块不包含决定哪些点应归为一组的链接或距离函数。您需要在构建 Cluster 之前自行编写代码确定集群成员关系。
常见问题
此模块会自动按距离对数据点进行分组吗?
不。Cluster、DataPoint 和 ClusterCollection 是用于表示已决定的分组并计算质心的构建块 — 没有内置的聚合或基于距离的分配步骤。
Cluster() 与 Cluster.empty() 有什么区别?
Cluster(items=None) 每次被调用时都会创建一个新实例。Cluster.empty() 是一个类方法,在每次调用时返回相同的已缓存、共享的空集群实例。
创建后,我可以向 Cluster 添加项目吗?
不行。Cluster 在构造之外仅公开 contains()、clone() 和 count 属性——成员在构造函数执行后即固定。
get_centroid() 能处理任意数量的维度吗?
是的,只要集群中的每个 DataPoint.value 列表长度相同。get_centroid 对每个维度独立求平均,并将结果作为新的 DataPoint 返回。
ClusterCollection 相比普通的 Python 集群列表额外提供了什么?
主要是一个带有 len() 支持的类型化容器。它并未在迭代、查找或合并行为上提供超出您从原始列表构建的功能。