
本文介绍如何利用预训练句子嵌入模型(如sentence transformers)计算每条文本与指定5个关键词之间的语义相似度,并将0–1范围内的相似分批量注入dataframe新列,实现高效、可解释的关键词代表性量化。
本文介绍如何利用预训练句子嵌入模型(如sentence transformers)计算每条文本与指定5个关键词之间的语义相似度,并将0–1范围内的相似分批量注入dataframe新列,实现高效、可解释的关键词代表性量化。
在自然语言处理任务中,常需评估若干关键词对一段文本的“语义代表性”——即该词是否在语义空间中贴近文本整体含义,而非简单依赖词频或共现。例如,文本 "I want to eat" 与词 food 的语义关联远强于 house,这种关系无法通过传统关键词匹配捕获,而需基于上下文感知的向量表示进行建模。
推荐使用 sentence-transformers 库中的轻量级预训练模型(如 all-MiniLM-L6-v2),它能将文本和单词统一映射到同一高维语义空间,再通过余弦相似度量化语义距离(值域 [0, 1],越接近1表示语义越相近)。
以下是一个完整、可复用的实现方案:
import pandas as pd
from sentence_transformers import SentenceTransformer, util
class SemanticSimilarityCalculator:
def __init__(self, model_name: str = 'all-MiniLM-L6-v2') -> None:
self.model = SentenceTransformer(model_name)
self.word_embeddings = None
self.words = None
def encode_words(self, words: list[str]) -> None:
"""预先编码关键词,提升后续批量计算效率"""
self.word_embeddings = self.model.encode(words, convert_to_tensor=True)
self.words = words
def calculate_similarity(self, text: str) -> list[float]:
if self.word_embeddings is None:
raise ValueError("请先调用 encode_words() 编码关键词")
text_embedding = self.model.encode(text, convert_to_tensor=True)
# 计算文本向量与所有词向量的余弦相似度
similarities = util.cos_sim(text_embedding, self.word_embeddings)[0].tolist()
return similarities
def add_similarity_scores_to_df(
self, df: pd.DataFrame, text_column: str, prefix: str = "word_"
) -> pd.DataFrame:
if self.words is None:
raise ValueError("请先调用 encode_words() 编码关键词")
# 生成列名:如 word_food、word_house
score_columns = [f"{prefix}{word}" for word in self.words]
# 批量应用相似度计算,返回多列
df[score_columns] = df[text_column].apply(
lambda x: pd.Series(self.calculate_similarity(x))
)
return df
# ✅ 使用示例
if __name__ == "__main__":
# 构造示例数据
df = pd.DataFrame({
"text": ["I want to eat", "The house is big", "I need to sleep"]
})
target_words = ["food", "house", "sleep", "drink", "run"]
# 初始化计算器并编码关键词
calc = SemanticSimilarityCalculator()
calc.encode_words(target_words)
# 注入相似度得分(自动创建 word_food, word_house 等列)
df_result = calc.add_similarity_scores_to_df(df, text_column="text")
print(df_result.round(4))
输出示例:
text word_food word_house word_sleep word_drink word_run 0 I want to eat 0.5924 0.2150 0.2541 0.3703 0.2594 1 The house is big 0.2433 0.6721 0.1708 0.2138 0.1197 2 I need to sleep 0.2537 0.2225 0.7251 0.3584 0.3038
✅ 关键优势与注意事项:
- 语义驱动:模型理解“eat”与“food”的深层关联,而非仅匹配字面;
- 高效批量:关键词仅编码一次,后续文本逐行推理,适合千级规模数据;
-
可扩展性强:支持任意数量关键词,列名前缀
prefix可自定义(如"score_"); -
模型选择建议:
all-MiniLM-L6-v2平衡速度与精度;若需更高精度,可换用all-mpnet-base-v2(稍慢但更准); - 注意歧义词:如 “apple” 在科技/水果语境下语义不同,本方法默认取通用嵌入;如需领域适配,建议微调模型或使用领域专用模型。
该方法已广泛应用于内容标签打分、搜索相关性排序、智能问卷分析等场景,是构建可解释语义评分系统的可靠基础。










