标签传播 - 数组太大

时间:2013-09-15 12:25:59

标签: python classification scikit-learn unsupervised-learning

我在scikit中使用标签传播学习半监督分类。我有7个维度的17,000个数据点。我无法在此数据集上使用它。它抛出一个numpy大数组错误。但是,当我处理相对较小的数据集200分时,它工作正常。任何人都可以建议修复吗?

label_prop_model.fit(np.array(data), labels)
File "/usr/lib/pymodules/python2.7/sklearn/semi_supervised/mylabelprop.py", line 58, in fit
graph_matrix = self._build_graph()
File "/usr/lib/pymodules/python2.7/sklearn/semi_supervised/mylabelprop.py", line 108, in _build_graph
affinity_matrix = self._get_kernel(self.X_) # get the affinty martix from the data using rbf kernel
File "/usr/lib/pymodules/python2.7/sklearn/semi_supervised/mylabelprop.py", line 26, in _get_kernel
return rbf_kernel(X, X, gamma=self.gamma)
File "/usr/lib/pymodules/python2.7/sklearn/metrics/pairwise.py", line 350, in rbf_kernel
K = euclidean_distances(X, Y, squared=True)
File "/usr/lib/pymodules/python2.7/sklearn/metrics/pairwise.py", line 173, in euclidean_distances
distances = safe_sparse_dot(X, Y.T, dense_output=True)
File "/usr/lib/pymodules/python2.7/sklearn/utils/extmath.py", line 79, in safe_sparse_dot
return np.dot(a, b)
ValueError: array is too big.

1 个答案:

答案 0 :(得分:1)

您的计算机有多少内存?

sklearn可能在这里做什么(我没有通过源,所以我可能错了)通过取17000xK矩阵的平方来计算每个数据点之间的向量的欧几里德长度。这将产生所有数据点的欧氏距离平方,但遗憾的是,如果您有N个数据点,则会生成NxN输出矩阵。据我所知,numpy使用双精度,这导致17000x17000x8字节矩阵,大约2.15 GB。

如果你的记忆不能容纳那个会造成麻烦的矩阵。尝试用numpy创建这个大小的矩阵:

import numpy
mat = numpy.ones(17000, 17000)

如果成功我就错了,问题就是其他问题(虽然肯定与内存大小和sklearn试图分配的矩阵有关)。

在我的脑海中,解决这个问题的一种方法可能是通过对未标记的数据点进行二次采样来传播部分标签(如果你有许多标记点,可能还有标记点)。如果您能够运行17000/2数据点的算法并且您有 L 标记点,则通过随机绘制(17000- L )/ 2来构建新数据集来自原始集合的未标记点,并将它们与 L 标记点组合。为整个集的每个分区运行算法。

请注意,这可能会降低标签传播算法的性能,因为它可以使用更少的数据点。每组中标签之间的不一致也可能导致麻烦。 极其谨慎地使用,并且只有在您有某种方式来评估性能时才会使用:)

更安全的方法是 A :获取更多内存或 B :获取内存密集程度较低的标签传播算法。通过在需要时重新计算欧氏距离而不是像scikit似乎在这里做的那样构建一个完整的所有对距离矩阵,当然可以通过时间复杂度来交换记忆复杂性。