【问题标题】:Label Propagation - Array is too big标签传播 - 数组太大
【发布时间】:2013-09-19 16:15:32
【问题描述】:

我在 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.

【问题讨论】:

  • 请发布确切的错误信息。很难知道出了什么问题。
  • @larsmans。我已添加错误消息。

标签: python classification scikit-learn unsupervised-learning


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

【讨论】:

  • 您的分析基本正确,但np.ones 可以毫无问题地分配这样的数组。 np.dot 是问题所在:它使用 BLAS 来提高速度,但这将其限制为 BLAS 的 32 位 API,因此不能超过 2GB。
  • 谢谢亚历克斯,我更换了系统,它运行良好,虽然花了一些时间。我以前的机器有 2 GB,新的机器有 8 GB。
  • 感谢 larsmans,知道有用。我会在答案中指出您的评论。
猜你喜欢
  • 2014-04-05
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多