如何遍历字符串列表生成成对WMD距离矩阵?(结合SpaCy与wmd-relax)
我来帮你搞定这个WMD距离矩阵的生成问题!既然你已经把wmd-relax和SpaCy对接好了,那接下来的核心就是遍历所有文本对计算距离,然后整理成符合需求的矩阵。下面是具体的步骤和代码示例,一步步来:
步骤1:先把新闻文本转换成SpaCy Doc对象
首先得把你的新闻文章列表转换成SpaCy处理后的Doc对象,这是用wmd-relax计算距离的前提。示例代码如下:
import spacy # 加载你配置好的SpaCy模型(确保已经和wmd-relax集成完毕) nlp = spacy.load("en_core_web_md") # 这里用预训练的md模型,你可以换成自己训练的 # 你的新闻文章列表,替换成你实际的数据 news_articles = [ "Apple announces new iPhone with improved camera features.", "Tech giant reveals latest smartphone upgrade focusing on photography.", "Stock market rises following positive earnings reports from tech companies." ] # 批量转换成SpaCy Doc对象 docs = [nlp(article) for article in news_articles]
步骤2:生成成对WMD距离矩阵
接下来要遍历所有两两文本组合计算WMD距离,这里提供两种常用的矩阵格式供你选择:
方式1:生成压缩矩阵(和scipy pdist输出格式一致)
如果你想和scipy的pdist输出格式匹配,只需要计算所有i<j的文本对(避免重复计算),得到一个一维的压缩矩阵:
import numpy as np from itertools import combinations condensed_distances = [] # 遍历所有不重复的文本对 for doc1, doc2 in combinations(docs, 2): # 调用wmd-relax的方法计算距离(注意:返回的是距离值,越小越相似) wmd_distance = doc1.wmd(doc2) condensed_distances.append(wmd_distance) # 转换成numpy数组,方便后续处理 condensed_matrix = np.array(condensed_distances)
方式2:生成对称方阵(更直观)
如果你想要一个N×N的对称矩阵(N是新闻数量),对角线为0(自己和自己的距离为0),这样查看任意两篇新闻的距离会更直观:
n = len(docs) square_matrix = np.zeros((n, n)) for i in range(n): for j in range(n): if i == j: square_matrix[i][j] = 0.0 elif i < j: # 计算一次距离,利用WMD的对称性赋值给两个位置 distance = docs[i].wmd(docs[j]) square_matrix[i][j] = distance square_matrix[j][i] = distance
这样square_matrix[i][j]就代表第i篇和第j篇新闻的WMD距离。
可选:和scipy工具兼容
如果你之后想用scipy的其他距离相关工具处理,可以轻松在压缩矩阵和方阵之间转换:
from scipy.spatial.distance import squareform # 压缩矩阵转方阵 square_matrix_from_condensed = squareform(condensed_matrix) # 方阵转压缩矩阵 condensed_matrix_from_square = squareform(square_matrix)
几个要注意的点
- 确认wmd-relax集成成功:正常情况下,安装wmd-relax后,SpaCy的Doc对象会自动拥有
wmd方法,如果没有的话,检查一下安装步骤是否正确。 - 计算效率:WMD本身计算成本不低,新闻数量多的时候可能会慢,不过wmd-relax已经是优化后的实现了,比原生WMD快不少。
- 文本预处理:如果你的新闻有很多噪声(比如特殊字符、无意义的停用词),建议先做清洗(比如去标点、停用词,词形还原等),这样计算出来的距离会更准确。
内容的提问来源于stack exchange,提问作者Jan Pesl
相关产品推荐
相关产品推荐

