使用Cleanlab检测文本数据集中的问题
在本篇5分钟快速入门教程中,我们使用Cleanlab检测在线银行客户服务请求(文本)组成意图分类数据集中的各种问题。我们考虑了Banking77-OOS数据集的一个子集,其中包含1000个客户服务请求,根据其意图将其分类为10个类别(您可以在任何文本分类数据集上运行相同的代码)。Cleanlab自动识别我们数据集中不良的示例,包括错误标记的数据、超出范围的示例(异常值)或其他模棱两可的示例。在深入建模数据之前,请考虑过滤或更正此类不良示例!
本教程中我们将执行的操作概述
使用预训练的Transformer模型从客户服务请求中提取文本嵌入
在文本嵌入上训练一个简单的逻辑回归模型,以计算样本外预测概率
使用这些预测和嵌入运行Cleanlab的
Datalab
审计,以识别诸如:标签问题、异常值和数据集中的近似重复等问题。
快速入门
已经从在现有标签集上训练的模型中获得了(样本外)pred_probs
?也许您也有一些数值型features
?运行以下代码以查找数据集中任何潜在的标签错误。
注意:如果在Colab上运行,可能需要使用GPU(选择:运行时 > 更改运行时类型 > 硬件加速器 > GPU)
from cleanlab import Datalab
lab = Datalab(data=your_dataset, label_name="column_name_of_labels")
lab.find_issues(pred_probs=your_pred_probs, features=your_features)
lab.report()
lab.get_issues()
安装所需依赖项
您可以使用pip
安装本教程所需的所有软件包,如下所示
!pip install -U scikit-learn sentence-transformers datasets
!pip install -U "cleanlab[datalab]"
import re
import string
import pandas as pd
from sklearn.metrics import accuracy_score, log_loss
from sklearn.model_selection import cross_val_predict
from sklearn.linear_model import LogisticRegression
from sentence_transformers import SentenceTransformer
from cleanlab import Datalab
import random
import numpy as np
pd.set_option("display.max_colwidth", None)
SEED = 123456 # for reproducibility
np.random.seed(SEED)
random.seed(SEED)
加载并格式化文本数据集
from datasets import load_dataset
dataset = load_dataset("PolyAI/banking77", split="train")
data = pd.DataFrame(dataset[:1000])
data.head()
>>> raw_texts, labels = data["text"].values, data["label"].values
>>> num_classes = len(set(labels))
>>> print(f"This dataset has {num_classes} classes.")
>>> print(f"Classes: {set(labels)}")
This dataset has 7 classes. Classes: {32, 34, 36, 11, 13, 46, 17}
让我们查看数据集中第 i 个示例
>>> i = 1 # change this to view other examples from the dataset
>>> print(f"Example Label: {labels[i]}")
>>> print(f"Example Text: {raw_texts[i]}")
Example Label: 11 Example Text: What can I do if my card still hasn't arrived after 2 weeks?
数据存储为两个 NumPy 数组
raw_texts
以文本格式存储客户服务请求话语labels
存储每个示例的意图类别(标签)
您可以轻松地将上述内容替换为您自己的文本数据集,并继续本教程的其余部分。
接下来,我们将文本字符串转换为更适合作为机器学习模型输入的向量。
我们将使用预训练 Transformer 模型中的数字表示作为我们文本的嵌入。 句子转换器 库提供了用于计算文本数据这些嵌入的简单方法。在这里,我们加载预训练的 electra-small-discriminator
模型,然后将我们的数据通过网络运行以提取每个示例的向量嵌入。
transformer = SentenceTransformer("google/electra-small-discriminator")
text_embeddings = transformer.encode(raw_texts)
我们随后的机器学习模型将直接对 text_embeddings
的元素进行运算,以便对客户服务请求进行分类。
定义分类模型并计算样本外预测概率
利用预训练网络执行特定分类任务的一种典型方法是添加线性输出层,并在新数据上微调网络参数。但是,这在计算上可能很密集。或者,我们可以冻结网络的预训练权重,并且只训练输出层,而无需依赖 GPU。在这里,我们通过在提取的嵌入之上拟合 scikit-learn 线性模型来方便地做到这一点。
为了识别标签问题,cleanlab 需要模型对每个数据点进行概率预测。但是,对于模型先前训练过的数据点,这些预测将是过拟合的(因此不可靠)。cleanlab 旨在仅用于样本外预测类概率,即在训练期间从模型中排除的数据点上。
在这里,我们使用带有交叉验证的逻辑回归模型,获取数据集每个示例的样本外预测类概率。确保 pred_probs
的列相对于类的排序顺序正确排序,对于 Datalab 而言,该顺序为:按类名进行词典排序。
model = LogisticRegression(max_iter=400)
pred_probs = cross_val_predict(model, text_embeddings, labels, method="predict_proba")
使用 Cleanlab 查找数据集中的问题
给定特征嵌入和从任何模型获得的(样本外)预测类概率,cleanlab 可以快速帮助您识别数据集中质量较低的示例。
在这里,我们使用 Cleanlab 的 Datalab
来查找数据中的问题。Datalab 提供了几种加载数据的方法;我们将简单地将训练特征和噪声标签包装在一个字典中。
data_dict = {"texts": raw_texts, "labels": labels}
审核数据所需的全部操作就是调用 find_issues()
。我们将上面获得的预测概率和特征嵌入传递进来,但根据您感兴趣的问题类型,您不一定需要提供所有这些信息。提供的输入越多,Datalab
可以在数据中检测到的问题类型就越多。使用更好的模型生成这些输入将确保 cleanlab 更准确地估计问题。
lab = Datalab(data_dict, label_name="labels")
lab.find_issues(pred_probs=pred_probs, features=text_embeddings)
输出将如下所示
Finding null issues ...
Finding label issues ...
Finding outlier issues ...
Fitting OOD estimator based on provided features ...
Finding near_duplicate issues ...
Finding non_iid issues ...
Finding class_imbalance issues ...
Finding underperforming_group issues ...
Audit complete. 62 issues found in the dataset.
审核完成后,使用 report
方法查看结果
>>> lab.report()
Here is a summary of the different kinds of issues found in the data: issue_type num_issues outlier 37 near_duplicate 14 label 10 non_iid 1 Dataset Information: num_examples: 1000, num_classes: 7 ---------------------- outlier issues ---------------------- About this issue: Examples that are very different from the rest of the dataset (i.e. potentially out-of-distribution or rare/anomalous instances). Number of examples with this issue: 37 Overall dataset quality in terms of this issue: 0.3671 Examples representing most severe instances of this issue: is_outlier_issue outlier_score 791 True 0.024866 601 True 0.031162 863 True 0.060738 355 True 0.064199 157 True 0.065075 ------------------ near_duplicate issues ------------------- About this issue: A (near) duplicate issue refers to two or more examples in a dataset that are extremely similar to each other, relative to the rest of the dataset. The examples flagged with this issue may be exactly duplicated, or lie atypically close together when represented as vectors (i.e. feature embeddings). Number of examples with this issue: 14 Overall dataset quality in terms of this issue: 0.5961 Examples representing most severe instances of this issue: is_near_duplicate_issue near_duplicate_score near_duplicate_sets distance_to_nearest_neighbor 459 True 0.009544 [429] 0.000566 429 True 0.009544 [459] 0.000566 501 True 0.046044 [412, 517] 0.002781 412 True 0.046044 [501] 0.002781 698 True 0.054626 [607] 0.003314 ----------------------- label issues ----------------------- About this issue: Examples whose given label is estimated to be potentially incorrect (e.g. due to annotation error) are flagged as having label issues. Number of examples with this issue: 10 Overall dataset quality in terms of this issue: 0.9930 Examples representing most severe instances of this issue: is_label_issue label_score given_label predicted_label 379 False 0.025486 32 11 100 False 0.032102 11 36 300 False 0.037742 32 46 485 True 0.057666 17 34 159 True 0.059408 13 11 ---------------------- non_iid issues ---------------------- About this issue: Whether the dataset exhibits statistically significant violations of the IID assumption like: changepoints or shift, drift, autocorrelation, etc. The specific violation considered is whether the examples are ordered such that almost adjacent examples tend to have more similar feature values. Number of examples with this issue: 1 Overall dataset quality in terms of this issue: 0.0000 Examples representing most severe instances of this issue: is_non_iid_issue non_iid_score 988 True 0.563774 975 False 0.570179 997 False 0.571891 967 False 0.572357 956 False 0.577413 Additional Information: p-value: 0.0
标签问题
报告表明,cleanlab 在我们的数据集中识别出许多标签问题。我们可以使用 get_issues
方法查看哪些示例被标记为可能标记错误,以及每个示例的标签质量分数,指定 label
作为参数来关注数据中的标签问题。
label_issues = lab.get_issues("label")
label_issues.head()
is_label_issue | label_score | given_label | predicted_label | |
---|---|---|---|---|
0 | False | 0.903926 | 11 | 11 |
1 | False | 0.860544 | 11 | 11 |
2 | False | 0.658309 | 11 | 11 |
3 | False | 0.697085 | 11 | 11 |
4 | False | 0.434934 | 11 | 11 |
此方法返回一个数据框,其中包含每个示例的标签质量分数。这些数值分数介于 0 和 1 之间,分数越低表示示例越有可能标记错误。数据框还包含一个布尔列,指定每个示例是否被识别为存在标签问题(表示其可能标记错误)。
我们可以获取标记有标签问题的示例的子集,并按标签质量分数排序,以查找数据集中 5 个最有可能标记错误的示例的索引。
>>> identified_label_issues = label_issues[label_issues["is_label_issue"] == True]
>>> lowest_quality_labels = label_issues["label_score"].argsort()[:5].to_numpy()
>>> print(
... f"cleanlab found {len(identified_label_issues)} potential label errors in the dataset.\n"
... f"Here are indices of the top 5 most likely errors: \n {lowest_quality_labels}"
... )
cleanlab found 10 potential label errors in the dataset. Here are indices of the top 5 most likely errors: [379 100 300 485 159]
让我们回顾一些最有可能的标签错误。
在这里,我们显示了数据集中被识别为最有可能的标签错误的前 5 个示例,以及它们的给定(原始)标签和来自 cleanlab 的建议替代标签。
data_with_suggested_labels = pd.DataFrame(
{"text": raw_texts, "given_label": labels, "suggested_label": label_issues["predicted_label"]}
)
data_with_suggested_labels.iloc[lowest_quality_labels]
上述命令的输出将如下所示
text | given_label | suggested_label | |
---|---|---|---|
379 | 我计划进行的转账的汇率是从哪个特定来源提取的? | 32 | 11 |
100 | 你能分享一下卡的追踪号码吗? | 11 | 36 |
300 | 如果我需要兑现外币转账,那该怎么办? | 32 | 46 |
485 | 我的货币兑换是否被多收了费用? | 17 | 34 |
159 | 有没有办法在应用程序中查看我的卡? | 13 | 11 |
这些是 cleanlab 在此数据中识别出的非常明显的标签错误!请注意,given_label
未能正确反映这些请求的意图,无论是谁制作此数据集,都犯了许多错误,在对数据建模之前必须解决这些错误。
异常值问题
根据报告,我们的数据集中包含一些异常值。我们可以通过 get_issues
查看哪些示例是异常值(以及一个量化每个示例在数据集中出现的典型程度的数值质量分数)。我们根据 cleanlab 的异常值质量分数对结果 DataFrame 进行排序,以查看数据集中最严重的异常值。
outlier_issues = lab.get_issues("outlier")
outlier_issues.sort_values("outlier_score").head()
输出将如下所示
is_outlier_issue | outlier_score | |
---|---|---|
791 | True | 0.024866 |
601 | True | 0.031162 |
863 | True | 0.060738 |
355 | True | 0.064199 |
157 | True | 0.065075 |
lowest_quality_outliers = outlier_issues["outlier_score"].argsort()[:5]
data.iloc[lowest_quality_outliers]
最低质量异常值的示例输出将如下所示
index | text | label |
---|---|---|
791 | 提取挂起是什么意思? | 46 |
601 | 交易中收取 1 美元费用。 | 34 |
863 | 我的 ATM 取款仍在挂起 | 46 |
355 | 解释银行间汇率 | 32 |
157 | 丢失的卡已找到,想要将其放回应用程序 | 13 |
我们看到 cleanlab 已经识别出此数据集中似乎不是正确的客户请求的条目。此数据集中异常值似乎是超出范围的客户请求和其他与意图分类无关的无意义文本。仔细考虑此类异常值是否会对您的数据建模产生不利影响,如果会,请考虑将其从数据集中删除。
近似重复问题
根据报告,我们的数据集中包含一些近似重复的示例集。我们可以通过 get_issues
查看哪些示例是(近似)重复的(以及量化每个示例与其在数据集中最近邻的不同程度的数值质量分数)。我们根据 cleanlab 的近似重复质量分数对结果 DataFrame 进行排序,以查看数据集中最接近重复的文本示例。
duplicate_issues = lab.get_issues("near_duplicate")
duplicate_issues.sort_values("near_duplicate_score").head()
上述结果显示了 cleanlab 认为哪些示例是近似重复的(其中 is_near_duplicate_issue == True
的行)。在这里,我们看到示例 459 和 429 是近似重复的,示例 501 和 412 也是如此。
让我们查看这些示例以了解它们有多相似。
data.iloc[[459, 429]]
示例输出
index | text | label |
---|---|---|
459 | 我在国外购买了一些东西,但使用了错误的汇率。 | 17 |
429 | 我在海外购买了一些东西,但使用了错误的汇率。 | 17 |
data.iloc[[501, 412]]
示例输出
index | text | label |
---|---|---|
501 | 你使用的汇率非常糟糕。这不可能是官方的银行间汇率。 | 17 |
412 | 你使用的汇率很糟糕。这不可能是官方的银行间汇率。 | 17 |
我们发现这两组请求确实非常相似!在数据集中包含近似重复项可能会对模型产生意外影响,并且要注意不要将它们拆分到训练/测试集中。从常见问题解答了解有关处理数据集中近似重复项的更多信息。
非独立同分布问题(数据漂移)
根据报告,我们的数据集似乎不是独立同分布 (IID) 的。数据集的整体非 IID 分数(显示在下方)对应于统计检验的p 值
,该检验用于确定数据集中样本的排序是否与其特征值之间的相似性相关。较低的p 值
强烈表明数据集违反了 IID 假设,这是从数据集中产生的结论(模型)泛化到更大群体所需的关键假设。
p_value = lab.get_info("non_iid")["p-value"]
p_value
在这里,我们的数据集被标记为非 IID,因为行恰好按原始数据中的类别标签排序。如果我们记得在模型训练和数据分割之前打乱行,这可能是良性的。但是,如果您不知道为什么您的数据被标记为非 IID,那么您应该担心潜在的数据漂移或数据点之间意外的交互(它们的值可能在统计上不独立)。仔细考虑未来的测试数据可能是什么样子(以及您的数据是否代表您关心的总体)。您不应该在非 IID 测试运行之前打乱您的数据(这会使其结论无效)。
如上所示,cleanlab 可以自动筛选出数据集中最可能出现的问题,以帮助您更好地整理数据集以进行后续建模。使用此筛选列表,您可以决定是否修复这些标签问题或从数据集中删除无意义或重复的示例,以获得用于训练下一个机器学习模型的更高质量的数据集。cleanlab 的问题检测可以使用您最初训练的任何类型模型的输出运行。
Cleanlab 开源项目
Cleanlab 是一个标准的数据中心 AI 软件包,旨在解决凌乱的真实世界数据的质量问题。
请考虑为 Cleanlab Github 仓库加星,我们欢迎为该项目做出贡献。
< > 在 GitHub 上更新