cleanlab Datalab 完整指南:一站式数据与标签质量问题审计 API
【免费下载链接】cleanlabCleanlab's open-source library is the standard>项目地址: https://gitcode.com/GitHub_Trending/cl/cleanlab
导读
Datalab是 cleanlab 库中面向数据质量审计的统一入口,通过一个对象即可自动检测真实世界数据中的各类标签错误与数据问题(标签错误、异常点、近似重复、非独立同分布、类不平衡、欠表现分组、空值、数据估值等)。本文将围绕 datalab.py 中Datalab类的完整 API(构造参数、find_issues、report、get_issues、issue_summary、save/load等)展开,并结合仓库源码说明底层实现原理与参数细节。读完本文,你将掌握如何用几行代码对分类、回归、多标签及图像数据集发起一次完整的数据质量审计,并能按需定制审计的问题类型与输出深度。
一、Datalab 是什么:统一审计入口的设计思想
在 cleanlab 库中,针对具体目标(如仅查找标签问题、仅清洗标签)可以使用cleanlab.classification、cleanlab.filter、cleanlab.rank等模块中的专门方法;而Datalab则被官方文档明确推荐为"如果你想审计数据质量并检测其中问题"的首选接口(见 datalab.py 类注释)。
Datalab的核心设计特点是:
- 单一对象、多类问题并行审计:一次调用即可检查标签错误、异常点、近似重复、非 IID、类不平衡、欠表现分组、空值、数据估值等常见问题;
- 中间状态复用:
Datalab会跟踪某些 cleanlab 函数产生的中间状态(例如 KNN 图等数据统计),并在其他函数之间复用,从而提升效率; - 与模型解耦:审计过程只通过模型的预测概率、特征向量或预计算的 KNN 图与模型交互,可以配合任何你已经训练好的模型使用;
- 可扩展:通过注册机制支持自定义问题类型(见下文"扩展机制")。
从源码看,Datalab的构造过程实际上完成了一系列内部组件的装配(datalab.py__init__):
Task(任务类型枚举) └─ Data(数据封装、校验、标签格式化) ├─ labels(标签对象,分类任务映射为 0..K-1 整数) └─ _imagelab(可选,图像数据集专用,来自 CleanVision 适配层) └─ _DataIssuesBuilder → data_issues(DataIssues 结果容器)其中Task枚举定义在 task.py,Data负责把各种格式的数据统一转为 Hugging Facedatasets.Dataset并格式化标签(data.py)。
二、构造 Datalab:支持的参数与数据格式
2.1 完整构造签名
Datalab( data, # 必填 task="classification", # "classification" | "regression" | "multilabel" label_name=None, # 标签列名 image_key=None, # 图像字段(可选) verbosity=1, # 0~4 的整数,默认 1 )对应源码位于 datalab.py__init__。
2.2 data:五种受支持的输入格式
data接受所有能被转换为 Hugging FaceDataset对象的"类数据集"对象,完整支持列表(见 data.pyData._load_data):
| 格式 | 说明 |
|---|---|
datasets.Dataset | Hugging Face 数据集对象,直接使用 |
pandas.DataFrame | 通过Dataset.from_pandas转换 |
dict | 键为字符串,值为等长数组/列表 |
list | 由具有相同键的字典组成的列表 |
str | 本地文件路径(.txt/.csv/.json)或 Hugging Face Hub 上的数据集标识符 |
构造时Data还会做格式校验:不支持的输入类型会抛出DataFormatError;如果传入的是DatasetDict(即包含多个 split 的数据集),会抛出DatasetDictError,提示应显式指定split,例如datasets.load_dataset("dataset", split="train")。
注意两点使用约束:
- 分类任务下,标签会被映射为
[0, 1, ..., K-1]的整数;多标签任务下,标签被格式化为列表的列表(如[[0, 1], [1, 2]]);回归任务下标签保持连续数值; - 使用
Datalab需要datasets包,它属于 cleanlab 的可选依赖,可通过pip install "cleanlab[all]"一并安装。
2.3 task:三类受支持的任务
Task枚举(task.py)目前支持三种任务:
| 取值 | 含义 | 标签处理 |
|---|---|---|
"classification"(默认) | 多分类 | 映射为整数 |
"regression" | 回归(连续值预测) | 保持连续值 |
"multilabel" | 多标签分类 | 列表的列表 |
传入非法任务字符串会抛出ValueError。
2.4 image_key 与图像特定问题
image_key用于图像数据集,指向存放实际图片(PIL 对象)的字段。指定后,Datalab会通过create_imagelab(imagelab.py)调用 CleanVision 包,额外审计图像特有的问题类型。默认启用的图像问题类型定义在 constants.pyDEFAULT_CLEANVISION_ISSUES:
dark(过暗)light(过亮)low_information(信息量低,默认阈值 0.15)odd_aspect_ratio(宽高比异常)odd_size(尺寸异常)grayscale(灰度图)blurry(模糊)
限制:image_key目前仅支持以 Hugging Facedatasets.Dataset对象形式传入的数据。
2.5 verbosity:输出详细程度
verbosity取值为 0 到 4 的整数,值越高,审计时Datalab打印的信息越多,默认 1。它同时影响find_issues的过程输出与report的默认详细程度(report也可单独覆盖)。
三、发起审计:find_issues 的四个可选输入
find_issues是Datalab的核心方法,签名如下(datalab.py):
datalab.find_issues( *, pred_probs=None, # 模型预测概率 features=None, # 特征向量/嵌入 knn_graph=None, # 预计算的 KNN 稀疏矩阵 issue_types=None, # 自定义问题类型与参数 )重要说明:审计结果保存在datalab.issues属性中,find_issues本身不返回任何值;issue_types与knn_graph等参数均为关键字参数(keyword-only)。
3.1 输入与可检测问题类型的对应关系
find_issues与模型之间只通过"预测概率 / 嵌入 / 由它们衍生的 KNN 图"交互。提供的输入越多,能检测的问题类型越多;如果只提供部分输入,Datalab会基于有限信息输出它能得到的结论。各输入与问题类型的对应关系见 issue_finder.py_CLASSIFICATION_ARGS_DICT:
| 输入 | 主要服务的问题类型 |
|---|---|
pred_probs | label(标签错误)、outlier、non_iid、underperforming_group |
features | outlier、near_duplicate、non_iid、data_valuation、null、label(当没有 pred_probs 时用于拟合 KNN 模型生成预测) |
knn_graph | outlier、near_duplicate、non_iid、data_valuation、underperforming_group |
无(仅class_imbalance) | 类不平衡检测不需要任何模型输入 |
优先级规则(源码 issue_finder.py 已明示):
- 同时提供
knn_graph与features时,knn_graph优先(大多数问题管理器会优先使用 KNN 图以提高效率,同时会打印警告); - 只提供
features时,内部会基于欧氏或余弦距离构建knn_graph; - 两者都不提供时,
near_duplicate(近似重复)等问题将不会被检测; - 提供
cluster_ids(与knn_graph/features同时)时,cluster_ids优先于自动聚类。
3.2 pred_probs:三种任务的形状要求
| 任务 | 形状要求 |
|---|---|
| 分类 | 二维数组(num_examples, K),K为类别数;列顺序必须与类别排序一致,Datalab 采用按类别名词典序排列 |
| 回归 | 一维数组(num_examples,),每行是该样本的预测值 |
| 多标签 | 二维数组(num_examples, K),列顺序同样按类别名词典序 |
要最准确地检测标签问题,应提供你能训练出的最准确模型的样本外(out-of-sample)预测概率(例如通过交叉验证产生)。
3.3 features:特征嵌入的要求
features是每个样本的特征向量表示,必须是二维数组(num_examples, num_features)。它可以是来自(预)训练模型的嵌入,也可以是对原始特征做数值化变换的结果。
3.4 knn_graph:预计算 KNN 图(CSR 稀疏矩阵)
knn_graph是样本间距离的 K 近邻图,必须以scipy 的 CSR 稀疏矩阵形式传入,要求:
- 方阵,形状
(num_examples, num_examples),非零项总数约k * num_examples(k为每个样本的邻居数),且均匀分布在各行; - 每个非零项是两个样本间的距离,对角线必须全零(自距离省略,邻居不含自身);
- 每行内的距离需按升序排列(
data数组的对应分段内),indices保持同步; - 重复样本(距离为 0)应存储显式零:
knn_graph[i, j] = 0; - 对于距离为 0 的重复样本对,必须显式存零。
CSR 格式的三个一维数组含义如下:
data:按行存放矩阵全部非零元素(每行内部已排序);indices:每个非零元素对应的列索引,与data一一对应;indptr:每行非零元素在data中的起止下标,第i行的元素位于data[indptr[i]]到data[indptr[i+1]]。
文档中的示例:
knn_graph.todense() # matrix([[0. , 0.3, 0.2], # [0.3, 0. , 0.4], # [0.2, 0.4, 0. ]]) knn_graph.data # array([0.2, 0.3, 0.3, 0.4, 0.2, 0.4]) # 第一行的升序距离为 0.2、0.3;第二行为 0.3、0.4;依此类推。 knn_graph.indices # array([2, 1, 0, 2, 0, 1]) # 与 data 中距离对应的邻居列索引。 knn_graph.indptr # array([0, 2, 4, 6]) # 第一行非零项存于 data[0]~data[2],第二行存于 data[2]~data[4],依此类推。这类矩阵可以直接由sklearn.neighbors.NearestNeighbors.kneighbors_graph(mode="distance")生成。注意:请直接传入稀疏矩阵本身,不要传knn_graph.toarray()转换后的稠密矩阵。
3.5 issue_types:定制审计内容
issue_types是一个"字典的字典":键是感兴趣的问题类型,值是对应IssueManager构造参数组成的字典。不传则使用默认问题类型集合与推荐参数。
最简单的定制——只审计标签问题:
issue_types = {"label": {}} lab.find_issues(pred_probs=pred_probs, issue_types=issue_types)进阶定制——向LabelIssueManager构造器传参(例如指定CleanLearning的prune_method):
issue_types = { "label": { "clean_learning_kwargs": { "prune_method": "prune_by_noise_rate", }, }, } lab.find_issues(pred_probs=pred_probs, issue_types=issue_types)边界行为:如果传入空的issue_types={},find_issues会打印警告"未指定问题类型因此不会在数据集中找到任何问题",并直接返回(datalab.py)。
3.6 三个可直接运行的完整示例
方式一:只传 pred_probs
from sklearn.linear_model import LogisticRegression import numpy as np from cleanlab import Datalab X = np.array([[0, 1], [1, 1], [2, 2], [2, 0]]) y = np.array([0, 1, 1, 0]) clf = LogisticRegression(random_state=0).fit(X, y) pred_probs = clf.predict_proba(X) lab = Datalab(data={"X": X, "y": y}, label_name="y") lab.find_issues(pred_probs=pred_probs)方式二:只传 features
from sklearn.linear_model import LogisticRegression import numpy as np from cleanlab import Datalab X = np.array([[0, 1], [1, 1], [2, 2], [2, 0]]) y = np.array([0, 1, 1, 0]) lab = Datalab(data={"X": X, "y": y}, label_name="y") lab.find_issues(features=X)方式三:传预计算 knn_graph
from sklearn.neighbors import NearestNeighbors import numpy as np from cleanlab import Datalab X = np.array([[0, 1], [1, 1], [2, 2], [2, 0]]) y = np.array([0, 1, 1, 0]) nbrs = NearestNeighbors(n_neighbors=2, metric="euclidean").fit(X) knn_graph = nbrs.kneighbors_graph(mode="distance") lab = Datalab(data={"X": X, "y": y}, label_name="y") lab.find_issues(knn_graph=knn_graph)官方文档建议:同时传pred_probs和features可以获得更全面的审计结果。
3.7 find_issues 的底层执行流程
从源码看,find_issues最终委托给IssueFinder(issue_finder.pyIssueFinder.find_issues),其执行链路为:
- 根据传入输入解析每个问题类型所需的参数(
_resolve_required_args_for_*系列函数); - 通过
_IssueManagerFactory.from_list从注册表REGISTRY实例化对应的问题管理器; - 逐个运行
IssueManager.find_issues(**arg_dict),并将结果收集进DataIssues(collect_statistics+collect_issues_from_issue_manager); - 单个问题管理器失败不会中断整体审计,而是被记录并最终打印"Failed to check for these issue types";
- 最后调用
set_health_score()计算数据集整体健康分(当前实现为各类问题 score 的均值,见 data_issues.py)。
此外,当数据集没有标签时(label_name未提供),label、class_imbalance等问题类型会被自动跳过并给出警告(issue_finder.pyget_available_issue_types)。
四、默认审计的问题类型与任务相关注册表
当issue_types未指定时,Datalab使用各任务的默认问题类型集合(issue_manager_factory.pylist_default_issue_types):
| 任务 | 默认审计的问题类型 |
|---|---|
| 分类 | null、label、outlier、near_duplicate、non_iid、class_imbalance、underperforming_group |
| 回归 | null、label、outlier、near_duplicate、non_iid |
| 多标签 | null、label、outlier、near_duplicate、non_iid |
而完整的可能问题类型注册表REGISTRY(即list_possible_issue_types()返回的内容,见 issue_manager_factory.py)为:
| 任务 | 全部已注册问题类型 |
|---|---|
| 分类 | outlier、label、near_duplicate、non_iid、class_imbalance、underperforming_group、data_valuation、null |
| 回归 | label、outlier、near_duplicate、non_iid、data_valuation、null |
| 多标签 | label、outlier、near_duplicate、non_iid、data_valuation、null |
对于图像数据集(指定了image_key),list_possible_issue_types()与list_default_issue_types()都会追加DEFAULT_CLEANVISION_ISSUES中的图像问题类型(datalab.py)。注意data_valuation(数据估值)属于"可能"但不在默认审计集合中的问题类型,需要显式传入issue_types才会运行。
4.1 每种问题类型的三种输出估计
对每种问题类型(以<ISSUE_NAME>代称),Datalab会产出三类估计:
- 逐样本质量分
<ISSUE_NAME>_score:0~1 的数值,越接近 0 表示该样本越严重地表现出此问题;通过datalab.issues属性或datalab.get_issues("<ISSUE_NAME>")访问; - 逐样本布尔标记
is_<ISSUE_NAME>_issue:True表示估计该样本存在此问题; - 数据集整体分:0~1,量化该问题在整个数据集上的严重程度,分数越高表示整体越健康;通过
datalab.issue_summary属性或datalab.get_issue_summary("<ISSUE_NAME>")访问。
以outlier为例:
issue_name = "outlier" # 代码中的引用名 issue_score = "outlier_score" # 质量分列名,越典型的异常点分数越低 is_issue = "is_outlier_issue" # 布尔标记列名横向可比性提醒:同一种问题类型的分数可以在不同样本、不同数据集之间比较,但不同类型问题之间的分数不可互相比较(例如标签质量用标签似然估计,而异常点质量用特征空间 KNN 距离估计,两者本质不可比)。某些问题类型(如non_iid)的整体分并非逐样本分数的均值,而是数据集的全局统计量(如数据为 IID 这一假设检验的 p 值)。
数据集级 vs 样本级问题:non_iid、class_imbalance、underperforming_group属于主要关乎整个数据集的问题,应优先通过get_issue_summary的全局分来考察;而label、outlier、near_duplicate、null属于主要关乎单个样本的问题,可放心用get_issues逐样本查看。
4.2 每种问题类型所需的模型输入
不同问题类型的检测依赖不同的输入,可从 issue_finder.py 参数表 归纳:
| 问题类型 | 需要的输入 |
|---|---|
label | 分类:pred_probs(或features);回归:features+ 预测值;多标签:pred_probs |
outlier | 分类:pred_probs/features/knn_graph之一;其余任务:features/knn_graph |
near_duplicate | features或knn_graph |
non_iid | 分类:pred_probs/features/knn_graph;其余任务:features/knn_graph |
underperforming_group | pred_probs+(features/knn_graph/cluster_ids三者之一) |
data_valuation | features或knn_graph |
class_imbalance | 无(仅需标签) |
null | features |
IssueFinder会自动剔除"输入不足"的问题类型,因此你可以放心只提供部分输入。
五、查看审计结果:属性与查询方法
5.1 属性速查表
| 属性 | 类型 | 内容 |
|---|---|---|
datalab.issues | pd.DataFrame | 逐样本问题标记与质量分 |
datalab.issue_summary | pd.DataFrame | 各问题类型整体汇总(列:issue_type、score、num_issues) |
datalab.info | dict | 每个问题类型的详细信息与统计(含statistics键,存放样本数、类别数、健康分等) |
datalab.labels | np.ndarray/List[List[int]] | 标签([0, ..., K-1]格式) |
datalab.has_labels | bool | 是否有标签且为整数格式 |
datalab.class_names | List[str] | 类别名列表(无标签时为空列表) |
datalab.data | Dataset | 内部的 Hugging Face Dataset |
datalab.cleanlab_version | str | 创建该对象的 cleanlab 版本 |
issue_summary示例:
>>> datalab.issue_summary issue_type score outlier 0.123 label 0.456info示例(同时检测了 label 与 outlier):
>>> datalab.info { "label": { "given_labels": [0, 1, 0, 1, 1, 1, 1, 1, 0, 1, ...], "predicted_label": [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, ...], ..., }, "outlier": { "nearest_neighbor": [3, 7, 1, 2, 8, 4, 5, 9, 6, 0, ...], "distance_to_nearest_neighbor": [0.123, 0.789, 0.456, ...], ..., }, }5.2 查询方法
| 方法 | 说明 |
|---|---|
get_issues(issue_name=None) | 返回逐样本问题 DataFrame。issue_name=None时返回全部类型;指定时只返回该类型相关列(label会附带given_label/predicted_label列,near_duplicate会附带near_duplicate_sets/distance_to_nearest_neighbor列)。非法名称抛出ValueError |
get_issue_summary(issue_name=None) | 返回问题汇总 DataFrame;None时返回全部 |
get_info(issue_name=None) | 返回指定问题类型的详细信息字典;未计算时抛出ValueError |
list_possible_issue_types() | 返回所有已注册、可在find_issues中使用的问题类型 |
list_default_issue_types() | 返回不指定issue_types时默认运行的问题类型 |
get_issues的实现位于 data_issues.pyDataIssues.get_issues:当issues为空(未执行find_issues)时会给出详细提示的ValueError。数据统计(样本数、类别名、类别数、健康分)则通过get_info("statistics")或DataIssues.statistics属性获取(data_issues.pyget_data_statistics)。
六、生成可读报告:report 方法
datalab.report( *, num_examples=5, # 每种问题展示的 top 样本数 verbosity=None, # 覆盖构造时的 verbosity(默认沿用) include_description=True, # 是否包含每种问题的文字描述 show_summary_score=False, # 是否显示整体严重度分数列 show_all_issues=False, # 是否展示所有被检查过的问题类型(含未检测到的) )各参数行为(datalab.pyreport):
num_examples:报告对每种问题类型展示受害最严重的 top N 个样本;verbosity:更高等级会向报告中加入更多信息(每种IssueManager各自定义各等级追加的内容,例如LabelIssueManager在第 3 级会加入classes_by_label_quality与overlapping_classes,见 label.py);include_description:熟悉各类问题定义后可设为False以精简输出;show_summary_score:是否显示每种问题的整体严重度分。注意这些分数在不同问题类型之间不可比较;show_all_issues:设为True时,报告会包含所有被检查过的问题类型(包括在数据中未检测到的问题类型)。
报告实现位于 report.pyReporter.get_report:先按num_issues降序输出汇总表,再逐一调用各问题管理器的report类方法拼接各问题详情。报告头部会打印数据集信息(num_examples、num_classes);当数据中没有任何问题时,会输出 "No issues found in the data. Good job!",并建议用show_summary_score=True与show_all_issues=True重跑以查看完整信息(report.py)。
七、持久化:save 与 load
Datalab支持将审计结果保存到磁盘并在之后重新加载:
datalab.save(path="my_datalab/", force=False) datalab_loaded = Datalab.load(path="my_datalab/", data=None)要点(datalab.py 与 serialize.py_Serializer):
save会在path目录下生成:datalab.pkl(对象本身)、issues.csv、summary.csv以及data/子目录(数据集副本);force=False且目录已存在时抛出FileExistsError;- 数据集本身不会被保存在
Datalab内,如需保留数据请自行另存; load时若传入data,会校验数据哈希与长度是否与保存时一致,不一致则报错;- cleanlab 不保证旧版本保存的
Datalab能被未来版本加载;版本不一致时load会打印警告("Things may be broken!")。
八、扩展机制:自定义问题类型
Datalab通过工厂 + 注册表机制支持自定义问题类型(issue_manager_factory.pyregister)。任何IssueManager子类都可以被注册进REGISTRY,之后即可像内置问题类型一样在find_issues(issue_types={...})中使用。
from cleanlab.datalab.internal.issue_manager.issue_manager import IssueManager from cleanlab.datalab.internal.issue_manager_factory import register @register class MyIssueManager(IssueManager): issue_name: str = "my_issue" def find_issues(self, **kwargs): # 实现具体的问题检测逻辑 pass或采用函数调用式注册:
register(MyIssueManager, task="classification")IssueManager基类(issue_manager.py)要求每个问题管理器为每个样本计算:
- 0~1 的严重度分数(越接近 0 越严重);
- 布尔
is_issue标记(可通过阈值化分数得到,或像 Confident Learning 那样用其他方式判定); - 数据集整体严重度(如所有样本分数均值或
is_issue=True的样本数); - 其他有用的
info(例如标签问题的confident_thresholds、confident_joint、预测标签;近似重复问题的重复样本集合等)。
注意:注册表与工厂属于内部实现细节,文档明确警告不应被普通用户直接使用;@register装饰器注册同名问题类型时会打印覆盖警告。
九、从源码与测试看典型用法
仓库测试 test_datalab.py 覆盖了Datalab的典型生命周期:构造(非法DatasetDict校验)、print/__repr__输出、class_names、list_default_issue_types、get_info、get_issue_summary、get_issues、带pred_probs的find_issues、空issue_types警告、自定义超参数、重复find_issues后report、save/load/pickle往返、失败问题管理器容错、knn_graph与features的优先级等。
最小可用流程总结如下:
from cleanlab import Datalab # 1. 构造 lab = Datalab(data=dataset, label_name="label", task="classification") # 2. 审计(pred_probs 需为样本外预测概率) lab.find_issues(pred_probs=pred_probs, features=features) # 3. 查看结果 lab.report() # 人类可读报告 lab.get_issues("label") # 标签问题逐样本详情 lab.get_issue_summary() # 各问题类型汇总 lab.info["statistics"] # 数据集统计与健康分 # 4. 持久化(可选) lab.save(path="audit_result/")一个实用的惯例是:先用lab.find_issues(features=X)做一次"无需训练模型"的初步审计(覆盖异常点、近似重复、非 IID、空值等),再补充pred_probs进行完整审计(覆盖标签错误、类不平衡、欠表现分组等)。
十、适用前提与注意事项
- 可选依赖:
Datalab依赖datasets包(图像审计还依赖cleanvision),请通过pip install "cleanlab[all]"安装全部可选依赖; - pred_probs 列序:分类与多标签任务的
pred_probs列必须按类别名词典序排列,否则标签审计结果会错位; - knn_graph 格式:必须是符合 CSR 规范、对角线为零、行内升序的稀疏矩阵,重复样本对须显式存零;
- 输入不足时的问题降级:不提供
pred_probs/features/knn_graph,相应问题类型会自动被跳过,这是设计行为而非错误; - 分数可比性边界:同类型问题的分数可跨样本/跨数据集比较,不同类型之间不可比较;
- 持久化兼容性:
save的结果不保证被未来 cleanlab 版本加载。
结语
Datalab将 cleanlab 的数据中心 AI 能力收敛为"一个对象、一次调用",覆盖从构造、审计、查询、报告到持久化的完整数据质量工作流。结合 datalab.py 源码及其内部组件(issue_finder.py、data_issues.py、issue_manager_factory.py、report.py),你可以按需定制审计内容,甚至注册自己的问题类型,将数据质量审计变成可复用、可解释、可扩展的标准流程。
【免费下载链接】cleanlabCleanlab's open-source library is the standard>项目地址: https://gitcode.com/GitHub_Trending/cl/cleanlab
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考