t-SNE降维技术

7
我有两组数据,分别是训练集和测试集。这两组数据都有30213和30235个项目,并且每个项目有66个维度。
我尝试使用scikit learn的t-SNE算法将维度降至2。由于数据集很大,如果我尝试一次性处理整个数据集,就会出现内存错误。因此,我尝试将它们分成块,并依次转换一个块,如下所示:
tsne = manifold.TSNE(n_components=2, perplexity=30, init='pca', random_state=0)

X_tsne_train = np.array( [ [ 0.0 for j in range( 2 ) ] for i in range( X_train.shape[0] ) ] )

X_tsne_test = np.array( [ [ 0.0 for j in range( 2 ) ] for i in range( X_test.shape[0] ) ] )

d = ( ( X_train, X_tsne_train ), ( X_test, X_tsne_test ) )

chunk = 5000

for Z in d:

        x, x_tsne = Z[0], Z[1]
        pstart, pend = 0, 0
        while pend < x.shape[0]:
                if pend + chunk < x.shape[0]:
                        pend = pstart + chunk
                else:
                        pend = x.shape[0]
                print 'pstart = ', pstart, 'pend = ', pend
                x_part = x[pstart:pend]
                x_tsne[pstart:pend] += tsne.fit_transform(x_part)
                pstart = pend

它运行时不会出现MemoryError,但我发现相同的数据项在脚本的不同运行中产生了不同的输出。这可能是因为每块数据上的拟合和变换操作同时进行。但如果我尝试在训练数据上进行拟合 tsne.fit(X_train),我会得到一个MemoryError。如何正确地将所有训练和测试集中的数据项降到2维而没有任何片段间的不一致性?


正如当前答案所指出的那样,您无法将t-sne应用于较小的块并以有意义的方式合并结果。尽管如此,我对更简单的问题感兴趣:“我有少量数据(66维中的5k个项目),但t-SNE会产生MemoryError错误,为什么会这样?”(我个人在50维中有24k行,也遇到了同样的问题)。 - Nikana Reklawyks
1个回答

2
我不完全确定你所说的“相同数据项的不同输出”是什么意思,但这里有一些评论可能会对你有所帮助。
首先,t-SNE并不像PCA或其他方法那样是一种真正的“降维”技术。没有办法将一个固定的、学习过的t-SNE模型应用于新数据。(请注意,该类没有transform()方法,只有fit()和fit_transform()方法。)因此,你将无法使用“训练”和“测试”集。
其次,每次调用fit_transform()时,你都会得到一个完全不同的模型。因此,你所缩减的维度的含义在每个块之间是不一致的。每个块都有自己的小低维空间。模型每次都不同,因此数据没有被投影到相同的空间中。
第三,你没有包括将“train”与“test”分开的代码。也许,在你小心地设置t-SNE的随机种子的同时,你没有设置你的训练/测试分割的随机种子,导致后续运行结果不同。
最后,如果您想使用t-SNE来可视化您的数据,您可以考虑遵循文档页面上的建议,应用PCA将输入的维度从66降至15。这将大大减少t-SNE的内存占用。 SKLearn文档中的t-SNE

2
虽然这些都是真实的,但对于那些有合理维度数据并遇到“MemoryError”的人来说并没有什么帮助。t-SNE FAQ建议在数据过大时降低数据的维度,但我的理解是,在50维中有数百万个示例应该是可以的,只要时间足够长。我有24k个点在50维中,这不算太大。为什么会失败? - Nikana Reklawyks
我们如何避免内存错误?是手动分区或拆分数据吗? - Beyhan Gul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接