在自然语言生成任务中,如何评估模型生成文本的质量是一个关键问题。BLEU和ROUGE是两个最常用的自动评估指标,本文将详细介绍这两个指标的原理、计算方法和代码实现。
BLEU主要评估生成文本与参考文本之间的n-gram重叠程度,最初用于机器翻译评估。
BLEU得分的计算包含两个主要部分:
展开代码P_n = (匹配的n-gram数量) / (候选文本中n-gram总数)
展开代码BP = min(1, exp(1 - r/c))
其中:r = 参考文本长度,c = 候选文本长度
展开代码BLEU = BP × exp(∑(w_n × log(P_n)))
其中:w_n 是n-gram的权重,通常取1/4
python展开代码from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction
import jieba
def calculate_bleu(reference, candidate):
"""
计算BLEU得分
"""
# 中文分词
ref_tokens = list(jieba.cut(reference))
cand_tokens = list(jieba.cut(candidate))
# 计算BLEU得分 (1-gram到4-gram)
smoothie = SmoothingFunction().method3
bleu_score = sentence_bleu(
[ref_tokens],
cand_tokens,
smoothing_function=smoothie
)
return bleu_score
# 示例使用
reference = "今天天气很好,适合出门游玩"
candidate = "今天天气不错,很适合外出"
bleu = calculate_bleu(reference, candidate)
print(f"BLEU Score: {bleu:.4f}")
ROUGE主要评估召回率,即参考文本中有多少内容被生成文本覆盖,常用于文本摘要评估。
展开代码ROUGE-N = (参考文本和候选文本共同的n-gram数) / (参考文本中n-gram总数)
展开代码R_lcs = LCS(X,Y) / |Y| P_lcs = LCS(X,Y) / |X| F_lcs = (1+β²) × R_lcs × P_lcs / (R_lcs + β² × P_lcs)
python展开代码from rouge_chinese import Rouge
import jieba
def calculate_rouge(reference, candidate):
"""
计算ROUGE得分
"""
# 中文分词
ref_tokens = " ".join(jieba.cut(reference))
cand_tokens = " ".join(jieba.cut(candidate))
# 初始化ROUGE
rouge = Rouge()
# 计算得分
scores = rouge.get_scores(cand_tokens, ref_tokens)
return scores[0]
# 示例使用
reference = "人工智能技术发展迅速,在各个领域都有广泛应用"
candidate = "AI技术进步很快,应用范围很广"
rouge_scores = calculate_rouge(reference, candidate)
print("ROUGE Scores:")
print(f"ROUGE-1: {rouge_scores['rouge-1']['f']:.4f}")
print(f"ROUGE-2: {rouge_scores['rouge-2']['f']:.4f}")
print(f"ROUGE-L: {rouge_scores['rouge-l']['f']:.4f}")
在LLaMA-Factory框架中,您可以这样使用这些指标:
python展开代码# 使用vLLM进行批量推理
python scripts/vllm_infer.py \
--model_name_or_path your_model_path \
--dataset your_test_dataset \
--save_name predictions.jsonl
# 评估生成质量
python scripts/eval_bleu_rouge.py predictions.jsonl
eval_bleu_rouge.py
的核心代码:
python展开代码def compute_metrics(sample):
# 获取预测和标签
hypothesis = list(jieba.cut(sample["predict"]))
reference = list(jieba.cut(sample["label"]))
# 计算BLEU
bleu_score = sentence_bleu(
[list(sample["label"])],
list(sample["predict"]),
smoothing_function=SmoothingFunction().method3,
)
# 计算ROUGE
if len(" ".join(hypothesis).split()) == 0 or len(" ".join(reference).split()) == 0:
rouge_scores = {"rouge-1": {"f": 0.0}, "rouge-2": {"f": 0.0}, "rouge-l": {"f": 0.0}}
else:
rouge = Rouge()
rouge_scores = rouge.get_scores(" ".join(hypothesis), " ".join(reference))[0]
return {
"bleu": bleu_score,
"rouge-1": rouge_scores["rouge-1"]["f"],
"rouge-2": rouge_scores["rouge-2"]["f"],
"rouge-l": rouge_scores["rouge-l"]["f"]
}
因此,在实际应用中,建议将自动评估指标与人工评估相结合,以获得更准确的模型性能评价。
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!