LangChain学习笔记 Evaluation篇 之 String Evaluator(2): 自定义String Evaluator、字符串距离和嵌入距离

401 阅读2分钟

这个章节将主要基于LangChain Evaluation部分的文档和Juice继续学习LangChain框架的String Evaluator,欢迎大家在文章下讨论学习,我们直奔主题吧。

String Evaluators

自定义String Evaluator

可以通过从StringEvaluator类继承并实现_evaluate_string(以及用于异步支持的_avaluate_strings)方法来创建自己的自定义字符串评估器。下面的例子,将使用HuggingFace Evaluation库创建一个perplexity评估器。Perplexity是衡量模型对生成的文本的预测效果的指标。

from typing import Any, Optional
from langchain.evaluation import StringEvaluator
from evaluate import load

class PerplexityEvaluator(StringEvaluator):
    """评估字符串的Perplexity"""

    def __init__(self, model_id: str = "gpt2"):
        self.model_id = model_id
        self.metric_fn = load(
            "perplexity", module_type="metric", model_id=self.model_id, pad_token=0
        )

    def _evaluate_strings(
        self,
        *,
        prediction: str,
        reference: Optional[str] = None,
        input: Optional[str] = None,
        **kwargs: Any,
    ) -> dict:
        results = self.metric_fn.compute(
            predictions=[prediction], model_id=self.model_id
        )
        ppl = results["perplexities"][0]
        return {"score": ppl}

evaluator = PerplexityEvaluator()
evaluator.evaluate_strings(prediction="The rains in Spain fall mainly on the plain.")

# Using pad_token, but it is not set yet.
# huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...
# To disable this warning, you can either:
# - Avoid using `tokenizers` before the fork if possible
# - Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)
# 0%|          | 0/1 [00:00<?, ?it/s]
# {'score': 190.3675537109375}

Embedding距离评估器

要评估预测和参考标签字符串之间的语义相似性(或相异性),可以使用embedding_distance评估器对两个嵌入的表示使用距离度量。注意:这会返回一个距离分数,这意味着根据其嵌入的表示,数字越低,预测与参考越相似。

from langchain.evaluation import load_evaluator

evaluator = load_evaluator("embedding_distance")
evaluator.evaluate_strings(prediction="I shall go", reference="I shan't go")
# {'score': 0.0966466944859925}
evaluator.evaluate_strings(prediction="I shall go", reference="I will go")
# {'score': 0.03761174337464557}

选择距离指标

默认情况下,评估器使用余弦距离。如果愿意,可以选择不同的距离指标。看个例子。

from langchain.evaluation import EmbeddingDistance

list(EmbeddingDistance)

# [<EmbeddingDistance.COSINE: 'cosine'>,
# <EmbeddingDistance.EUCLIDEAN: 'euclidean'>,
# <EmbeddingDistance.MANHATTAN: 'manhattan'>,
# <EmbeddingDistance.CHEBYSHEV: 'chebyshev'>,
# <EmbeddingDistance.HAMMING: 'hamming'>]

evaluator = load_evaluator(
    "embedding_distance", distance_metric=EmbeddingDistance.EUCLIDEAN
)

选择嵌入模型

构造函数默认使用OpenAI Embeddings,但可以根据需要进行配置。看一个使用huggingface嵌入的例子

from langchain.embeddings import HuggingFaceEmbeddings

embedding_model = HuggingFaceEmbeddings()
hf_evaluator = load_evaluator("embedding_distance", embeddings=embedding_model)

String距离

将LLM或Chain的字符串输出与参考标签进行比较的最简单方法之一是使用字符串距离指标,如Levenstein或后缀距离。这可以与近似/模糊匹配criteria一起用于基本的单元测试。可以使用Langchain的string_distance评估器来访问它,评估器使用rapidfuzz库中的距离指标。注:返回的是距离分数,越低通常意味着结果越好。

看一下示例:

from langchain.evaluation import load_evaluator

evaluator = load_evaluator("string_distance")

evaluator.evaluate_strings(
    prediction="The job is completely done.",
    reference="The job is done",
)

# {'score': 0.0724999999999999}

配置字符串距离指标

默认情况下,StringDistanceEvalChain使用Levenstein距离,但也支持其他字符串距离算法。使用distance参数进行配置。

看一下有哪些可以使用的算法:

from langchain.evaluation import StringDistance

list(StringDistance)

# [<StringDistance.DAMERAU_LEVENSHTEIN: 'damerau_levenshtein'>,
# <StringDistance.LEVENSHTEIN: 'levenshtein'>,
# <StringDistance.JARO: 'jaro'>,
# <StringDistance.JARO_WINKLER: 'jaro_winkler'>]

总结

本章节我们继续学习String Evaluator部分。主要学习了如何自定义一个String Evaluator,通过集成StringEvaluator类并实现_evaluate_strings方法(或者异步方法_aevaluate_strings),你可以使用自定义的指标来完成一个字符串评估器;学习了Embedding距离评估器,用于评估模型预测和参考字符串的语义相似性来判断模型内容的可用性;学习了String距离,使用简单的字符串距离指标就可以对于生成的内容做一个基本的评估。

String Evaluator的部分就告一段落,下一章节我们将开始Comparison Evaluator的学习。