提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 前言
- 加載預訓練詞向量
- TokenEmbedding 類詳解
- 預訓練詞向量簡介 (GloVe)
- 具體含義
- 總結建議
- 應用預訓練詞向量
- 詞相似度
- knn 函數
- get_similar_tokens 函數
- 相似詞查找示例
- 詞類比
- get_analogy 函數
- 詞類比任務示例
- 總結
前言
詞向量(Word Embeddings)是自然語言處理(NLP)中的基石之一。它們是將詞匯表中的詞語映射到低維連續向量空間的技術,使得語義上相似的詞在向量空間中也彼此接近。實際上,在大型語料庫上預先訓練的詞向量可以應用于下游的自然語言處理任務,這將在后面討論。為了直觀地演示大型語料庫中預訓練詞向量的語義,讓我們將預訓練詞向量應用到詞的相似性和類比任務中。
本篇博客將通過 PyTorch 代碼實例,展示如何加載和使用預訓練的 GloVe 詞向量,并將其應用于查找相似詞和完成詞類比任務。我們將一步步解析代碼,幫助大家理解其背后的原理。
完整代碼:下載鏈接
加載預訓練詞向量
首先,我們需要一種方式來加載和管理預訓練的詞向量。下面我們將定義一個 TokenEmbedding
類,它能夠從文本文件中加載詞向量(如 GloVe 或 fastText 格式),并提供方便的接口來查詢詞語對應的向量。
TokenEmbedding 類詳解
這個類將負責以下核心功能:
- 從指定的詞向量文件加載詞匯表和對應的向量。
- 為詞匯表中的每個詞創建一個索引。
- 為不在詞匯表中的“未知”詞(unk)提供一個默認向量(通常是零向量)。
- 允許通過詞語列表快速獲取它們對應的向量矩陣。
import torch
import osclass TokenEmbedding:"""GloVe詞嵌入類用于加載和使用預訓練的詞向量(如GloVe、fastText等)"""def __init__(self, embedding_name):"""初始化TokenEmbedding對象參數:embedding_name (str): 嵌入文件名(不含擴展名),例如 'glove.6B.50d'屬性:idx_to_token (list): 索引到詞匯的映射列表,維度為[vocab_size]idx_to_vec (torch.Tensor): 索引到向量的映射矩陣,維度為[vocab_size, embedding_dim]unknown_idx (int): 未知詞匯的索引,默認為0token_to_idx (dict): 詞匯到索引的映射字典"""# 加載嵌入文件,獲取詞匯列表和向量矩陣self.idx_to_token, self.idx_to_vec = self._load_embedding(embedding_name)# 設置未知詞匯的索引為0(對應'<unk>'標記)self.unknown_idx = 0# 創建詞匯到索引的反向映射字典# token_to_idx: dict,鍵為詞匯(str),值為索引(int)self.token_to_idx = {token: idx for idx, token in enumerate(self.idx_to_token)}def _load_embedding(self, embedding_name):"""從文件加載預訓練的詞嵌入參數:embedding_name (str): 嵌入文件名返回:idx_to_token (list): 詞匯列表,維度為[vocab_size]idx_to_vec (torch.Tensor): 詞向量矩陣,維度為[vocab_size, embedding_dim]"""# 初始化詞匯列表和向量列表,第一個位置預留給未知詞匯標記idx_to_token = ['<unk>'] # list,存儲所有詞匯,維度為[vocab_size]idx_to_vec = [] # list,臨時存儲向量,后續轉換為tensor# 構建數據文件路徑data_dir = embedding_name + ".txt"# GloVe網站:https://nlp.stanford.edu/projects/glove/# fastText網站:https://fasttext.cc/# 檢查文件是否存在if not os.path.exists(data_dir):print(f"警告:嵌入文件 {data_dir} 不存在。請確保已下載并放置在正確路徑。")print("例如,可以從 https://nlp.stanford.edu/data/glove.6B.zip 下載glove.6B.50d.txt")# 為演示目的,創建一個空的占位符,實際應用中應拋出錯誤或處理# raise FileNotFoundError(f"嵌入文件 {data_dir} 不存在")return ['<unk>'], torch.zeros((1,1)) # 返回一個最小的有效結構# 逐行讀取嵌入文件with open(data_dir, 'r', encoding='utf-8') as f:for line in f:# 移除行尾換行符并按空格分割elems = line.rstrip().split(' ')# 第一個元素是詞匯,其余元素是向量值token = elems[0] # str,當前詞匯# 將字符串向量值轉換為浮點數列表try:# 嘗試轉換,處理fastText首行可能不符合格式的情況vec_values = [float(elem) for elem in elems[1:]] # list[float],維度為[embedding_dim]except ValueError:# print(f"跳過格式不正確的行: {line[:50]}...") # 對于fastText,這可能是第一行continue# 跳過標題信息或格式錯誤的行(例如fastText中的首行通常是詞匯數和維度)if len(vec_values) > 1 and token: # 確保有向量值且token不為空idx_to_token.append(token)idx_to_vec.append(vec_values)# 為未知詞匯<unk>創建零向量# 向量維度與其他詞匯向量保持一致embedding_dim = len(idx_to_vec[0]) if idx_to_vec else 50 # 如果列表為空,默認50維unknown_vec = [0.0]