如何用Python计算并打印文本文件中词语的两两余弦相似度矩阵?
实现词语余弦相似度矩阵的Python代码方案
没问题,我帮你搞定这个余弦相似度矩阵的代码!咱们一步步来,先理清楚思路:首先读取文本文件内容,把句子拆成独立词语并做简单预处理,接着把每个词转换成可计算的向量,然后计算每对词语的余弦相似度,最后把结果整理成行列都是词语的矩阵格式打印出来。
基础版:One-Hot编码实现(适合短文本快速验证)
如果只是需要验证逻辑,One-Hot编码是最简单的词向量表示方式,代码如下:
import numpy as np from sklearn.metrics.pairwise import cosine_similarity # 1. 读取并预处理文本 def load_and_preprocess_text(file_path): with open(file_path, 'r', encoding='utf-8') as f: text = f.read().lower() # 统一转小写避免大小写差异 # 去除干扰标点 punctuation = [',', '.', "'"] for p in punctuation: text = text.replace(p, '') # 按空格分割成词语列表 words = text.split() # 去重并保留原顺序 unique_words = list(dict.fromkeys(words)) return words, unique_words # 2. 生成One-Hot词向量矩阵 def create_one_hot_vectors(unique_words): vocab_size = len(unique_words) word_to_idx = {word: idx for idx, word in enumerate(unique_words)} # 初始化矩阵,每个词对应一个仅自身位置为1的向量 one_hot_matrix = np.zeros((vocab_size, vocab_size)) for word, idx in word_to_idx.items(): one_hot_matrix[idx, idx] = 1 return one_hot_matrix, word_to_idx # 3. 计算余弦相似度矩阵 def compute_cosine_similarity(vector_matrix): # 用sklearn工具快速计算所有向量对的相似度 return cosine_similarity(vector_matrix) # 4. 格式化打印矩阵(行列对齐更易读) def print_similarity_matrix(similarity_matrix, unique_words): # 打印表头(所有词语) print(' '.join(['{:>10}'.format(word) for word in [''] + unique_words])) # 逐行打印每个词语对应的相似度值 for idx, word in enumerate(unique_words): row = [word] + ['{:.2f}'.format(val) for val in similarity_matrix[idx]] print(' '.join(['{:>10}'.format(item) for item in row])) # 主执行逻辑 if __name__ == "__main__": file_path = 'f.txt' words, unique_words = load_and_preprocess_text(file_path) one_hot_matrix, word_to_idx = create_one_hot_vectors(unique_words) similarity_matrix = compute_cosine_similarity(one_hot_matrix) print_similarity_matrix(similarity_matrix, unique_words)
进阶版:基于共现窗口的语义相似度(符合你提到的非零跨词相似度)
One-Hot编码下不同词语的相似度为0,如果你想要类似0.54、0.42这种反映上下文关联的相似度值,可以用共现矩阵生成词向量,代码如下:
import numpy as np from sklearn.metrics.pairwise import cosine_similarity def load_and_preprocess_text(file_path): with open(file_path, 'r', encoding='utf-8') as f: text = f.read().lower() punctuation = [',', '.', "'"] for p in punctuation: text = text.replace(p, '') words = text.split() unique_words = list(dict.fromkeys(words)) return words, unique_words # 生成共现矩阵(窗口大小设为2,即每个词左右各2个词算共现) def create_cooccurrence_matrix(words, unique_words, window_size=2): vocab_size = len(unique_words) word_to_idx = {word: idx for idx, word in enumerate(unique_words)} cooccurrence_matrix = np.zeros((vocab_size, vocab_size)) for idx, word in enumerate(words): # 确定当前词的上下文窗口范围 start = max(0, idx - window_size) end = min(len(words), idx + window_size + 1) # 遍历窗口内的邻居词,更新共现次数 for neighbor_idx in range(start, end): if neighbor_idx != idx: neighbor_word = words[neighbor_idx] cooccurrence_matrix[word_to_idx[word]][word_to_idx[neighbor_word]] += 1 return cooccurrence_matrix, word_to_idx def compute_cosine_similarity(vector_matrix): return cosine_similarity(vector_matrix) def print_similarity_matrix(similarity_matrix, unique_words): print(' '.join(['{:>10}'.format(word) for word in [''] + unique_words])) for idx, word in enumerate(unique_words): row = [word] + ['{:.2f}'.format(val) for val in similarity_matrix[idx]] print(' '.join(['{:>10}'.format(item) for item in row])) # 主执行逻辑 if __name__ == "__main__": file_path = 'f.txt' words, unique_words = load_and_preprocess_text(file_path) cooccurrence_matrix, word_to_idx = create_cooccurrence_matrix(words, unique_words) similarity_matrix = compute_cosine_similarity(cooccurrence_matrix) print_similarity_matrix(similarity_matrix, unique_words)
小提示
- 共现窗口大小可以调整:
window_size越大,包含的上下文信息越多,相似度计算会更偏向全局关联。 - 如果需要更精准的语义相似度,可以替换成预训练的Word2Vec/GloVe词向量,只需要把生成向量的部分换成加载预训练模型的逻辑即可,相似度计算方式完全一致。
内容的提问来源于stack exchange,提问作者LamaMo
相关产品推荐
相关产品推荐

