Cleanlab KNN 搜索接口详解:使用 construct_knn 与 sklearn NearestNeighbors 构建数据质量检查基础设施
【免费下载链接】cleanlabCleanlab's open-source library is the standard>项目地址: https://gitcode.com/GitHub_Trending/cl/cleanlab
Cleanlab 的数据中心 AI 库在检测离群点、重复项、标签错误等数据质量问题时,大量依赖 k 近邻(KNN)搜索。本文围绕 cleanlab/internal/neighbor/search.py 中的construct_knn辅助函数,深入讲解 Cleanlab 对外部 KNN 搜索对象提出的完整接口契约:包括必须实现的fit、kneighbors方法,拟合后应暴露的属性,以及如何用你自己的近似 KNN 库替换默认的 scikit-learnNearestNeighbors实现。读完本文,你将掌握 Cleanlab KNN 搜索索引的构造方式、接口兼容性要求,以及它在 Datalab 各类 issue 检测中的实际调用链。
一、search 模块在 neighbor 子包中的定位
Cleanlab 的cleanlab.internal.neighbor子包专门提供近邻搜索与成对距离计算能力,index.rst 将其划分为三个模块,分工清晰:
neighbor.search:提供包装默认近邻搜索实现的辅助函数,即本文主角construct_knn;neighbor.knn_graph:提供近邻搜索索引的搭建与 KNN 图的构造函数(如features_to_knn、create_knn_graph_and_index);neighbor.metric:提供近邻搜索距离度量的选择函数(如decide_default_metric)。
search.py本身只有约 75 行,核心即construct_knn一个函数,它直接封装 scikit-learn 的NearestNeighbors构造器并返回实例。但它的价值不在于封装本身,而在于其 docstring 中明确写出的、面向第三方 KNN 库开发者的搜索对象接口规范——这是 Cleanlab 官方文档(由 docs/source/cleanlab/internal/neighbor/search.rst 通过 Sphinxautomodule指令生成)定义的兼容性契约,也是本文讲解的核心。
二、construct_knn:一行构造 KNN 搜索对象
construct_knn的签名与实现如下(search.py):
def construct_knn(n_neighbors: int, metric: Metric, **knn_kwargs) -> NearestNeighbors: sklearn_knn = NearestNeighbors(n_neighbors=n_neighbors, metric=metric, **knn_kwargs) return sklearn_knn参数说明
| 参数 | 类型 | 含义 |
|---|---|---|
n_neighbors | int | 搜索时考虑的最近邻数量 k |
metric | Metric | 计算点之间距离的度量,见 cleanlab/typing.py 定义:Metric = Union[str, Callable],可以是字符串(如"cosine"、"euclidean")或可调用对象(如scipy.spatial.distance.euclidean) |
**knn_kwargs | 关键字参数 | 透传给底层搜索索引构造器的额外参数,如algorithm、leaf_size、metric_params等,完整选项参见 scikit-learn 的NearestNeighbors文档 |
两个重要注意点:
metric若为可调用对象,它必须接受两个参数(两个数据点)并返回它们之间的距离(search.py);**knn_kwargs会被原样透传给底层 KNN 搜索算法,这为自定义搜索索引提供了扩展点——例如 tests/internal/neighbor/test_neighbor.py 中的test_knn_kwargs演示了传入algorithm、leaf_size、metric_params={"V": V}等参数后,knn.n_neighbors、knn.radius、knn.metric_params、拟合后的effective_metric_params_、n_features_in_、n_samples_fit_等属性均正确生效。
典型调用链
construct_knn一般不直接对外调用,而是由上层函数接管:
features_to_knn(features, n_neighbors=..., metric=...)(knn_graph.py)调用construct_knn构造对象后立即.fit(features)并返回已拟合的NearestNeighbors;create_knn_graph_and_index(knn_graph.py)再基于它同时产出 KNN 稀疏图与搜索索引;OutOfDistribution(outlier.py)和回归任务的rank.py(regression/rank.py)也直接调用features_to_knn。
三、搜索对象接口契约:第三方 KNN 库的接入标准
construct_knn的 docstring 明确说明:"You can implement a similar method to run cleanlab with your own approximate-KNN library."(你可以实现一个类似的方法,用你自己的近似 KNN 库来运行 Cleanlab)。这意味着 Cleanlab 并不绑定 sklearn,只要你的搜索对象满足以下接口规范,即可无缝接入。
必须实现的方法
fit:接受特征数组X拟合模型,使后续近邻搜索可在该数据上进行。kneighbors:查找点的 K 近邻,返回最近邻的距离数组与索引数组。它需要处理两种场景:- 传入查询数组
features: np.ndarray时,为查询数组中的每个点返回距离与索引; - 不传查询数组(
features = None)时,为索引中的每个点返回其近邻,且不把查询点本身当作自己的近邻(自查询模式,KNN 图构造依赖此行为)。 - 可选地允许对每个查询点重新指定近邻数量,缺省时使用构造器中的
n_neighbors值。
- 传入查询数组
应当暴露的属性
| 类别 | 属性 | 含义 |
|---|---|---|
| 构造参数 | n_neighbors | 考虑的近邻数量 |
| 构造参数 | metric | 计算点间距离所用的度量 |
| 构造参数 | metric_params | 距离度量函数的额外参数 |
| 拟合属性 | n_features_in_ | 拟合时观测到的特征数量 |
| 拟合属性 | effective_metric_ | 实际用于近邻距离计算的度量 |
| 拟合属性 | effective_metric_params_ | 距离计算中使用的度量参数 |
| 拟合属性 | n_samples_fit_ | 拟合数据中的样本数量 |
| 辅助方法 | __sklearn_is_fitted__ | 返回布尔值指示对象是否已拟合,用于 is_fitted 校验(该校验会检查是否存在以尾下划线结尾的拟合属性) |
上述属性在 test_neighbor.py 的test_knn_kwargs中均有断言验证。
可选实现
kneighbors_graph:非必需,仅作便利实现。KNN 图的构造职责已转移给cleanlab.internal.neighbor.knn_graph.construct_knn_graph_from_index(见 knn_graph.py),该函数基于搜索索引的kneighbors自查询结果,直接构造 CSR 格式的稀疏加权邻接矩阵。
这套规范确保兼容性,并为需要接入其他近邻实现(如近似 KNN、ANN 库)或修改现有功能的开发者提供了清晰指令。
四、距离度量选择:metric 参数的底层逻辑
construct_knn的metric参数与 metric.py 中的默认度量决策函数配合使用。当上层未显式指定 metric 时,features_to_knn会调用decide_default_metric依据特征数组形状自动选择:
- 若特征列数
M > HIGH_DIMENSION_CUTOFF(取值为 3),默认使用"cosine"度量——余弦度量更适合高维数据; - 否则使用欧氏距离,具体实现再依据行数
N判断:N > ROW_COUNT_CUTOFF(取值为 100)时返回字符串"euclidean",由 sklearn 实现,大数据集上性能更好;- 否则返回
scipy.spatial.distance.euclidean可调用对象,速度较慢但数值更精确。
metric.py 定义了HIGH_DIMENSION_CUTOFF = 3与ROW_COUNT_CUTOFF = 100两个常量;tests/internal/neighbor/test_metric.py 通过参数化测试验证了 2D/3D 特征始终用欧氏度量、4 维及以上始终用余弦度量。
五、实战验证:从 features 到 KNN 索引
结合features_to_knn的官方示例(knn_graph.py):
import numpy as np from cleanlab.internal.neighbor import features_to_knn features = np.random.rand(100, 10) knn = features_to_knn(features) # NearestNeighbors(metric='cosine', n_neighbors=10)行为细节:
- 默认近邻数
k = min(DEFAULT_K, N-1),其中DEFAULT_K = 10(knn_graph.py),且k >= N时会抛出ValueError(knn_graph.py); - 100×10 的特征数组列数大于 3,自动选择
"cosine"度量; - 返回的
knn是已 fit 的NearestNeighbors实例,可立即执行knn.kneighbors(...)查询; - test_neighbor.py 的
test_features_to_knn对 N ∈ {2, 10, 100, 101} × M ∈ {2,3,4,5,10,50,100} 做了全组合验证,并断言knn.n_neighbors == min(10, N-1)、维度 >3 时 metric 为"cosine"、否则为"euclidean"。
六、在 Datalab 中的实际调用:KNN 图驱动数据质量检测
KNN 搜索对象最终服务于 Datalab 的数据质量检测。以 knn_graph_helpers.py 的set_knn_graph为例,其调用链为:
set_knn_graph → create_knn_graph_and_index → features_to_knn → construct_knn → sklearn NearestNeighborsset_knn_graph会复用 Datalab 统计信息中已有的weighted_knn_graph(避免重复计算),仅当 KNN 图缺失或knn_metric变化时才重新构造。各 issue 检测器共享这一 KNN 图:
- 离群点检测(outlier.py):
OutOfDistribution在未提供 knn 时调用features_to_knn构造默认估计器,基于每个样本到其 K 近邻的平均距离计算离群分数,且会校验传入的k不超过knn.n_neighbors; - 重复项检测(duplicate.py):从 KNN 图的最近邻距离矩阵中提取最近邻距离,结合中位数阈值筛选疑似重复;
- 数据估值(data_valuation.py):基于 KNN 图计算 Data Shapley 分数。
KNN 图中还存在一个关键细节:correct_exact_duplicates=True时(默认开启),create_knn_graph_and_index会通过correct_knn_graph修正特征数组中完全重复的样本,确保它们的互相距离为 0 且正确进入彼此近邻集合(knn_graph.py)。test_neighbor.py 与基于 Hypothesis 的属性测试(test_knn_graph_duplicate_handling,test_neighbor.py)系统验证了重复样本校正前后的距离与索引一致性。
七、扩展你自己的 KNN 实现
基于上述接口契约,接入自定义近邻库的落地步骤可以归纳为:
- 实现一个类,提供
fit(X)与kneighbors(X=None, n_neighbors=None, return_distance=True)方法,返回符合契约的距离/索引数组; - 暴露
n_neighbors、metric、metric_params等属性与拟合后属性,并实现__sklearn_is_fitted__; - 仿照
construct_knn写一个工厂函数,返回你的自定义对象实例,之后即可将其传入依赖NearestNeighbors兼容接口的 Cleanlab 函数(如OutOfDistribution的knn参数)使用。
需要再次强调的是,该契约由 search.rst 生成的官方 API 文档完整承载,任何面向 Cleanlab 的自定义 KNN 集成都应以上述fit/kneighbors方法、属性与拟合属性清单为准,并在接入后参考 tests/internal/neighbor/test_neighbor.py 的断言模式对兼容性做回归验证。
【免费下载链接】cleanlabCleanlab's open-source library is the standard>项目地址: https://gitcode.com/GitHub_Trending/cl/cleanlab
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考