问:BERT与GloVe词嵌入的差异及多语境下bank嵌入相似度解读
BERT Embeddings 与 GloVe 的核心差异
- 静态 vs 语境化:GloVe是静态词嵌入,每个词对应唯一固定向量,不随上下文变化;BERT是语境化嵌入,同一词在不同语义场景下会生成不同向量。
- 训练逻辑:GloVe基于全局语料的词共现统计,通过矩阵分解学习通用语义;BERT基于双向Transformer架构,以掩码语言模型(MLM)和下一句预测(NSP)为预训练目标,深度捕捉上下文依赖关系。
- 歧义处理能力:GloVe无法区分多义词的不同语义,只能表达词的通用含义;BERT能根据动态语境调整向量,精准区分多义词的不同语义指向。
- 规模与维度:GloVe常见维度为50/100/200/300,训练数据规模相对有限;BERT-base为768维,基于超大规模语料库(如BooksCorpus+Wikipedia)训练,语义表达更丰富。
语境化词表示实验相关疑问解答
1. 嵌入差异程度与余弦相似度解读
余弦相似度取值范围为[-1,1],值越接近1表示向量语义越相似,越接近0表示语义无关,接近-1表示语义完全相反。
在BERT的实际表现中:
- 同一词的不同语义(如"bank"的金融/河岸义),余弦相似度通常在0.5~0.7区间,明显低于同一语义重复出现的相似度(通常>0.8);
- 完全无关的词(如"bank"与"football"),相似度一般在0.2~0.4左右。
2. 不同语境下"bank"的嵌入应该相似还是不同?
若BERT正常工作,两个不同语境下的"bank"嵌入应表现出显著差异:
- 金融语境的"bank"向量会偏向金融领域特征,与"loan""application"等词汇语义关联紧密;
- 河岸语境的"bank"向量会偏向场景描述特征,与"river""sat"等词汇语义关联紧密;
- 这种差异正是BERT语境化嵌入的核心价值,也是其能解决多义词歧义问题的关键。
实验代码
from transformers import BertTokenizer, BertModel import torch, numpy as np from sklearn.metrics.pairwise import cosine_similarity import seaborn as sns, matplotlib.pyplot as plt tokenizer = BertTokenizer.from_pretrained("bert-base-uncased") model = BertModel.from_pretrained("bert-base-uncased") model.eval() sentences = [ "The bank approved my loan application.", "She sat quietly on the river bank.", "I love playing football on weekends.", "The goal was scored in the final minute." ] cls_embeddings = [] all_outputs = [] all_inputs = [] for sent in sentences: inputs = tokenizer(sent, return_tensors="pt") with torch.no_grad(): outputs = model(**inputs) cls_emb = outputs.last_hidden_state[0, 0, :].numpy() # [CLS] token cls_embeddings.append(cls_emb) all_outputs.append(outputs) all_inputs.append(inputs) cls_embeddings = np.array(cls_embeddings) sim_matrix = cosine_similarity(cls_embeddings) labels = ["Bank(loan)", "Bank(river)", "Football", "Goal"] plt.figure(figsize=(6, 5)) sns.heatmap(sim_matrix, annot=True, xticklabels=labels, yticklabels=labels, cmap="viridis", vmin=0, vmax=1) plt.title("Cosine Similarity of [CLS] Embeddings") plt.tight_layout() plt.show() def get_word_embedding(sentence, word, tokenizer, model): inputs = tokenizer(sentence, return_tensors="pt") tokens = tokenizer.convert_ids_to_tokens(inputs["input_ids"][0]) with torch.no_grad(): outputs = model(**inputs) idx = tokens.index(word) return outputs.last_hidden_state[0, idx, :].numpy() bank_emb1 = get_word_embedding(sentences[0], "bank", tokenizer, model) bank_emb2 = get_word_embedding(sentences[1], "bank", tokenizer, model) bank_sim = cosine_similarity([bank_emb1], [bank_emb2])[0][0] print(f"Cosine similarity between 'bank' embeddings: {bank_sim:.4f}")
内容的提问来源于stack exchange,提问作者Sandesh Singh
相关产品推荐
相关产品推荐

