评估文档

使用 `evaluator` 与自定义管道

Hugging Face's logo
加入 Hugging Face 社区

并获得增强文档体验

开始

使用 `evaluator` 与自定义管道

评估器旨在与 `transformer` 管道开箱即用。但是,在很多情况下,您的模型或管道可能不是 `transformer` 生态系统的一部分。您仍然可以使用 `evaluator` 轻松地为它们计算指标。在本指南中,我们将展示如何为 Scikit-Learn 管道 和 Spacy 管道 执行此操作。让我们从 Scikit-Learn 案例开始。

Scikit-Learn

首先,我们需要训练一个模型。我们将使用 IMDb 数据集 训练一个简单的文本分类器,因此,让我们先下载数据集

from datasets import load_dataset

ds = load_dataset("imdb")

然后,我们可以构建一个简单的 TF-IDF 预处理器和 Naive Bayes 分类器,并将其包装在 `Pipeline` 中

from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer

text_clf = Pipeline([
        ('vect', CountVectorizer()),
        ('tfidf', TfidfTransformer()),
        ('clf', MultinomialNB()),
])

text_clf.fit(ds["train"]["text"], ds["train"]["label"])

遵循 `transformers` 中 `TextClassificationPipeline` 的惯例,我们的管道应该是可调用的,并返回一个字典列表。此外,我们使用 `task` 属性来检查管道是否与 `evaluator` 兼容。我们可以为此目的编写一个小的包装器类

class ScikitEvalPipeline:
    def __init__(self, pipeline):
        self.pipeline = pipeline
        self.task = "text-classification"

    def __call__(self, input_texts, **kwargs):
        return [{"label": p} for p in self.pipeline.predict(input_texts)]

pipe = ScikitEvalPipeline(text_clf)

现在,我们可以将此 `pipeline` 传递给 `evaluator`

from evaluate import evaluator

task_evaluator = evaluator("text-classification")
task_evaluator.compute(pipe, ds["test"], "accuracy")

>>> {'accuracy': 0.82956}

实现该简单的包装器是将任何框架中的任何模型与 `evaluator` 一起使用所需要的全部操作。在 `__call__` 中,您可以实现所有必要的逻辑来高效地通过您的模型进行正向传播。

Spacy

我们将使用 `spacytextblob` 项目的 `polarity` 功能来获得一个简单的情感分析器。首先,您需要安装该项目并下载资源

pip install spacytextblob
python -m textblob.download_corpora
python -m spacy download en_core_web_sm

然后,我们可以简单地加载 `nlp` 管道并添加 `spacytextblob` 管道

import spacy

nlp = spacy.load('en_core_web_sm')
nlp.add_pipe('spacytextblob')

此代码片段展示了我们如何使用 `spacytextblob` 添加的 `polarity` 功能来获取文本的情感

texts = ["This movie is horrible", "This movie is awesome"]
results = nlp.pipe(texts)

for txt, res in zip(texts, results):
    print(f"{text} | Polarity: {res._.blob.polarity}")

现在,我们可以将其包装在一个简单的包装器类中,就像之前的 Scikit-Learn 示例一样。它只需要返回一个包含预测标签的字典列表。如果极性大于 0,我们将预测正面情感,否则预测负面情感

class SpacyEvalPipeline:
    def __init__(self, nlp):
        self.nlp = nlp
        self.task = "text-classification"

    def __call__(self, input_texts, **kwargs):
        results =[]
        for p in self.nlp.pipe(input_texts):
            if p._.blob.polarity>=0:
                results.append({"label": 1})
            else:
                results.append({"label": 0})
        return results

pipe = SpacyEvalPipeline(nlp)

该类与 `evaluator` 兼容,我们可以使用之前示例中的相同实例以及 IMDb 测试集

eval.compute(pipe, ds["test"], "accuracy")
>>> {'accuracy': 0.6914}

这将比 Scikit-Learn 示例花费更长时间,但大约 10-15 分钟后,您将获得评估结果!