在 Colab 中打开  在 GitHub 上查看 Notebook

🎮 监控数据和模型漂移的真实世界示例#

在本教程中,我们将探索数据和模型漂移经常发生的典型真实世界场景和工作流程,并演示如何使用不同的工具(如 ArgillaOllamaBerTopicTextDescriptives)有效地监控这些变化。

我们将遵循的步骤是

  • 准备示例数据集

  • 使用历史数据微调分类器

  • 使用来自 OllamaGemma 模拟数据漂移

  • 展示如何使用 Argilla 监控数据漂移

  • 使用 BerTopicTextDescriptives 分析数据漂移

简介#

训练机器学习模型需要大量数据。因此,从业者通常使用当前数据集来训练模型,直到达到令人满意的质量。然而,随着时间的推移,模型的性能可能会开始下降,这种现象被称为模型漂移。了解这种情况发生的原因对于有效处理问题至关重要。

模型漂移的主要原因之一是数据漂移,指的是数据分布或统计数据随时间的变化。当模型遇到与其训练集不同的新数据时,其预测准确性可能会下降。例如,由于语言和电子邮件格式的变化,十年前训练的垃圾邮件分类器可能无法准确分类今天的电子邮件。

因此,尽早识别数据漂移至关重要。这样做需要识别两种主要类型的数据漂移

  1. 概念漂移:当输入数据和输出之间的关系发生变化,导致以前的关联变得无关紧要时,就会发生这种情况。随着时间的推移,某些概念的含义可能会发生变化,从而影响其在模型计算中的权重。概念漂移可以以多种方式表现出来,包括

    • 突发漂移,即一个新概念突然出现。COVID-19 的出现就是例证。

    • 渐变漂移,即一个新概念逐渐地、交替地与现有概念融合。

    • 增量漂移,即一个新概念随着时间的推移慢慢建立起来。

    • 复发概念,即以前遇到过的概念重新出现。

concept-drift-type.png

  1. 协变量偏移:当输入数据本身发生变化,但输出数据没有随之变化时,就会发生这种情况。

几种方法和指标可以帮助检测机器学习中的数据漂移,包括数据质量评估、Kolmogorov-Smirnov 检验、卡方检验、群体稳定性指数、Earth-Mover 距离、Kullback-Leibler 散度和 Jensen-Shannon 散度等。在自然语言处理 (NLP) 领域,监控输入文本数据中是否存在漂移迹象尤为重要。此外,手动标注测试数据集是一种有价值的质量控制措施,可以评估模型的持续性能,并有助于及时调整以减轻数据漂移的影响。

在本教程中,我们将重现一个真实场景,在该场景中,我们将监控在视频游戏评论数据集上训练的情感分类器模型。我们将通过测试新评论并分析这些变化对模型性能的影响来模拟和分析数据漂移。

运行 Argilla#

对于本教程,您需要运行 Argilla 服务器。部署和运行 Argilla 有两个主要选项

在 Hugging Face Spaces 上部署 Argilla:如果您想使用外部 Notebook(例如 Google Colab)运行教程,并且您在 Hugging Face 上有一个帐户,则只需点击几下即可在 Spaces 上部署 Argilla

deploy on spaces

有关配置部署的详细信息,请查看 官方 Hugging Face Hub 指南

使用 Argilla 的快速入门 Docker 镜像启动 Argilla:如果您想在 本地计算机上运行 Argilla,建议使用此选项。请注意,此选项仅允许您在本地运行教程,而不能使用外部 Notebook 服务。

有关部署选项的更多信息,请查看文档的部署部分。

提示

本教程是一个 Jupyter Notebook。有两种运行它的选项

  • 使用此页面顶部的“在 Colab 中打开”按钮。此选项允许您直接在 Google Colab 上运行 Notebook。不要忘记将运行时类型更改为 GPU 以加快模型训练和推理速度。

  • 通过单击页面顶部的“查看源代码”链接下载 .ipynb 文件。此选项允许您下载 Notebook 并在本地计算机或您选择的 Jupyter Notebook 工具上运行它。

设置环境#

要完成本教程,您需要使用 pip 安装 Argilla 客户端和一些第三方库

[ ]:
# %pip install --upgrade pip
%pip install argilla -qqq
%pip install datasets
%pip install transformers
%pip install ollama

# Optional packages for further analysis
%pip install bertopic
%pip install textdescriptives
%pip install seaborn

让我们进行所需的导入

[ ]:
import re
import pandas as pd
import nltk
import spacy
import seaborn as sns
import matplotlib.pyplot as plt

from datasets import load_dataset
from transformers import pipeline
from bertopic import BERTopic
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
import textdescriptives as td

import argilla as rg
from argilla.feedback import TrainingTask, ArgillaTrainer

import ollama

nltk.download('punkt')
nltk.download('stopwords')

如果您使用 Docker 快速入门镜像或公共 Hugging Face Spaces 运行 Argilla,则需要使用 URLAPI_KEY 初始化 Argilla 客户端

[2]:
# Replace api_url with the url to your HF Spaces URL if using Spaces
# Replace api_key if you configured a custom API key
# Replace workspace with the name of your workspace
rg.init(
    api_url="https://#:6900",
    api_key="argilla.apikey",
    workspace="argilla"
)

如果您运行的是私有 Hugging Face Space,您还需要按如下方式设置 HF_TOKEN

[ ]:
# # Set the HF_TOKEN environment variable
# import os
# os.environ['HF_TOKEN'] = "your-hf-token"

# # Replace api_url with the url to your HF Spaces URL
# # Replace api_key if you configured a custom API key
# rg.init(
#     api_url="https://[your-owner-name]-[your_space_name].hf.space",
#     api_key="admin.apikey",
#     extra_headers={"Authorization": f"Bearer {os.environ['HF_TOKEN']}"},
# )

启用遥测#

我们从您与教程的互动中获得了宝贵的见解。为了改进我们自己,为您提供最合适的内容,使用以下代码行将帮助我们了解本教程是否有效地为您服务。虽然这是完全匿名的,但如果您愿意,可以选择跳过此步骤。有关更多信息,请查看 遥测 页面。

[ ]:
try:
    from argilla.utils.telemetry import tutorial_running
    tutorial_running()
except ImportError:
    print("Telemetry is introduced in Argilla 1.20.0 and not found in the current installation. Skipping telemetry.")

准备数据#

为了模拟数据漂移,我们将使用 LoganKells/amazon_product_reviews_video_games 数据集,其中包含来自亚马逊的视频游戏评论及其相应的评分和时间戳。

[3]:
# Load the dataset
hf_dataset_games = load_dataset("LoganKells/amazon_product_reviews_video_games", split= "train[:10000]")
[4]:
hf_dataset_games
[4]:
Dataset({
    features: ['Unnamed: 0', 'reviewerID', 'asin', 'reviewerName', 'helpful', 'reviewText', 'overall', 'summary', 'unixReviewTime', 'reviewTime'],
    num_rows: 10000
})

首先,我们将对数据进行一些预处理,以保留所需的列:游戏评论、给定的评分和日期。

[5]:
# Convert to a pandas dataframe
df_games = hf_dataset_games.to_pandas()

# Convert the UnixReviewTime to a datetime
df_games['datetime'] = pd.to_datetime(df_games['unixReviewTime'], unit='s')

# Select the columns we want to keep
df_games = df_games[["reviewText", "overall", "datetime"]]
df_games = df_games.rename(columns={"reviewText": "review", "overall": "rating"})
df_games.head()
[5]:
评论 评分 日期时间
0 安装游戏很困难(因为... 0.0 2012-07-09
1 如果您喜欢拉力赛车,您会喜欢这款游戏... 3.0 2013-06-30
2 第一次发货收到的是书而不是游戏... 0.0 2014-06-28
3 我在 Xbox 360 上玩过 Dirt 2,这是一款还不错的游戏... 3.0 2011-06-14
4 总的来说,这是一款制作精良的赛车游戏,具有... 3.0 2013-05-11

然后,我们将数据集分为两部分:参考数据集,即模型学习的历史数据;以及当前数据集,我们想要测试的新数据。我们将模拟我们的模型是在 1999 年至 2004 年的评论上训练的,但现在我们正在 2010 年至 2014 年的评论上对其进行测试。

[6]:
# Divide the dataset into two parts
ref_year = 2005
curr_year = 2010
df_reference = df_games[df_games['datetime'].dt.year < ref_year]
df_current = df_games[df_games['datetime'].dt.year >= curr_year]

print(f"Reference dataset: {df_reference.shape[0]} reviews")
print(f"Current dataset: {df_current.shape[0]} reviews")
Reference dataset: 4705 reviews
Current dataset: 3443 reviews

我们还将定义一些变量并创建一些函数,以在以下部分中帮助我们。

[7]:
# To create a feedback dataset
def create_feedback_dataset():
    dataset = rg.FeedbackDataset.for_text_classification(
        labels=["very-positive", "positive", "neutral", "negative", "very-negative"],
        multi_label=False,
        use_markdown=True,
        guidelines=None,
        metadata_properties=[
            rg.TermsMetadataProperty(
            name="datetime",
            title="Datetime",
        )],
        vectors_settings=None,
    )
    return dataset
[8]:
# To convert the rating to a label
id2label = {0.0: "very-negative", 1.0: "negative", 2.0: "neutral", 3.0: "positive", 4.0: "very-positive"}
[9]:
# Lists to store the first 300 reviews and datetimes
ref_reviews = df_reference["review"].head(300).tolist()
ref_datetime = df_reference["datetime"].head(300).tolist()

curr_reviews = df_current["review"].head(300).tolist()
curr_datetime = df_current["datetime"].head(300).tolist()

微调原始模型#

假设我们当前正在微调情感分类器模型,以预测视频游戏评论的情感。因此,按照常见的工作流程,我们创建一个 FeedbackDataset 以使用我们的数据并微调我们将在未来几年使用的模型。用于微调的数据是 1999 年至 2004 年的 4705 条评论。

训练可能需要一些时间才能完成,因此您可以修改 训练器参数 以使其更快或使用较小的数据集。

[ ]:
# Create the feedback dataset
ref_rg_ds = create_feedback_dataset()

records = [
    rg.FeedbackRecord(
        fields={"text": row["review"]},
        responses=[
            {
                "values": {
                    "label": {
                        "value": id2label[row["rating"]]
                    }
                }
            }
        ],
        metadata={
            "datetime": str(row["datetime"])
        }
    )
    for _ , row in df_reference.iterrows()
]

ref_rg_ds.add_records(records)
ref_rg_ds.push_to_argilla(name="reference_dataset", workspace="argilla")
[ ]:
# Fine-tune the model
task = TrainingTask.for_text_classification(
    text=ref_rg_ds.field_by_name("text"),
    label=ref_rg_ds.question_by_name("label"),
    label_strategy=None
)

trainer = ArgillaTrainer(
    dataset=ref_rg_ds,
    task=task,
    framework="transformers",
    train_size=0.8,
)

trainer.train(output_dir="model-drift-simulation")
{'eval_loss': 0.8788877129554749, 'eval_accuracy': 0.6354941551540914, 'eval_runtime': 944.7263, 'eval_samples_per_second': 0.996, 'eval_steps_per_second': 0.125, 'epoch': 1.0}
{'train_runtime': 10846.666, 'train_samples_per_second': 0.347, 'train_steps_per_second': 0.043, 'train_loss': 1.072760642302517, 'epoch': 1.0}

观察模型在验证数据集上的性能。如果结果满足我们的质量标准,我们可以继续在生产环境中部署模型。在我们的例子中,我们将想象性能足够好。

模拟数据漂移#

我们假设我们已经过去了五年。我们在这段时间内使用了我们的模型,但现在数据发生了变化。我们将使用最近可用的 Gemma 模型(Google 及其 DeepMind 团队开发的新开放模型),来自 Ollama 生成新评论来模拟这种变化。作为一项定期任务,模型性能的评估将在小型测试中进行,因此我们将使用 2010 年至 2014 年的前 300 条新评论。

Ollama 允许您在 MacOs、Windows 和 Linux 上本地运行 LLM。查看 官方文档 了解更多详细信息。

请注意,此过程可能需要一段时间,您可以选择跳过此步骤并下载创建的数据集。

dataset = load_dataset("sdiazlor/data-drift-simulation-dataset")

我们将编写一个系统提示来定义模型要执行的任务,并使用它来生成新评论。此外,我们将更改模型的参数,使其更具创造性并生成更多样化的评论。

[ ]:
modelfile='''
FROM gemma:7b-instruct
SYSTEM You are a professional video game reviewer. Your job is to write a new and ambiguous video game review inspired by the given one. Please provide the new review that is within 128 tokens, ensuring that no sentences are left incomplete. Directly provide the new review without any other information.
'''

ollama.create(model='data-drift-simulator', modelfile=modelfile)
[27]:
# Example of using the model
response = ollama.generate(
    model='data-drift-simulator',
    prompt="Installing the game was a struggle (because of games for windows live bugs).Some championship races and cars can only be 'unlocked' by buying them as an addon to the game. I paid nearly 30 dollars when the game was new. I don\'t like the idea that I have to keep paying to keep playing.I noticed no improvement in the physics or graphics compared to Dirt 2.I tossed it in the garbage and vowed never to buy another codemasters game. I\'m really tired of arcade style rally/racing games anyway.I\'ll continue to get my fix from Richard Burns Rally, and you should to. :)http://www.amazon.com/Richard-Burns-Rally-PC/dp/B000C97156/ref=sr_1_1?ie=UTF8&qid;=1341886844&sr;=8-1&keywords;=richard+burns+rallyThank you for reading my review! If you enjoyed it, be sure to rate it as helpful.",
    options={'num_predict':128}
    )
print(response["response"])
## Codemasters Rally - A Mixed Bag of Laps and Lameness

If you're in the market for a rally racer that'll have you slinging gravel and leaving your friends in the dust, Codemasters Rally might be... well... a bit of a mess.

Installing this game was a battle, thanks to the ever-present Windows Live bugs. And what's even more infuriating is that some championship races and cars are locked behind paywalls, demanding extra dough just to keep playing. I coughed up nearly $30 when the game was new, and I'm not thrilled about having to keep shelling out
[ ]:
# List to save the rewritten reviews
rewritten_reviews = []

# Define the initial parameters
temperature = 0.5
mirostat_tau = 6.0
num_predict = 128
top_k = 40
top_p = 0.95

# Iterate over the reviews
for i, review in enumerate(curr_reviews):
    print(f"Processing review {i+1} of {len(curr_reviews)}")

    if i % 100 == 0 and i > 0:
        temperature += 0.1
        top_k += 10
        print(f"Temperature: {temperature}, Top K: {top_k}")

    response = ollama.generate(
        model='data-drift-simulator',
        prompt=review,
        options={
            'temperature': temperature,
            'mirostat_tau': mirostat_tau,
            'num_predict': num_predict,
            'top_k': top_k,
            'top_p': top_p
        }
    )
    print(response['response'])
    rewritten_reviews.append(response['response'])
[33]:
# Add the rewritten reviews to the current dataframe
df_current_test = df_current.head(300)
df_current_test["rewritten_reviews"] = rewritten_reviews
[34]:
df_current_test.head()
[34]:
评论 评分 日期时间 rewritten_reviews
0 安装游戏很困难(因为... 0.0 2012-07-09 ## 这款赛车游戏不赛车\n\n这款 g...
1 如果您喜欢拉力赛车,您会喜欢这款游戏... 3.0 2013-06-30 ## 维修站\n\n如果您是一位汽油头...
2 第一次发货收到的是书而不是游戏... 0.0 2014-06-28 ## 最后的希望:评论\n\n最后的希望到了...
3 我在 Xbox 360 上玩过 Dirt 2,这是一款还不错的游戏... 3.0 2011-06-14 ## 赛车地平线\n\n风在您身边呼啸而过...
4 总的来说,这是一款制作精良的赛车游戏,具有... 3.0 2013-05-11 ## Dirt 2:这款赛车游戏会吞噬控制器...\n

监控数据漂移#

使用 Argilla 监控#

在我们建立的工作流程中,我们继续使用我们的模型来预测新获取的数据的结果。监控模型的性能是我们质量控制过程中不可或缺的一部分,以确保其精度保持一致。为了保持模型对新数据预测的质量,我们将实施 Argilla。

因此,我们首先使用我们的模型对前 300 条新的(和重写的)评论进行一些预测。

[35]:
# Generate the predictions for the rewritten reviews
classifier = pipeline("text-classification", model="model-drift-simulation")

# Assuming current_df is your DataFrame with a column named 'text'
texts = df_current_test['rewritten_reviews']

# Initialize lists to store labels and scores
labels = []
scores = []

# Iterate over each text in the DataFrame and make predictions
for text in texts:
    prediction = classifier(text)
    labels.append(prediction[0]['label'])
    scores.append(prediction[0]['score'])

# Add the predicted labels and scores as new columns to the original DataFrame
df_current_test['predicted_label'] = labels
df_current_test['predicted_score'] = scores
df_current_test.head()
[35]:
评论 评分 日期时间 rewritten_reviews predicted_label predicted_score
0 安装游戏很困难(因为... 0.0 2012-07-09 ## 这款赛车游戏不赛车\n\n这款 g... 中性 0.314727
1 如果您喜欢拉力赛车,您会喜欢这款游戏... 3.0 2013-06-30 ## 维修站\n\n如果您是一位汽油头... 非常积极 0.529094
2 第一次发货收到的是书而不是游戏... 0.0 2014-06-28 ## 最后的希望:评论\n\n最后的希望到了... 中性 0.278454
3 我在 Xbox 360 上玩过 Dirt 2,这是一款还不错的游戏... 3.0 2011-06-14 ## 赛车地平线\n\n风在您身边呼啸而过... 非常积极 0.788434
4 总的来说,这是一款制作精良的赛车游戏,具有... 3.0 2013-05-11 ## Dirt 2:这款赛车游戏会吞噬控制器...\n 积极 0.496734

对于我们的记录,我们将评分视为标注者提供的评论的实际标签,而建议的标签将代表我们模型的预测。因此,我们创建一个 FeedbackDataset 并使用 Metrics 计算模型在新数据上的准确率。

有关指标的更多详细信息,请查看 文档

[ ]:
# Create a new feedback dataset
curr_rg_ds = create_feedback_dataset()

records = [
    rg.FeedbackRecord(
        fields={"text": row["rewritten_reviews"]},
        suggestions=[
        {
            "question_name": "label",
            "value": row["predicted_label"],
            "agent": "model_drift"
        }
    ],
        responses=[
            {
                "values": {
                    "label": {
                        "value": id2label[row["rating"]]
                    }
                }
            }
        ],
        metadata={
            "datetime": str(row["datetime"])
        }
    )
    for _ , row in df_current_test.iterrows()
]

curr_rg_ds.add_records(records)
curr_rg_ds.push_to_argilla(name="current_dataset", workspace="argilla")
[37]:
# Compute the model metrics
model_metrics_unified = curr_rg_ds.compute_model_metrics(question_name="label", metric_names=["accuracy", "precision", "recall", "f1-score", "confusion-matrix"], strategy="majority")
model_metrics_unified
[37]:
[ModelMetricResult(metric_name='accuracy', count=300, result=0.5533333333333333),
 ModelMetricResult(metric_name='precision', count=300, result=0.2532811059907834),
 ModelMetricResult(metric_name='recall', count=300, result=0.2772412030631758),
 ModelMetricResult(metric_name='f1-score', count=300, result=0.2559887955182073),
 ModelMetricResult(metric_name='confusion-matrix', count=300, result=                         suggestions_negative  suggestions_neutral  \
 responses_negative                          1                    2
 responses_neutral                           1                    3
 responses_positive                          0                    4
 responses_very-negative                     6                    6
 responses_very-positive                     0                    9

                          suggestions_positive  suggestions_very-negative  \
 responses_negative                          3                          0
 responses_neutral                          15                          0
 responses_positive                         18                          0
 responses_very-negative                     7                          0
 responses_very-positive                    50                          0

                          suggestions_very-positive
 responses_negative                               1
 responses_neutral                                7
 responses_positive                              21
 responses_very-negative                          2
 responses_very-positive                        144  )]

我们可以观察到模型的准确率有所下降,这是数据漂移的迹象。所以现在我们意识到存在问题,我们必须分析数据。为此,有几种可能性,我们将演示其中的两种。

选项 1:使用 BerTopic 分析数据漂移#

主题建模对于确定评论的主要主题以及比较参考数据集和当前数据集之间的主题非常有用。为了使数据平衡,我们将使用每个数据集的前 300 个样本。我们将预处理数据并使用 BerTopic 模型。

有关如何使用 BerTopic 的更多信息,请查看 官方文档

[38]:
# Function to clean the text data
def clean_review(review):
    review = review.lower()
    review = re.sub(r"http\S+", "", review)
    review = re.sub(r'[^a-zA-Z\s]', '', review)

    tokens = word_tokenize(review)
    stop_words = set(stopwords.words('english'))
    tokens = [word for word in tokens if word not in stop_words]
    cleaned_review = ' '.join(tokens)

    return cleaned_review

# Clean the list of reviews
cleaned_ref_reviews = [clean_review(review) for review in ref_reviews]
cleaned_rew_reviews = [clean_review(review) for review in rewritten_reviews]
[39]:
# Join the data so that it can be visualized over time
total_reviews = cleaned_ref_reviews + cleaned_rew_reviews
total_datetime = ref_datetime + curr_datetime
[42]:
# Fit the model
topic_model = BERTopic(verbose=True)
topics, probs = topic_model.fit_transform(total_reviews)

topics_over_time = topic_model.topics_over_time(total_reviews, total_datetime, nr_bins=20)
2024-03-14 22:30:44,145 - BERTopic - Embedding - Transforming documents to embeddings.
2024-03-14 22:31:06,262 - BERTopic - Embedding - Completed ✓
2024-03-14 22:31:06,264 - BERTopic - Dimensionality - Fitting the dimensionality reduction algorithm
2024-03-14 22:31:10,195 - BERTopic - Dimensionality - Completed ✓
2024-03-14 22:31:10,199 - BERTopic - Cluster - Start clustering the reduced embeddings
2024-03-14 22:31:10,253 - BERTopic - Cluster - Completed ✓
2024-03-14 22:31:10,263 - BERTopic - Representation - Extracting topics from clusters using representation models.
2024-03-14 22:31:10,411 - BERTopic - Representation - Completed ✓

如果我们可视化随时间推移的主题,我们可以看到主题已经发生了变化。这是数据漂移的明显迹象。

[43]:
# Visualize the topics over time
topic_model.visualize_topics_over_time(topics_over_time, top_n_topics=10)

Data type cannot be displayed: application/vnd.plotly.v1+json

选项 2:使用 TextDescriptives 分析数据漂移#

数据统计是分析数据漂移的另一种方法。我们可以使用 TextDescriptives 来比较参考数据集和当前数据集的统计数据。

有关如何使用 TextDescriptives 的更多信息,请查看 文档。请注意,Argilla 还集成了 将文本描述符添加为元数据

[44]:
# Create a dataframe with all the data over time
data = {
    'datetime': total_datetime,
    'text': ref_reviews + rewritten_reviews
}
df_curr_ref = pd.DataFrame(data)

# Extract the metrics
metrics = td.extract_metrics(
    text=df_curr_ref["text"],
    spacy_model="en_core_web_sm",
    metrics=["descriptive_stats"],
)

# Join the metrics with the original dataframe and drop the NaN values
metrics_df = df_curr_ref.join(metrics.drop(columns=["text"]))
metrics_df.dropna(inplace=True)

使用 seaborn 库,我们可以可视化参考数据集和当前数据集的统计数据。我们可以观察到统计数据发生了变化,这是数据漂移的另一个迹象。

[45]:
# Create the time series subplots
fig,ax = plt.subplots( 2, 2,
                                    figsize = ( 10, 8))

sns.lineplot( x = "datetime", y = "token_length_mean",
                    color = 'r', data = metrics_df,
                    ax = ax[0][0])

ax[0][0].tick_params(labelrotation = 25)
sns.lineplot( x = "datetime", y = "token_length_median",
                    color = 'g', data = metrics_df,
                    ax = ax[0][1])

ax[0][1].tick_params(labelrotation = 25)
sns.lineplot(x = "datetime", y = "token_length_std",
                    color = 'b', data = metrics_df,
                    ax = ax[1][0])

ax[1][0].tick_params(labelrotation = 25)

sns.lineplot(x = "datetime", y = "n_tokens",
                    color = 'y', data = metrics_df,
                    ax = ax[1][1])

ax[1][1].tick_params(labelrotation = 25)
fig.tight_layout(pad = 1.2)
../../../_images/tutorials_and_integrations_tutorials_feedback_monitoring-data-model-drift_59_0.png

结论#

在本教程中,我们创建了一个真实世界场景的模拟,在该场景中,我们在视频游戏评论数据集上训练情感分类器模型。随着时间的推移,当我们将此模型应用于正在进行的数据时,使用 Argilla 进行的例行质量控制检查(使用 gemma 生成的模拟当前数据)显示模型准确率下降。为了诊断问题,我们检查数据并发现主题和统计数据发生偏移,表明存在数据漂移。此分析是使用 BerTopicTextDescriptives 等工具进行的,以识别和理解这些变化。因此,我们学习了如何使用不同的工具有效地监控数据漂移,以及如何分析这些变化对模型性能的影响。