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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:32:24