跳转到内容

事实正确性

事实正确性

FactualCorrectness 是一个比较和评估生成的 responsereference 之间事实准确性的指标。该指标用于确定生成的响应与参考文本在多大程度上保持一致。事实正确性得分范围为 0 到 1,值越高表示性能越好。为了衡量响应与参考文本之间的一致性,该指标首先使用大语言模型(LLM)将响应和参考文本分解为多个声明,然后使用自然语言推理来确定响应和参考文本之间的事实重叠部分。事实重叠部分通过精确率、召回率和 F1 分数进行量化,这些可以通过 mode 参数进行控制。

示例

from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas.metrics.collections import FactualCorrectness

# Setup LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)

# Create metric
scorer = FactualCorrectness(llm=llm)

# Evaluate
result = await scorer.ascore(
    response="The Eiffel Tower is located in Paris.",
    reference="The Eiffel Tower is located in Paris. It has a height of 1000ft."
)
print(f"Factual Correctness Score: {result.value}")

输出

Factual Correctness Score: 0.67

默认情况下,模式设置为 f1。您可以通过设置 mode 参数将模式更改为 precisionrecall

# Precision mode - measures what fraction of response claims are supported by reference
scorer = FactualCorrectness(llm=llm, mode="precision")
result = await scorer.ascore(
    response="The Eiffel Tower is located in Paris.",
    reference="The Eiffel Tower is located in Paris. It has a height of 1000ft."
)
print(f"Precision Score: {result.value}")

输出

Precision Score: 1.0

您还可以使用 atomicitycoverage 参数来配置声明分解的粒度。

# High granularity - more detailed claim decomposition
scorer = FactualCorrectness(
    llm=llm,
    mode="f1",
    atomicity="high",  # More atomic claims
    coverage="high"    # Comprehensive coverage
)

同步用法

如果你偏好同步代码,可以使用 .score() 方法来代替 .ascore()

result = scorer.score(
    response="The Eiffel Tower is located in Paris.",
    reference="The Eiffel Tower is located in Paris. It has a height of 1000ft."
)

计算方法

计算真正例(TP)、假正例(FP)和假负例(FN)的公式如下:

\[ \text{真正例 (TP)} = \text{响应中存在于参考文本中的声明数量} \]
\[ \text{假正例 (FP)} = \text{响应中不存在于参考文本中的声明数量} \]
\[ \text{假负例 (FN)} = \text{参考文本中不存在于响应中的声明数量} \]

计算精确率、召回率和 F1 分数的公式如下:

\[ \text{精确率} = {TP \over (TP + FP)} \]
\[ \text{召回率} = {TP \over (TP + FN)} \]
\[ \text{F1 分数} = {2 \times \text{精确率} \times \text{召回率} \over (\text{精确率} + \text{召回率})} \]

控制声明数量

响应和参考文本中的每个句子都可以被分解为一个或多个声明。从单个句子生成的声明数量由您的应用所需的 atomicitycoverage 水平决定。

示例

scorer = FactualCorrectness(mode="precision",atomicity="low")
输出
1.0

理解原子性和覆盖率

在声明分解中,有两个重要参数会影响输出:

  1. 原子性
  2. 覆盖率

这些参数有助于控制生成声明的粒度和完整性。

原子性

原子性(Atomicity) 指的是一个句子被分解成其最小、有意义的组成部分的程度。可以根据您需要高度详细的声明还是更概括的视图来进行调整。

  • 高原子性:句子被分解为其基本、不可分割的声明。这会产生多个较小的声明,每个声明代表一个独立的信息片段。

示例: - 原始句子: - “阿尔伯特·爱因斯坦是一位德国理论物理学家,他发展了相对论并为量子力学做出了贡献。” - 分解后的声明: - “阿尔伯特·爱因斯坦是一位德国理论物理学家。” - “阿尔伯特·爱因斯坦发展了相对论。” - “阿尔伯特·爱因斯坦为量子力学做出了贡献。”

  • 低原子性:句子保持更完整的状态,从而产生较少的声明,每个声明可能包含多个信息片段。

示例: - 原始句子: - “阿尔伯特·爱因斯坦是一位德国理论物理学家,他发展了相对论并为量子力学做出了贡献。” - 分解后的声明: - “阿尔伯特·爱因斯坦是一位德国理论物理学家,他发展了相对论并为量子力学做出了贡献。”

覆盖率

覆盖率(Coverage) 指的是声明对原始句子中信息的全面代表程度。可以调整它以包含所有细节或概括内容。

  • 高覆盖率:分解后的声明捕捉了原始句子中存在的所有信息,保留了每一个细节。

示例: - 原始句子: - “玛丽·居里是一位波兰裔法国籍物理学家和化学家,她对放射性进行了开创性研究。” - 分解后的声明: - “玛丽·居里是一位波兰物理学家。” - “玛丽·居里是一位入籍法国的物理学家。” - “玛丽·居里是一位化学家。” - “玛丽·居里对放射性进行了开创性研究。”

  • 低覆盖率:分解后的声明仅涵盖要点,省略一些细节以提供更概括的视图。

示例: - 原始句子: - “玛丽·居里是一位波兰裔法国籍物理学家和化学家,她对放射性进行了开创性研究。” - 分解后的声明: - “玛丽·居里是一位物理学家。” - “玛丽·居里对放射性进行了研究。”

结合原子性和覆盖率

通过同时调整原子性和覆盖率,您可以自定义细节和完整性的级别,以满足您特定用例的需求。

  • 高原子性与高覆盖率:生成高度详细和全面的声明,涵盖原始句子的所有方面。

示例: - 原始句子: - “查尔斯·巴贝奇是一位英国数学家、哲学家、发明家和机械工程师。” - 分解后的声明: - “查尔斯·巴贝奇是一位英国数学家。” - “查尔斯·巴贝奇是一位哲学家。” - “查尔斯·巴贝奇是一位发明家。” - “查尔斯·巴贝奇是一位机械工程师。”

  • 低原子性与低覆盖率:生成较少、细节较少的声明,总结主要思想而不涉及具体细节。

示例: - 原始句子: - “查尔斯·巴贝奇是一位英国数学家、哲学家、发明家和机械工程师。” - 分解后的声明: - “查尔斯·巴贝奇是一位英国数学家。” - “查尔斯·巴贝奇是一位发明家。”

实际应用

  • 当您需要为深入分析或信息提取进行详细而全面的分解时,请使用高原子性与高覆盖率
  • 当只需要关键信息时(例如用于摘要),请使用低原子性与低覆盖率

这种在控制声明数量方面的灵活性有助于确保信息以适合您应用需求的粒度级别呈现。

旧版指标 API

以下示例使用旧版指标 API 模式。对于新项目,我们建议使用上面显示的基于集合的 API。

弃用时间表

此 API 将在 0.4 版本中被弃用,并在 1.0 版本中被移除。请迁移到上面显示的基于集合的 API。

使用 SingleTurnSample 的示例

from ragas.dataset_schema import SingleTurnSample
from ragas.metrics._factual_correctness import FactualCorrectness


sample = SingleTurnSample(
    response="The Eiffel Tower is located in Paris.",
    reference="The Eiffel Tower is located in Paris. I has a height of 1000ft."
)

scorer = FactualCorrectness(llm = evaluator_llm)
await scorer.single_turn_ascore(sample)

输出

0.67

更改模式

默认情况下,模式设置为 F1,您可以通过设置 mode 参数将模式更改为 precisionrecall

scorer = FactualCorrectness(llm = evaluator_llm, mode="precision")

输出

1.0

控制原子性

scorer = FactualCorrectness(mode="precision", atomicity="low")

输出

1.0