1

我在 scikit learn 中使用标签传播进行半监督分类。我有 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.
4

1 回答 1

2

你的电脑有多少内存?

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 在这里所做的那样构建完整的所有对距离矩阵来将内存复杂度换成时间复杂度。

于 2013-09-16T00:34:15.173 回答