You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用BERT-base-uncased计算余弦相似度时准确率为0的问题排查

问题排查与修正方案

核心错误点及修复

1. 问题与答案样本无对应关系

你分别对问题和答案做了随机采样:

sample_1000_quest = train_ds['questions'].sample(1000)
sample_1000_answer = train_ds['answers'].sample(1000)

这会导致采样的1000个问题和1000个答案完全随机配对,目标问题的真实答案大概率不在采样的答案集合里,准确率必然为0。

修复方式:
按行采样完整数据,保证每个问题对应其真实答案:

# 随机采样1000条完整数据(问题+答案一一对应)
sample_ds = train_ds.sample(1000)
sample_1000_quest = sample_ds['questions']
sample_1000_answer = sample_ds['answers']

2. 真实答案索引逻辑完全错误

原代码中:

ground_truth_idx = train_ds['answers'].iloc[selected_question_idx]

你把原数据集的答案内容当成了采样后答案列表的索引,逻辑完全混乱。正确逻辑是找到目标问题对应的真实答案,再定位它在采样答案集合中的位置索引。

修复方式:

# 获取目标问题对应的真实答案内容
ground_truth_answer = sample_ds['answers'].iloc[1]  # 对应selected_question = sample_1000_quest.iloc[1]
# 找到该答案在采样答案列表中的位置索引
ground_truth_pos = sample_1000_answer.index.get_loc(sample_ds.index[1])

后续判断准确率时用ground_truth_pos与most_similar_indices对比。

3. 设备不一致导致计算异常

原代码中,问题的embedding在CPU计算,答案的embedding在GPU计算,两个张量设备不匹配会导致余弦相似度计算结果异常。

修复方式:
统一将模型和所有张量放到同一设备:

# 模型移到指定设备
model_bert = model_bert.to(device)
# 问题编码也移到设备
encoded_question = tokenizer_bert(selected_question, return_tensors='pt', padding=True, truncation=True).to(device)
with torch.no_grad():
    outputs = model_bert(**encoded_question)
    question_embedding = outputs.last_hidden_state.mean(dim=1)

4. 模型与文本语言不匹配

你使用bert-base-uncased(英文预训练模型)处理土耳其语文本,该模型未学习过土耳其语语义,生成的embedding无法正确表示文本含义,导致匹配结果完全不相关。

修复方式:
使用土耳其语预训练BERT模型,比如dbmdz/bert-base-turkish-uncased:

tokenizer_bert = BertTokenizer.from_pretrained('dbmdz/bert-base-turkish-uncased')
model_bert = BertModel.from_pretrained('dbmdz/bert-base-turkish-uncased', output_hidden_states=True).eval().to(device)

修正后的完整代码示例

# 按行采样保证问题答案对应
sample_ds = train_ds.sample(1000)
sample_1000_quest = sample_ds['questions']
sample_1000_answer = sample_ds['answers']

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 使用土耳其语BERT模型
tokenizer_bert = BertTokenizer.from_pretrained('dbmdz/bert-base-turkish-uncased')
model_bert = BertModel.from_pretrained('dbmdz/bert-base-turkish-uncased', output_hidden_states=True).eval().to(device)

selected_question = sample_1000_quest.iloc[1]
# 获取对应真实答案及位置索引
ground_truth_answer = sample_ds['answers'].iloc[1]
ground_truth_pos = sample_1000_answer.index.get_loc(sample_ds.index[1])

# 编码问题并计算embedding
encoded_question = tokenizer_bert(selected_question, return_tensors='pt', padding=True, truncation=True).to(device)
with torch.no_grad():
    outputs = model_bert(**encoded_question)
    question_embedding = outputs.last_hidden_state.mean(dim=1)

# 编码所有答案并计算embedding
answer_embeddings = []
for answer in sample_1000_answer:
    encoded_answer = tokenizer_bert(answer, return_tensors='pt', padding=True, truncation=True).to(device)
    with torch.no_grad():
        outputs = model_bert(**encoded_answer)
        answer_embedding = outputs.last_hidden_state.mean(dim=1)
        answer_embeddings.append(answer_embedding)

# 计算余弦相似度
similarities = []
for answer_embedding in answer_embeddings:
    similarity = cosine_similarity(question_embedding, answer_embedding)
    similarities.append(similarity.item())

# 获取Top5相似答案的位置索引
most_similar_indices = np.argsort(similarities)[-5:][::-1]

# 计算准确率
top1_accuracy = 1 if most_similar_indices[0] == ground_truth_pos else 0
top5_accuracy = 1 if ground_truth_pos in most_similar_indices else 0

# 输出结果
print("Selected Question:", selected_question)
print("Ground Truth Answer:", ground_truth_answer)
print("Most similar 5 answers:")
for i, idx in enumerate(most_similar_indices):
    print(f"{i+1}. {sample_1000_answer.iloc[idx]}")

print("Top-1 Accuracy:", top1_accuracy)
print("Top-5 Accuracy:", top5_accuracy)

内容的提问来源于stack exchange,提问作者Zephyrus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:00:13