嵌套字典提取数组转ndarray,如何适配sklearn余弦相似度生成目标矩阵
问题根源定位
你遇到的形状不匹配问题,本质是两个操作上的疏漏:
- 嵌套字典里每个年份对应类别的TF-IDF,本身是形状为
(1, n_features)的二维数组,不是一维向量。直接把这些二维元素丢进列表转numpy数组,得到的是三维结构,根本不符合sklearn余弦相似度要求的二维(n_samples, n_features)输入格式 - 之前尝试的暴力reshape,没有先对齐维度的实际含义:用
reshape(1,-1)把整个三维数组拉成单行,相当于只有1个样本,最终算出1×1的结果;用reshape(-1,1)把数组拉成单列,把特征维度错当成样本维度,最终算出尺寸完全不符合要求的大矩阵
正确实现方法
1. 提取单类别TF-IDF的二维矩阵
收集每个年份的目标类别(比如negative)TF-IDF时,先把单文档附带的多余维度去掉,再统一组装成模块要求的二维矩阵:
import numpy as np from sklearn.metrics.pairwise import cosine_similarity def build_class_tfidf(tfidf_dict, year_list, class_name): vec_list = [] for year in year_list: # squeeze会自动删除所有长度为1的维度,把(1, n_features)的单文档数组压成(n_features,)的一维向量 single_tfidf = tfidf_dict[year][class_name].squeeze() vec_list.append(single_tfidf) # 把收集的一维向量堆成二维数组,此时形状严格为(样本数=len(year_list), 特征数=n_features) return np.asarray(vec_list)
2. 提前校验维度,避免无效计算
在传入余弦相似度模块前,一定要打印矩阵的shape确认维度正确:
- 第一维必须等于你要计算的文档总数(也就是你预期的9)
- 第二维是所有文档共有的TF-IDF特征总长度
# 提取negative类别的所有文档TF-IDF neg_matrix = build_class_tfidf(tfidf_ten_ks, dates, "negative") # 预期输出形状为 (9, 你的TF-IDF特征维度数) print(neg_matrix.shape)
3. 直接计算相似度
只要确认输入是形状为(9, n_features)的二维数组,直接传给余弦相似度模块就行,不需要额外做任何reshape:
# 输入是(9, n_features)时,输出的相似度矩阵必然是(9,9),正好是9个文档两两的相似度 neg_cos_sim = cosine_similarity(neg_matrix) # 可打印形状验证,预期输出 (9,9) print(neg_cos_sim.shape)
踩坑提示
- 不要在三维数组上硬做reshape操作,只要输入不是二维结构,要么直接触发sklearn报错,要么算出完全无效的结果
- 后续要算positive等其他类别的相似度时,只要替换
class_name参数重复调用build_class_tfidf即可,整套逻辑完全复用 - 如果后续处理稀疏格式的TF-IDF,
squeeze操作同样兼容,只要保证最终传入的是二维结构,余弦相似度模块可以直接正常计算,不需要转成稠密数组
内容的提问来源于stack exchange,提问作者Zèro
相关产品推荐
相关产品推荐

