Python中sklearn的TSNE降维后向量与原向量对应关系问题
现在手里有 360w 个 200 维向量,存放在 np.array 里,想把这些向量降维到二维然后投影出来,观察聚类情况。 使用 TSNE 的时候,出现问题,会卡住,过一段时间自动 kill 掉,但是如果用低维小数据测试则可以正常运行。
请问是不是数据太大,是否应该在训练时就调低向量维度?或者除 TSNE 外其他适合实现该数据降维的轮子。 环境为 python3.5,osx
Python中sklearn的TSNE降维后向量与原向量对应关系问题
想要没有性能问题和内存问题,请不要用 sklearn,效率极差。
手写一个就好
TSNE降维后向量与原向量的对应关系是通过索引顺序保持的。简单来说,TSNE.fit_transform(X)返回的二维/三维数组的第i行,就对应输入数据X的第i行。
举个例子,假设你有一个形状为(100, 50)的原始数据矩阵X,表示100个样本,每个样本有50个特征。执行TSNE降维到2维:
from sklearn.manifold import TSNE
import numpy as np
# 假设这是你的原始数据,100个样本,50维特征
X = np.random.randn(100, 50)
# 创建TSNE模型,降维到2维
tsne = TSNE(n_components=2, random_state=42, perplexity=30)
# 执行降维,得到新坐标
X_tsne = tsne.fit_transform(X)
print(f"原始数据形状: {X.shape}") # (100, 50)
print(f"降维后形状: {X_tsne.shape}") # (100, 2)
# 验证对应关系:第i个样本的对应关系
i = 42 # 随便选一个索引
print(f"\n原始数据第{i}个样本 (前5个特征): {X[i, :5]}")
print(f"降维后第{i}个样本的坐标: {X_tsne[i]}")
关键点说明:
- 顺序对应:
X_tsne[0]对应X[0],X_tsne[1]对应X[1],依此类推。这个对应关系是严格保持的。 - 标签同步:如果你有标签数据
y,降维后可视化时,y[i]的标签就对应X_tsne[i]这个点。 - fit_transform vs fit + transform:
fit_transform()在单次降维时使用。如果你需要对新数据(训练集外的数据)降维,理论上应该用fit()拟合训练集,再用transform()转换新数据,但注意:TSNE通常没有transform方法,因为它不是线性变换,且设计初衷就是可视化整个数据集。
一个完整的可视化示例,展示如何保持对应关系:
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.manifold import TSNE
# 加载手写数字数据集
digits = load_digits()
X = digits.data # 特征 (1797, 64)
y = digits.target # 标签 (1797,)
# TSNE降维
tsne = TSNE(n_components=2, random_state=42)
X_tsne = tsne.fit_transform(X)
# 可视化:用颜色表示原始标签
plt.figure(figsize=(10, 8))
scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y,
cmap='tab10', alpha=0.6, s=20)
plt.colorbar(scatter, label='Digit Label')
plt.title('TSNE Visualization of Digits Dataset')
plt.xlabel('TSNE Component 1')
plt.ylabel('TSNE Component 2')
# 验证对应关系:标注几个点
for idx in [0, 100, 500, 1000]: # 选几个样本
plt.annotate(f'X[{idx}]->y={y[idx]}',
xy=(X_tsne[idx, 0], X_tsne[idx, 1]),
xytext=(5, 5), textcoords='offset points',
fontsize=8, alpha=0.7)
plt.show()
常见问题:
- 数据洗牌:如果你在降维前对数据进行了洗牌(比如用
sklearn.utils.shuffle),必须同时对标签进行相同的洗牌,否则对应关系会错乱。 - 数据分割:如果先分割数据再分别降维,对应关系会乱,应该先降维再分割,或者确保用相同的随机种子。
总结:索引即对应关系,保持顺序即可。
一个向量一个向量降就可以了吧
QAQ,这么残忍的么
现在的想法是一方面用 doc2vec 做句向量,一方面把 360w 个循环进行均值,取最后 3w 个左右结果,然后再做,目前的话切片之后跑个万条是没问题的
200 维这么整,是 w2v 的结果?
没用过 tsne,输入可以是稀疏矩阵或者生成器吗
试试 pca 或者用 SPSS 做主成分分析…
换个大内存的机器跑吧
好哒,这就去这就去
是 word2vec,这个是抓取的部分社交网站用户的发言,之后做的向量化,输入是 np.array
跑不动了…我选择向量加一加,数量级降下来再跑,应该还是对数据集有代表性的吧?
应该是内存扛不住了。
不过就算能跑出来,360w 也没法看吧,可以采样一部分比较重要的词做降维,比如可以按 embedding 向量的范数排序,选最大的几千个先看看。
另外如果要用 python 来搞,https://github.com/DmitryUlyanov/Multicore-TSNE 比 sklearn 的效率会高很多。
滑窗 归一 然后有中间步骤的话 记得每部 保存磁盘序列化对象
成本最小的是加内存 妈的 昨天晚上刚跑了 8600w+
我是每个 100w 然后结果再下一步 呵呵 然后多进程
TSNE 的文档,建议使用 PCA 或 TruncatedSVD 降维
It is highly recommended to use another dimensionality reduction method (e.g. PCA for dense data or TruncatedSVD for sparse data) to reduce the number of dimensions to a reasonable amount (e.g. 50) if the number of features is very high.
估计 sklearn 吃不消的


