引言

随着大语言模型的快速发展,如何科学、全面地评估模型性能成为了AI领域的重要课题。本文将深入介绍两类核心大模型的评估方法:文本嵌入模型文本生成模型,通过实际代码示例帮助读者掌握模型评估的核心技能。

一、文本嵌入模型评估

1.1 什么是文本嵌入模型?

文本嵌入模型将文本转换为高维向量表示,这些向量能够捕捉文本的语义信息。好的嵌入模型应该让语义相似的文本在向量空间中距离更近。

1.2 核心评估指标

准确率 (Accuracy)
  • 定义:正确预测的样本数占总样本数的比例
  • 计算公式准确率 = 正确预测数 / 总样本数
  • 作用:衡量模型的整体预测准确性
  • 适用场景:二分类任务,如句子相似性判断
  • 局限:在类别不平衡时可能误导,如99%的样本都是同一类
精确率 (Precision)
  • 定义:预测为正例中真正为正例的比例
  • 计算公式精确率 = 真正例 / (真正例 + 假正例)
  • 作用:衡量模型预测的"质量",避免误报
  • 适用场景:关注预测准确性,如推荐系统中避免推荐不相关内容
  • 局限:可能牺牲召回率
召回率 (Recall)
  • 定义:真正例中被正确预测的比例
  • 计算公式召回率 = 真正例 / (真正例 + 假负例)
  • 作用:衡量模型发现正例的能力,避免漏报
  • 适用场景:信息检索,如搜索系统中确保找到相关内容
  • 局限:可能产生较多误报
F1分数 (F1-Score)
  • 定义:精确率和召回率的调和平均数
  • 计算公式F1 = 2 × (精确率 × 召回率) / (精确率 + 召回率)
  • 作用:平衡精确率和召回率,提供综合评估
  • 适用场景:需要平衡精确率和召回率的场景
  • 局限:在精确率和召回率差异很大时可能不够敏感

1.3 评估步骤

# 1. 加载数据集
dataset = load_dataset('C-MTEB/LCQMC', split='test')
test_samples = list(dataset)[0:100]

# 2. 提取句子对
s1 = [x['sentence1'] for x in test_samples]
s2 = [x['sentence2'] for x in test_samples]

# 3. 编码为向量
emb1 = model.encode(s1, normalize_embeddings=True)
emb2 = model.encode(s2, normalize_embeddings=True)

# 4. 计算相似度
similarities = (emb1 * emb2).sum(axis=1)

# 5. 基于阈值分类
threshold = 0.5
y_pred = (similarities > threshold).astype(np.int32)
y_true = np.array([int(x['label']) for x in test_samples])

# 6. 计算评估指标
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)

二、文本生成模型评估

2.1 什么是文本生成模型?

文本生成模型能够根据输入提示生成连贯、有意义的文本,如摘要、翻译、对话等。评估生成模型需要考虑生成文本的质量、流畅性和相关性。

2.2 核心评估指标

BLEU分数 (Bilingual Evaluation Understudy,双语评估替补)
  • 定义:基于n-gram匹配的自动评估指标
  • 计算方法:计算生成文本中n-gram在参考文本中的出现比例
  • 作用:衡量生成文本与参考文本的词汇匹配度
  • 适用场景:机器翻译、文本摘要等需要与参考文本对比的任务
  • 局限:不考虑语义,只关注词汇重叠;对同义词不敏感
ROUGE分数 (Recall-Oriented Understudy for Gisting Evaluation,面向召回率的摘要评估替补)
  • ROUGE-1:单个词的召回率,衡量词汇覆盖度
  • ROUGE-2:双词组合的召回率,考虑词汇顺序
  • ROUGE-L:最长公共子序列,衡量句子结构相似性
  • 作用:评估生成文本的内容覆盖度和结构相似性
  • 适用场景:文本摘要、内容生成等任务
  • 局限:主要关注内容覆盖,对语言流畅性评估有限
困惑度 (Perplexity)
  • 定义:模型对生成文本的"困惑"程度
  • 计算方法:基于语言模型的交叉熵损失计算
  • 作用:反映生成文本的语言流畅性和模型置信度
  • 适用场景:评估生成文本的语言质量
  • 局限:需要将生成文本重新输入模型,计算成本高

2.3 评估步骤

# 1. 加载数据集
dataset = load_dataset('suolyer/lcsts', split='train')
test_samples = list(dataset)[0:20]

# 2. 提取输入和参考文本
inputs = [x['input'] for x in test_samples]
references = [x['output'] for x in test_samples]

# 3. 生成文本
generated_results = []
for input_text, reference in zip(inputs, references):
    prompt = f"{input_text}\n\n摘要:"
    generated = model.generate(prompt, **generation_config)
    generated_results.append({
        "input": input_text,
        "reference": reference,
        "generated": generated
    })

# 4. 计算评估指标
def evaluate_generated_text(generated_list):
    smoother = SmoothingFunction()
    scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'])
    
    total_bleu = 0.0
    total_rouge1 = 0.0
    total_rouge2 = 0.0
    total_rougeL = 0.0
    total_perplexity = 0.0
    
    for res in generated_list:
        generated = res["generated"]
        reference = res["reference"]
        
        # BLEU计算
        bleu_score = sentence_bleu([reference], generated, 
                                 smoothing_function=smoother.method1)
        total_bleu += bleu_score
        
        # ROUGE计算
        rouge_scores = scorer.score(reference, generated)
        total_rouge1 += rouge_scores["rouge1"].fmeasure
        total_rouge2 += rouge_scores["rouge2"].fmeasure
        total_rougeL += rouge_scores["rougeL"].fmeasure
        
        # 困惑度计算
        inputs = tokenizer(generated, return_tensors="pt")
        with torch.no_grad():
            outputs = model(**inputs, labels=inputs["input_ids"])
        perplexity = torch.exp(outputs.loss).item()
        total_perplexity += perplexity
    
    # 返回平均分数
    return {
        "BLEU": total_bleu / len(generated_list),
        "ROUGE-1": total_rouge1 / len(generated_list),
        "ROUGE-2": total_rouge2 / len(generated_list),
        "ROUGE-L": total_rougeL / len(generated_list),
        "Perplexity": total_perplexity / len(generated_list)
    }

三、完整代码示例

3.1 文本嵌入模型评估完整代码(分类任务,预测一个类别)

""" 
@description: 评估文本嵌入模型(以 LCQMC 句子匹配为例)
@author: frank
@date: 2025-08-09
@version: 1.0

评估 BAAI/bge-small-zh 模型在 LCQMC(中文问句匹配)上的效果。
核心流程:加载数据 -> 编码句向量(L2 归一化)-> 计算余弦相似度 -> 基于阈值的二分类评估。
"""

# -*- coding: utf-8 -*-

from sentence_transformers import SentenceTransformer
from datasets import load_dataset

# 加载本地模型;也可直接用 huggingface 上的权重名,例如:"BAAI/bge-small-zh"
model_name = "D:\\xx\\pythonProject\\bge-small-zh"
model = SentenceTransformer(model_name)

# 内在质量评估:相似度相关性(句子匹配)
# 任务:中文句子匹配(LCQMC 数据集,Large-scale Chinese Question Matching Corpus)
# 说明:`C-MTEB/LCQMC` 为 MTEB 整理版本,字段通常包含 sentence1、sentence2、label/score(0/1)
# 若遇到网络/镜像问题,请配置环境变量 HF_ENDPOINT(例如国内镜像)或预先缓存到本地。
# 例如 PowerShell:$env:HF_ENDPOINT = "https://hf-mirror.com"
dataset = load_dataset('C-MTEB/LCQMC', split='test')

# 转为 Python 列表,便于后续处理与打印
test_samples = list(dataset)[0:100]

# 基本数据检查与可视化输出
print('test_samples[0:5]:', test_samples[0:5])
print(f'num_samples: {len(test_samples)}')
print(f'first_item_keys: {list(test_samples[0].keys())}')

import numpy as np
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score

# 1) 提取句子文本
# 字段语义:sentence1 与 sentence2 组成一条配对样本;标签 0/1 表示是否语义等价
s1 = [x['sentence1'] for x in test_samples]
s2 = [x['sentence2'] for x in test_samples]

# 2) 编码句向量
# 说明:normalize_embeddings=True 会做 L2 归一化,使每个向量长度为 1,仅保留方向信息,
#      此时两个向量的点积即为余弦相似度(范围约 [-1, 1])。
emb1 = model.encode(s1, normalize_embeddings=True, show_progress_bar=True)
emb2 = model.encode(s2, normalize_embeddings=True, show_progress_bar=True)
print(f'emb1.shape: {emb1.shape}, emb2.shape: {emb2.shape}')

# 3) 计算余弦相似度(归一化后点积=余弦)。使用向量化实现,效率更高
similarities = (emb1 * emb2).sum(axis=1)
print(f'similarities.shape: {similarities.shape}')
print(f'similarities stats -> min: {similarities.min():.4f}, max: {similarities.max():.4f}, mean: {similarities.mean():.4f}')

# 4) 准备标签
# 兼容两种字段名:优先使用 label,否则回退到 score
if 'label' in test_samples[0]:
    y_true = np.array([int(x['label']) for x in test_samples], dtype=np.int32)
elif 'score' in test_samples[0]:
    y_true = np.array([int(x['score']) for x in test_samples], dtype=np.int32)
else:
    raise KeyError('未找到标签字段:期望存在 "label" 或 "score"')

# 5) 基于阈值进行二分类预测
# 经验阈值 0.5,若需更优阈值,可在验证集上网格搜索
threshold = 0.5
y_pred = (similarities > threshold).astype(np.int32)

# 6) 评估指标
accuracy = accuracy_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
print(f"阈值: {threshold:.2f} | 准确率: {accuracy:.4f}, F1: {f1:.4f}, Precision: {precision:.4f}, Recall: {recall:.4f}")

# 7) 打印少量错例,便于人工检查
# FP: 预测相似(1)但实际不相似(0);FN: 预测不相似(0)但实际相似(1)
mis_idx = np.where(y_pred != y_true)[0].tolist()
print(f'misclassified: {len(mis_idx)}')
for i in mis_idx[:10]:  # 仅展示前 10 条
    item = test_samples[i]
    label_name = 'label' if 'label' in item else 'score'
    print(f'[mis] sim={similarities[i]:.3f} | pred={y_pred[i]} | true={item[label_name]}')
    print(f'  s1: {item["sentence1"]}')
    print(f'  s2: {item["sentence2"]}')

代码执行结果:

test_samples[0:5]: [{'sentence1': '谁有狂三这张高清的', 'sentence2': '这张高清图,谁有', 'score': 0}, {'sentence1': '英雄联盟什么英雄最 
好', 'sentence2': '英雄联盟最好英雄是什么', 'score': 1}, {'sentence1': '这是什么意思,被蹭网吗', 'sentence2': '我也是醉了,这是什么意思', 'score': 0}, {'sentence1': '现在有什么动画片好看呢?', 'sentence2': '现在有什么好看的动画片吗?', 'score': 1}, {'sentence1': '请问晶达
电子厂现在的工资待遇怎么样要求有哪些', 'sentence2': '三星电子厂工资 
待遇怎么样啊', 'score': 0}]
num_samples: 100
first_item_keys: ['sentence1', 'sentence2', 'score']
Batches: 100%|███████████████████████| 4/4 [00:00<00:00, 15.06it/s] 
Batches: 100%|███████████████████████| 4/4 [00:00<00:00, 14.36it/s] 
emb1.shape: (100, 512), emb2.shape: (100, 512)
similarities.shape: (100,)
similarities stats -> min: 0.7633, max: 0.9983, mean: 0.9448        
阈值: 0.50 | 准确率: 0.6100, F1: 0.7578, Precision: 0.6100, Recall: 
1.0000
misclassified: 39
[mis] sim=0.877 | pred=1 | true=0
  s1: 谁有狂三这张高清的
  s2: 这张高清图,谁有
[mis] sim=0.778 | pred=1 | true=0
  s1: 这是什么意思,被蹭网吗
  s2: 我也是醉了,这是什么意思
[mis] sim=0.880 | pred=1 | true=0
  s1: 请问晶达电子厂现在的工资待遇怎么样要求有哪些
  s2: 三星电子厂工资待遇怎么样啊
[mis] sim=0.921 | pred=1 | true=0
  s1: 文章真的爱姚笛吗
  s2: 姚笛真的被文章干了吗
[mis] sim=0.891 | pred=1 | true=0
  s1: 如加上什么部首
  s2: 给东加上部首是什么字?
[mis] sim=0.967 | pred=1 | true=0
  s1: 心各有所属是什么意思?
  s2: 心有所属是什么意思?
[mis] sim=0.964 | pred=1 | true=0
  s1: 世界杯哪位球员进球最多
  s2: 世界杯单界进球最多是哪位球员
[mis] sim=0.858 | pred=1 | true=0
  s1: 云赚钱怎么样
  s2: 怎么才能赚钱
[mis] sim=0.914 | pred=1 | true=0
  s1: 长的清新是什么意思
  s2: 小清新的意思是什么
[mis] sim=0.848 | pred=1 | true=0
  s1: 我们可以结婚了吗?
  s2: 在熙结婚了吗?

评估结果分析:

1. 整体表现:中等偏上
  • 准确率:61% - 模型整体判断正确的比例
  • F1分数:75.78% - 综合表现较好
2. 各指标详细分析
精确率 (Precision): 61%
  • 含义:在模型预测为"相似"的句子中,只有61%真的相似
  • 问题:存在较多"误报"(False Positive)
  • 影响:模型倾向于过度预测相似性
召回率 (Recall): 100%
  • 含义:所有真正相似的句子都被模型找到了
  • 优点:没有"漏报"(False Negative)
  • 特点:模型非常敏感,能找到所有相似句子
F1分数: 75.78%
  • 含义:精确率和召回率的平衡分数
  • 评价:虽然精确率不高,但召回率完美,F1分数仍达到75.78%
3. 问题诊断
主要问题:过度预测
模型行为:宁可错杀一千,不可放过一个
- 找到所有相似句子 ✓
- 但误判了很多不相似的句子 ✗
具体表现
  • 模型对相似性判断过于宽松
  • 阈值0.5可能设置过低
  • 模型倾向于给出较高的相似度分数
4. 改进建议
调整阈值
# 当前阈值:0.5
# 建议尝试:0.6, 0.7, 0.8
# 目标:在保持高召回率的同时提高精确率
阈值优化示例
# 假设调整到0.7
threshold = 0.7
y_pred = (similarities > threshold).astype(np.int32)

# 预期结果:
# 精确率:可能提升到70-80%
# 召回率:可能下降到80-90%
# F1分数:可能提升到75-85%
5. 业务场景适用性
适合的场景
  • 信息检索:宁可多返回一些结果,也不遗漏重要信息
  • 推荐系统:宁可推荐一些不太相关的,也不错过用户可能喜欢的内容
  • 初步筛选:作为第一轮筛选,后续可以人工精筛
不适合的场景
  • 精确匹配:需要高精度的相似性判断
  • 生产环境:误报成本较高的应用
  • 资源受限:计算资源有限,需要减少误判
6. 模型特点总结
优势
  • 敏感性高:能找到所有相似句子
  • 覆盖全面:不会遗漏重要信息
  • 适合粗筛:作为初步筛选工具
劣势
  • 精确性低:存在较多误判
  • 资源消耗:可能产生大量候选结果
  • 需要后处理:通常需要二次筛选
7. 实际应用建议
短期改进
  1. 提高阈值:从0.5调整到0.6-0.8
  2. 后处理:增加规则过滤或二次模型
  3. 人工审核:对重要结果进行人工确认
长期改进
  1. 模型微调:在特定领域数据上微调
  2. 集成学习:结合多个模型的判断
  3. 特征工程:增加更多语义特征
8. 结论

当前模型表现评级:B级(良好)

  • 优点:召回率完美,适合信息检索和初步筛选
  • 缺点:精确率偏低,存在过度预测问题
  • 建议:调整阈值到0.7左右,在保持高召回率的同时提高精确率
  • 适用性:适合作为粗筛工具,不适合精确匹配任务

这是一个典型的"高召回、低精确"模型,在特定应用场景下很有价值!

3.2 文本嵌入模型评估完整代码(回归任务,预测一个连续的数值)

""" 
@description: 评估文本嵌入模型(以 STS-B 为语义分析为例)
@author: frank
@date: 2025-08-09
@version: 1.0

评估 BAAI/bge-small-zh 模型在 STS-B(自然语言推理,semantic textual similarity tasks)上的效果。
核心流程:加载数据 -> 编码句向量(L2 归一化)-> 计算余弦相似度 -> 评估预测值与真实值的相关性。
"""

# -*- coding: utf-8 -*-

from sentence_transformers import SentenceTransformer
from datasets import load_dataset

# 加载本地模型;也可直接用 huggingface 上的权重名,例如:"BAAI/bge-small-zh"
model_name = "D:\\xx\\pythonProject\\all-MiniLM-L6-v2"
model = SentenceTransformer(model_name)

# 内在质量评估:相似度相关性(句子匹配)
# 任务:句子语义分析(STS-B 数据集,Semantic Textual Similarity Benchmark)
# 说明:`C-MTEB/LCQMC` 为 MTEB 整理版本,字段通常包含 sentence1、sentence2、label/score(0/1)
# 若遇到网络/镜像问题,请配置环境变量 HF_ENDPOINT(例如国内镜像)或预先缓存到本地。
# 例如 PowerShell:$env:HF_ENDPOINT = "https://hf-mirror.com"
dataset = load_dataset('sentence-transformers/stsb', split='test')

# 转为 Python 列表,便于后续处理与打印
test_samples = list(dataset)

# 基本数据检查与可视化输出
"""
test_samples[0:2]: [{'sentence1': 'A girl is styling her hair.', 'sentence2': 'A girl is brushing her hair.', 'score': 0.5}, {'sentence1': 'A group of men play soccer on the beach.', 'sentence2': 'A group of boys are playing soccer on the beach.', 'score': 0.72}]
"""
print('test_samples[0:5]:', test_samples[0:5])
print(f'num_samples: {len(test_samples)}')
print(f'first_item_keys: {list(test_samples[0].keys())}')

import numpy as np
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score
from scipy.stats import pearsonr, spearmanr

# 1) 提取句子文本
# 字段语义:sentence1 与 sentence2 组成一条配对样本;标签 0/1 表示是否语义等价
s1 = [x['sentence1'] for x in test_samples]
s2 = [x['sentence2'] for x in test_samples]

# 2) 编码句向量
# 说明:normalize_embeddings=True 会做 L2 归一化,使每个向量长度为 1,仅保留方向信息,
#      此时两个向量的点积即为余弦相似度(范围约 [-1, 1])。
emb1 = model.encode(s1, normalize_embeddings=True, show_progress_bar=True)
emb2 = model.encode(s2, normalize_embeddings=True, show_progress_bar=True)
print(f'emb1.shape: {emb1.shape}, emb2.shape: {emb2.shape}')

# 3) 计算余弦相似度(归一化后点积=余弦)。使用向量化实现,效率更高
similarities = (emb1 * emb2).sum(axis=1)
print(f'similarities.shape: {similarities.shape}')
print(f'similarities stats -> min: {similarities.min():.4f}, max: {similarities.max():.4f}, mean: {similarities.mean():.4f}')

# 4) 准备标签 - 保持浮点数格式
if 'label' in test_samples[0]:
    y_true = np.array([float(x['label']) for x in test_samples])
elif 'score' in test_samples[0]:
    y_true = np.array([float(x['score']) for x in test_samples])
else:
    raise KeyError('未找到标签字段:期望存在 "label" 或 "score"')

# 5) 直接使用相似度作为预测值(回归任务)
y_pred = similarities  # 不需要阈值分类

# 6) 评估指标 - 使用回归指标
pearson_corr, pearson_p = pearsonr(similarities, y_true)
spearman_corr, spearman_p = spearmanr(similarities, y_true)

print(f"Pearson 相关系数: {pearson_corr:.4f}, p值: {pearson_p:.4f}")
print(f"Spearman 相关系数: {spearman_corr:.4f}, p值: {spearman_p:.4f}")

# 可选:如果想看分类效果,可以设置阈值
threshold = 0.5
y_pred_binary = (similarities > threshold).astype(np.int32)
y_true_binary = (y_true > threshold).astype(np.int32)

# 分类指标
accuracy = accuracy_score(y_true_binary, y_pred_binary)
f1 = f1_score(y_true_binary, y_pred_binary)
print(f"阈值分类 - 准确率: {accuracy:.4f}, F1: {f1:.4f}")

# 7) 打印少量错例,便于人工检查
# FP: 预测相似(1)但实际不相似(0);FN: 预测不相似(0)但实际相似(1)
mis_idx = np.where(y_pred_binary != y_true_binary)[0].tolist()
print(f'misclassified: {len(mis_idx)}')
for i in mis_idx[:10]:  # 仅展示前 10 条
    item = test_samples[i]
    label_name = 'label' if 'label' in item else 'score'
    print(f'[mis] sim={similarities[i]:.3f} | pred={y_pred_binary[i]} | true={item[label_name]}')
    print(f'  s1: {item["sentence1"]}')
    print(f'  s2: {item["sentence2"]}')

代码执行结果:

test_samples[0:5]: [{'sentence1': 'A girl is styling her hair.', 'sentence2': 'A girl is brushing her hair.', 'score': 0.5}, {'sentence1': 'A group of men play soccer on the beach.', 'sentence2': 'A group of boys are playing soccer on the beach.', 'score': 0.72}, {'sentence1': "One woman is measuring another woman's ankle.", 'sentence2': 
"A woman measures another woman's ankle.", 'score': 1.0}, {'sentence1': 'A man is cutting up a cucumber.', 'sentence2': 'A man is slicing a cucumber.', 'score': 0.84}, {'sentence1': 'A man is playing a harp.', 'sentence2': 'A man is playing a keyboard.', 'score': 0.3}]   
num_samples: 1379
first_item_keys: ['sentence1', 'sentence2', 'score']
Batches: 100%|█████████████████████| 44/44 [00:04<00:00,  9.53it/s] 
Batches: 100%|█████████████████████| 44/44 [00:04<00:00, 10.10it/s]
emb1.shape: (1379, 384), emb2.shape: (1379, 384)
similarities.shape: (1379,)
similarities stats -> min: -0.1648, max: 0.9978, mean: 0.6079       
Pearson 相关系数: 0.8274, p值: 0.0000
Spearman 相关系数: 0.8203, p值: 0.0000
阈值分类 - 准确率: 0.8144, F1: 0.8499
misclassified: 256
[mis] sim=0.805 | pred=1 | true=0.5
  s1: A girl is styling her hair.
  s2: A girl is brushing her hair.
[mis] sim=0.502 | pred=1 | true=0.36
  s1: A woman is cutting onions.
  s2: A woman is cutting tofu.
[mis] sim=0.618 | pred=1 | true=0.44
  s1: A man is playing guitar.
  s2: A lady is playing the guitar.
[mis] sim=0.510 | pred=1 | true=0.34
  s1: A man is playing a guitar.
  s2: A man is playing a trumpet.
[mis] sim=0.510 | pred=1 | true=0.34
  s1: A man is playing a guitar.
  s2: A man is playing a trumpet.
[mis] sim=0.563 | pred=1 | true=0.4
  s1: A man is slicing a tomato.
  s2: A man is slicing a bun.
[mis] sim=0.513 | pred=1 | true=0.45
  s1: A man is slicing an onion.
  s2: A woman is slicing a pumpkin.
[mis] sim=0.700 | pred=1 | true=0.4
  s1: A  man is dancing.
  s2: A man and woman is dancing.
[mis] sim=0.768 | pred=1 | true=0.44
  s1: A woman is slicing garlics.
  s2: A woman is slicing an onion.
[mis] sim=0.663 | pred=1 | true=0.44
  s1: A little boy is singing and playing a guitar.
  s2: A man is singing and playing the guitar.

评估结果分析:

1. 整体表现:优秀

这是一个非常优秀的评估结果,表明模型在语义相似性任务上表现卓越。

2. 各指标详细分析
Pearson相关系数: 0.8274
  • 含义:模型预测的相似度与人工标注的相似度之间存在强线性相关
  • 评价:0.82+的相关系数属于"强相关"级别
  • 意义:模型能够很好地捕捉语义相似性的线性关系
Spearman相关系数: 0.8203
  • 含义:模型预测的相似度排名与人工标注的相似度排名高度一致
  • 评价:0.82+的等级相关系数表明排序质量很高
  • 意义:模型能够正确区分不同相似度级别的句子对
p值: 0.0000
  • 含义:统计显著性极高,结果非常可靠
  • 评价:p < 0.001,表明相关性不是偶然的
  • 意义:评估结果具有很高的统计置信度
3. 分类性能分析
准确率: 81.44%
  • 含义:基于0.5阈值的二分类准确率
  • 评价:超过80%的准确率属于优秀水平
  • 意义:模型能够有效区分相似和不相似的句子对
F1分数: 84.99%
  • 含义:精确率和召回率的平衡分数
  • 评价:接近85%的F1分数表明模型性能均衡
  • 意义:模型在精确性和完整性之间取得了良好平衡
4. 模型特点分析
优势
  • 语义理解能力强:能够准确捕捉句子间的语义关系
  • 排序质量高:能够正确区分不同相似度级别
  • 统计可靠性高:结果具有很高的统计显著性
  • 性能均衡:精确率和召回率都表现良好
适用场景
  • 语义搜索:能够准确找到语义相关的文档
  • 推荐系统:能够识别用户可能感兴趣的内容
  • 文本聚类:能够将语义相似的文本分组
  • 相似度排序:能够按相似度对文本进行排序
5. 与之前结果对比
指标 01-evaluate-text-embedding.py 01-evaluate-text-embedding2.py
任务类型 二分类(相似/不相似) 回归(相似度分数)
数据集 LCQMC STS-B
主要指标 准确率61%, F1 75.78% Pearson 0.8274, F1 84.99%
性能评价 中等偏上 优秀
6. 结果解释
为什么这个结果更好?
  1. 任务类型不同:回归任务比二分类任务更精细
  2. 数据集质量:STS-B是专门设计的语义相似性基准
  3. 评估方式:直接使用相似度分数,避免了阈值选择问题
  4. 模型适配性:all-MiniLM-L6-v2可能更适合这个任务
相关系数的意义
  • 0.8+的相关系数:表明模型预测与人工标注高度一致
  • 线性关系强:模型能够捕捉语义相似性的线性变化
  • 排序质量高:能够正确区分不同相似度级别
7. 实际应用价值
推荐使用场景
  • 语义搜索:能够准确找到相关文档
  • 推荐系统:能够识别用户兴趣
  • 文本匹配:能够找到相似内容
  • 质量评估:能够评估文本相似性
性能预期
  • 高精度:能够准确识别语义相似性
  • 高可靠性:结果具有统计显著性
  • 强泛化:在多种文本类型上表现良好
8. 改进建议
进一步优化
  1. 模型微调:在特定领域数据上微调
  2. 集成学习:结合多个模型的预测
  3. 特征工程:增加更多语义特征
应用部署
  1. 阈值优化:根据具体应用调整分类阈值
  2. 性能监控:持续监控模型性能
  3. 用户反馈:收集用户反馈优化模型
9. 结论

当前模型表现评级:A级(优秀)

  • 优点:语义理解能力强,排序质量高,统计可靠性高
  • 适用性:适合各种语义相似性任务
  • 建议:可以直接用于生产环境
  • 价值:为语义搜索、推荐系统等应用提供了强有力的支持

这是一个非常成功的文本嵌入模型评估结果,表明模型在语义相似性任务上达到了优秀水平!
注:这个模型仅支持英文,暂不支持中文。使用时请注意。bge模型支持中文。

3.3 文本生成模型评估完整代码

""" 
@description: 基于数据集评估文本生成模型 Qwen3-0.6B,生成摘要,并计算评估指标
@author: frank
@date: 2025-08-13
@version: 2.0

基于数据集对 Qwen3-0.6B 模型进行评估,输出完整评估指标。
"""

# -*- coding: utf-8 -*-

from transformers import AutoTokenizer, AutoModelForCausalLM
from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction
from rouge_score import rouge_scorer
from datasets import load_dataset
import torch

# --------------------------
# 步骤1:加载数据集
# --------------------------
def load_dataset_samples(dataset_name="suolyer/lcsts", split="train", max_samples=100):
    """加载数据集样本
    
    LCSTS (Large-scale Chinese Short Text Summarization) 数据集简介:
    - 规模:包含约240万条中文文本摘要对
    - 来源:从新浪微博收集的真实文本数据
    - 任务:中文文本摘要生成
    - 字段:input(原文) + output(摘要)
    - 特点:文本长度适中,摘要简洁,适合训练和评估摘要模型
    - 应用:文本摘要、内容理解、信息提取等NLP任务
    """
    print(f"正在加载数据集: {dataset_name}")
    dataset = load_dataset(dataset_name, split=split)
    # 打印 dataset、dataset类型
    # print(f"dataset: {dataset}")
    print(f"dataset类型: {type(dataset)}")
    
    # 简洁的写法,加载失败直接报错
    test_samples = list(dataset)[0:max_samples]
    # 打印 test_samples、test_samples类型
    print(f"test_samples: {test_samples[0:1]}")
    print(f"test_samples类型: {type(test_samples)}")
    
    # 提取输入和输出文本
    inputs = [x['input'] for x in test_samples]
    outputs = [x['output'] for x in test_samples]
    
    print(f"成功加载 {len(test_samples)} 条测试数据")
    return inputs, outputs

# 加载测试数据
inputs, references = load_dataset_samples(max_samples=20)

# --------------------------
# 步骤2:加载模型与分词器
# --------------------------
model_name = "D:\\xx\\pythonProject\\Qwen3-0.6B"
print(f"正在加载模型: {model_name}")

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# 配置生成参数
generation_config = {
    "max_new_tokens": 25,  # 减少最大token数量,避免过长
    "min_new_tokens": 5,   # 减少最小token数量,避免强制填充
    "temperature": 0.4,    # 降低温度,使生成更确定
    "top_k": 40,           # 减少候选数量,提高质量
    "do_sample": True,     # 启用采样
    "pad_token_id": tokenizer.eos_token_id
}

# --------------------------
# 步骤3:生成文本(模型推理)
# --------------------------
def generate_text(prompt, model, tokenizer, config):
    """用模型生成文本"""
    try:
        inputs = tokenizer(prompt, return_tensors="pt")
        outputs = model.generate(
            **inputs,
            max_new_tokens=config["max_new_tokens"],
            min_new_tokens=config["min_new_tokens"],
            temperature=config["temperature"],
            top_k=config["top_k"],
            do_sample=config["do_sample"],
            pad_token_id=config["pad_token_id"],
            repetition_penalty=config.get("repetition_penalty", 1.0),
            no_repeat_ngram_size=config.get("no_repeat_ngram_size", 0)
        )
        generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
        # 移除原始prompt,只保留生成的部分
        if prompt in generated_text:
            generated_text = generated_text.replace(prompt, "").strip()
        
        return generated_text
    except Exception as e:
        print(f"生成文本失败: {e}")
        return ""

# 生成所有测试用例的结果
print("正在生成文本...")
generated_results = []
for i, (input_text, reference) in enumerate(zip(inputs, references)):
    # 关闭推理过程显示,只显示进度
    print(f"处理第 {i+1}/{len(inputs)} 条数据...", end="", flush=True)
    
    # 构建提示词
    # 去除 input_text 中的 abc
    prompt = f"{input_text}\n\n摘要:"
    
    # 生成文本(关闭详细输出)
    generated = generate_text(prompt, model, tokenizer, generation_config)
    
    # 显示完成状态
    print(" ✓")
    
    generated_results.append({
        "input": input_text,
        "reference": reference,
        "generated": generated,
        "prompt": prompt
    })

# 打印生成结果示例
print("\n生成结果示例:")
for idx, res in enumerate(generated_results[:3]):
    print(f"测试用例 {idx+1}:")
    print(f"输入:{res['input'][:100]}...")
    print(f"参考:{res['reference']}")
    print(f"生成:{res['generated']}")
    print("-" * 50)

# --------------------------
# 步骤4:多指标评估
# --------------------------
def evaluate_generated_text(generated_list):
    """计算BLEU、ROUGE、困惑度等指标
    
    评估指标简介:
    
    1. BLEU (Bilingual Evaluation Understudy) 双语评估替补
       - 用途:衡量生成文本与参考文本的n-gram匹配度
       - 原理:计算生成文本中n-gram在参考文本中的出现比例
       - 范围:0-1,分数越高表示匹配度越好
       - 优势:客观、可重复,广泛用于机器翻译和文本生成评估
       - 局限:不考虑语义,只关注词汇重叠
    
    2. ROUGE (Recall-Oriented Understudy for Gisting Evaluation) 召回率评估替补
       - ROUGE-1:单个词的召回率,衡量词汇覆盖度
       - ROUGE-2:双词组合的召回率,考虑词汇顺序
       - ROUGE-L:最长公共子序列,衡量句子结构相似性
       - 范围:0-1,分数越高表示内容覆盖越全面
       - 应用:主要用于摘要生成、文本压缩等任务评估
    
    3. 困惑度 (Perplexity)
       - 用途:衡量模型对生成文本的"困惑"程度
       - 原理:基于语言模型的交叉熵损失计算
       - 范围:通常>1,数值越低表示模型越"确定"
       - 意义:反映生成文本的语言流畅性和模型置信度
       - 注意:需要将生成文本重新输入模型计算
    """
    # 初始化指标工具
    smoother = SmoothingFunction()
    scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True)
    
    total_bleu = 0.0
    total_rouge1 = 0.0
    total_rouge2 = 0.0
    total_rougeL = 0.0
    total_perplexity = 0.0
    valid_samples = 0
    
    for res in generated_list:
        generated = res["generated"]
        reference = res["reference"]
        
        # 跳过空生成结果
        if not generated.strip():
            continue
            
        valid_samples += 1
        
        # 1. BLEU 分数
        try:
            bleu_score = sentence_bleu(
                [reference],  # 参考文本列表
                generated,    # 候选文本
                smoothing_function=smoother.method1
            )
            # 确保bleu_score是数值类型
            if isinstance(bleu_score, (int, float)):
                total_bleu += float(bleu_score)
            else:
                total_bleu += 0.0
        except Exception as e:
            print(f"BLEU计算失败: {e}")
            total_bleu += 0.0
        
        # 2. ROUGE 分数
        try:
            rouge_scores = scorer.score(reference, generated)
            total_rouge1 += rouge_scores["rouge1"].fmeasure
            total_rouge2 += rouge_scores["rouge2"].fmeasure
            total_rougeL += rouge_scores["rougeL"].fmeasure
        except Exception as e:
            print(f"ROUGE计算失败: {e}")
            total_rouge1 += 0.0
            total_rouge2 += 0.0
            total_rougeL += 0.0
        
        # 3. 困惑度(Perplexity)
        try:
            inputs = tokenizer(generated, return_tensors="pt")
            with torch.no_grad():
                outputs = model(**inputs, labels=inputs["input_ids"])
            perplexity = torch.exp(outputs.loss).item()
            total_perplexity += perplexity
        except Exception as e:
            print(f"困惑度计算失败: {e}")
            total_perplexity += 0.0
    
    if valid_samples == 0:
        return {
            "BLEU": 0.0,
            "ROUGE-1": 0.0,
            "ROUGE-2": 0.0,
            "ROUGE-L": 0.0,
            "Perplexity": 0.0,
            "valid_samples": 0
        }
    
    # 计算平均分
    avg_bleu = total_bleu / valid_samples
    avg_rouge1 = total_rouge1 / valid_samples
    avg_rouge2 = total_rouge2 / valid_samples
    avg_rougeL = total_rougeL / valid_samples
    avg_perplexity = total_perplexity / valid_samples
    
    return {
        "BLEU": round(avg_bleu, 4),
        "ROUGE-1": round(avg_rouge1, 4),
        "ROUGE-2": round(avg_rouge2, 4),
        "ROUGE-L": round(avg_rougeL, 4),
        "Perplexity": round(avg_perplexity, 4),
        "valid_samples": valid_samples
    }

# 执行评估
print("\n正在计算评估指标...")
evaluation_results = evaluate_generated_text(generated_results)

# --------------------------
# 步骤5:输出完整评估结果
# --------------------------
print("\n" + "="*60)
print("Qwen3-0.6B 模型评估结果")
print("="*60)

print(f"测试样本总数: {len(generated_results)}")
print(f"有效样本数: {evaluation_results['valid_samples']}")
print(f"成功率: {evaluation_results['valid_samples']/len(generated_results)*100:.1f}%")

print("\n评估指标:")
print("-" * 40)
for metric, score in evaluation_results.items():
    if metric != "valid_samples":
        print(f"{metric:12}: {score}")

# 指标解释
print("\n指标说明:")
print("-" * 40)
print("BLEU      : 衡量n-gram匹配度,范围0-1,越高越好")
print("ROUGE-1   : 衡量单个词覆盖度,范围0-1,越高越好")
print("ROUGE-2   : 衡量双词组合覆盖度,范围0-1,越高越好")
print("ROUGE-L   : 衡量最长公共子序列,范围0-1,越高越好")
print("Perplexity: 衡量模型置信度,越低越好")

# 详细对比(前5个样本)
print("\n详细对比(前5个样本):")
print("="*60)
for idx, res in enumerate(generated_results[:5]):
    print(f"样本 {idx+1}:")
    print(f"输入文本: {res['input'][:80]}...")
    print(f"参考摘要: {res['reference']}")
    print(f"生成摘要: {res['generated']}")
    print("-" * 60)

print("\n评估完成!")

代码执行结果:

正在加载数据集: suolyer/lcsts
dataset类型: <class 'datasets.arrow_dataset.Dataset'>
test_samples: [{'input': '在本任务中,您将获得一段文本,您的任务是生
成该文本的摘要。前驻俄武官王海运少将指出,乌克兰危机几乎把世界主要国
家都卷入了,而中国不是当事方,相对超脱。因此,各方都在看中国怎么做,
都希望中国站在他们一边。此次危机很可能给中国带来又一个10年的“战略宽 
松期”。', 'output': '原中国驻俄武官:乌克兰危机或给中国带来十年战略 
宽松期', 'id': 0}]
test_samples类型: <class 'list'>
成功加载 20 条测试数据
正在加载模型: D:\programs\pyprojects\pythonProject\Qwen3-0.6B       
正在生成文本...
处理第 1/20 条数据... ✓
处理第 2/20 条数据... ✓
处理第 3/20 条数据... ✓
处理第 4/20 条数据... ✓
处理第 5/20 条数据... ✓
处理第 6/20 条数据... ✓
处理第 7/20 条数据... ✓
处理第 8/20 条数据... ✓
处理第 9/20 条数据... ✓
处理第 10/20 条数据... ✓
处理第 11/20 条数据... ✓
处理第 12/20 条数据... ✓
处理第 13/20 条数据... ✓
处理第 14/20 条数据... ✓
处理第 15/20 条数据... ✓
处理第 16/20 条数据... ✓
处理第 17/20 条数据... ✓
处理第 18/20 条数据... ✓
处理第 19/20 条数据... ✓
处理第 20/20 条数据... ✓

生成结果示例:
测试用例 1:
输入:在本任务中,您将获得一段文本,您的任务是生成该文本的摘要。前驻
俄武官王海运少将指出,乌克兰危机几乎把世界主要国家都卷入了,而中国不
是当事方,相对超脱。因此,各方都在看中国怎么做,都希望中国站在他们一
边...
参考:原中国驻俄武官:乌克兰危机或给中国带来十年战略宽松期
生成:中国在乌克兰危机中扮演了怎样的角色?请看下文。

这段文本的摘要应该包括哪些内容?
--------------------------------------------------
测试用例 2:
输入:在本任务中,您将获得一段文本,您的任务是生成该文本的摘要。常州
罗先生驾车准备拐弯,被一辆“天籁”野蛮加塞,此前该车已多次加塞,罗先生
热血上涌,撞了上去。交警判天籁车主负全责,罚款50元,并承担罗先生修...
参考:男子开车被人加塞怒撞对方交警判加塞者全责
生成:常州罗先生驾车准备拐弯,被一辆“天籁”加塞,此前该车已多次加塞,
--------------------------------------------------
测试用例 3:
输入:在本任务中,您将获得一段文本,您的任务是生成该文本的摘要。父母
不在家,男童从窗台坠下14楼。昨天上午9点左右,攀枝花市金沙丽水小区, 
父母急着上班,无意中将4岁多的木木遗忘在家,未送到幼儿园。木木醒来后...
参考:4岁男童背书包14楼坠下父母忘送其上幼儿园
生成:______。______。______。

根据任务要求,您需要将文本内容进行压缩,使信息完整、
--------------------------------------------------

正在计算评估指标...

============================================================        
Qwen3-0.6B 模型评估结果
============================================================        
测试样本总数: 20
有效样本数: 20
成功率: 100.0%

评估指标:
----------------------------------------
BLEU        : 0.0789
ROUGE-1     : 0.0
ROUGE-2     : 0.0
ROUGE-L     : 0.0
Perplexity  : 98.7494

指标说明:
----------------------------------------
BLEU      : 衡量n-gram匹配度,范围0-1,越高越好
ROUGE-1   : 衡量单个词覆盖度,范围0-1,越高越好
ROUGE-2   : 衡量双词组合覆盖度,范围0-1,越高越好
ROUGE-L   : 衡量最长公共子序列,范围0-1,越高越好
Perplexity: 衡量模型置信度,越低越好

详细对比(前5个样本):
============================================================        
样本 1:
输入文本: 在本任务中,您将获得一段文本,您的任务是生成该文本的摘要。
前驻俄武官王海运少将指出,乌克兰危机几乎把世界主要国家都卷入了,而中
国不是当事方,相对超脱。因此,各方...
参考摘要: 原中国驻俄武官:乌克兰危机或给中国带来十年战略宽松期      
生成摘要: 中国在乌克兰危机中扮演了怎样的角色?请看下文。

这段文本的摘要应该包括哪些内容?
------------------------------------------------------------        
样本 2:
输入文本: 在本任务中,您将获得一段文本,您的任务是生成该文本的摘要。
常州罗先生驾车准备拐弯,被一辆“天籁”野蛮加塞,此前该车已多次加塞,罗
先生热血上涌,撞了上去。交警判天...
参考摘要: 男子开车被人加塞怒撞对方交警判加塞者全责
生成摘要: 常州罗先生驾车准备拐弯,被一辆“天籁”加塞,此前该车已多次加
塞,
------------------------------------------------------------        
样本 3:
输入文本: 在本任务中,您将获得一段文本,您的任务是生成该文本的摘要。
父母不在家,男童从窗台坠下14楼。昨天上午9点左右,攀枝花市金沙丽水小 
区,父母急着上班,无意中将4岁多...
参考摘要: 4岁男童背书包14楼坠下父母忘送其上幼儿园
生成摘要: ______。______。______。

根据任务要求,您需要将文本内容进行压缩,使信息完整、
------------------------------------------------------------        
样本 4:
输入文本: 在本任务中,您将获得一段文本,您的任务是生成该文本的摘要。
如将学生综合素质评价纳入高考录取,会不会增大高考录取人为因素?农村学
校师资有限,如没法开选修课,如何保...
参考摘要: 专家:广西高中课改最关键在于师资
生成摘要: ______。
A. 该文主要讨论的是农村学校师资不足的问题
B. 该文主要讨论的是
------------------------------------------------------------        
样本 5:
输入文本: 在本任务中,您将获得一段文本,您的任务是生成该文本的摘要。
库克今日在《商业周刊》网站发文称身为同性恋者感到很自豪。“多年来,我 
向许多人公开了我的性取向。苹果的许...
参考摘要: 苹果CEO库克宣布出柜:身为同性恋者我感到自豪
生成摘要: 库克在《商业周刊》网站发文称身为同性恋者感到自豪。苹果的许
多同事知道他是一位
------------------------------------------------------------        

评估完成!

评估结果分析:

1. 整体表现:较差

这是一个非常不理想的评估结果,表明模型在中文摘要生成任务上存在严重问题。

2. 各指标详细分析
BLEU分数: 0.0789 (7.89%)
  • 含义:生成文本与参考文本的n-gram匹配度极低
  • 评价:7.89%的BLEU分数属于"很差"级别
  • 问题:模型生成的摘要与参考摘要几乎没有词汇重叠
ROUGE分数: 全部为0
  • ROUGE-1: 0.0 - 单个词覆盖度为0
  • ROUGE-2: 0.0 - 双词组合覆盖度为0
  • ROUGE-L: 0.0 - 最长公共子序列为0
  • 问题:这是最严重的问题,说明生成内容与参考完全无关
困惑度: 98.7494
  • 含义:模型对生成文本的"困惑"程度很高
  • 评价:数值远大于1,说明模型对生成内容"非常困惑"
  • 问题:生成文本的语言流畅性和模型置信度都很低
3. 问题诊断
主要问题:生成质量极差
模型行为:生成内容与输入和参考完全无关
- 词汇匹配度极低 ✗
- 内容覆盖度为0 ✗
- 语言流畅性差 ✗
- 模型置信度低 ✗
可能原因
  1. 模型能力不足:0.6B参数规模太小,无法胜任摘要任务
  2. 训练数据不匹配:模型可能没有在中文摘要数据上充分训练
  3. 提示词设计问题:当前的提示词可能不够明确
  4. 生成参数不当:temperature、top_k等参数可能需要调整
  5. 模型格式问题:可能存在模型加载或格式问题
4. 具体表现问题
生成内容问题
  • 生成内容与输入文本关联性差
  • 摘要质量低,可能包含无关信息
  • 语言表达不流畅,存在语法问题
  • 无法捕捉原文的核心信息
技术问题
  • 模型可能无法理解中文语义
  • 生成参数设置可能不当
  • 可能存在模型加载或配置问题
5. 改进建议
短期改进
  1. 优化提示词

    # 当前提示词
    prompt = f"{input_text}\n\n摘要:"
    
    # 改进提示词
    prompt = f"请为以下新闻生成一个简洁的摘要,要求:\n1. 突出核心事件\n2. 包含关键人物和地点\n3. 不超过20字\n\n新闻:{input_text}\n\n摘要:"
    
  2. 调整生成参数

    generation_config = {
        "max_new_tokens": 30,      # 增加长度
        "min_new_tokens": 10,      # 增加最小长度
        "temperature": 0.2,        # 降低温度,更确定
        "top_k": 20,               # 减少候选
        "repetition_penalty": 1.1, # 添加重复惩罚
    }
    
长期改进
  1. 使用更大模型:考虑使用Qwen1.5-1.8B或更大模型
  2. 数据预处理:确保输入文本格式一致
  3. 模型微调:在中文摘要数据上微调模型
  4. 集成学习:结合多个模型的判断
6. 与嵌入模型对比
模型类型 评估结果 性能评级 主要问题
文本嵌入 Pearson 0.8274, F1 84.99% A级(优秀)
文本生成 BLEU 0.0789, ROUGE 0.0 F级(不及格) 生成质量极差
7. 业务场景适用性
当前状态:不适合使用
  • 生产环境:完全不适合
  • 研究用途:可以作为反面案例
  • 教学用途:可以展示模型局限性
改进后可能适用
  • 初步筛选:经过大幅改进后可能用于粗筛
  • 辅助工具:作为人工摘要的辅助工具
  • 学习研究:用于模型改进研究
8. 技术建议
模型选择
# 推荐使用更大的模型
model_name = "Qwen/Qwen1.5-1.8B"  # 或更大
# 或者使用专门的中文摘要模型
model_name = "microsoft/DialoGPT-medium"
参数优化
# 更保守的生成参数
generation_config = {
    "max_new_tokens": 30,
    "min_new_tokens": 10,
    "temperature": 0.1,        # 更确定
    "top_k": 10,               # 更保守
    "do_sample": True,
    "repetition_penalty": 1.2,
    "no_repeat_ngram_size": 2,
}
9. 结论

当前模型表现评级:F级(不及格)

  • 主要问题:生成质量极差,内容与参考完全无关
  • 根本原因:模型能力不足,可能不适合中文摘要任务
  • 改进方向:需要大幅改进或更换模型
  • 适用性:当前完全不适合生产环境使用

建议:这是一个典型的模型能力不足案例,需要从模型选择、参数调优、提示词设计等多个方面进行根本性改进,或者考虑使用更适合的模型。
0.5B的模型确实偏小,不太实用。

四、指标选择指南

4.1 文本嵌入模型指标选择

场景 推荐指标 原因
二分类任务 准确率 + F1 整体性能 + 平衡评估
信息检索 召回率 + F1 关注找到相关内容
推荐系统 精确率 + F1 关注推荐质量
不平衡数据 F1 + 精确率 避免准确率误导

4.2 文本生成模型指标选择

场景 推荐指标 原因
机器翻译 BLEU + ROUGE 词汇匹配 + 内容覆盖
文本摘要 ROUGE + BLEU 内容覆盖 + 词汇匹配
创意写作 困惑度 + 人工评估 语言质量 + 创意性
对话系统 困惑度 + 人工评估 流畅性 + 相关性

五、评估最佳实践

5.1 数据准备

  • 选择代表性强的测试集
  • 确保数据质量和标注一致性
  • 考虑数据分布和平衡性

5.2 指标组合

  • 使用多个指标综合评估
  • 根据应用场景选择主要指标
  • 结合人工评估验证自动指标

5.3 结果分析

  • 分析错误案例找出模型弱点
  • 对比不同模型和参数设置
  • 关注指标趋势而非绝对数值

六、总结

大模型评估是一个多维度、多指标的综合过程。文本嵌入模型主要关注语义相似性判断的准确性,而文本生成模型则需要从内容质量、语言流畅性等多个角度评估。选择合适的评估指标和评估方法,对于模型优化和应用部署至关重要。

通过本文介绍的评估方法和代码示例,读者可以建立完整的大模型评估体系,为模型选择和优化提供科学依据。记住,没有完美的评估指标,只有适合特定场景的指标组合。在实际应用中,建议结合多个指标和人工评估,获得更全面、更可靠的模型性能评估结果。

Logo

更多推荐