使用Scikit Learn的DictVectorizer时,toarray中的MemoryError

时间:2014-06-16 20:48:55

标签: python scipy scikit-learn

我正在尝试在我的数据上实现SelectKBest算法,以获得最佳功能。为此,我首先使用DictVectorizer预处理我的数据,数据由1061427行和15个功能组成。每个功能都有许多不同的值,我相信由于基数较高,我会收到内存错误。

我收到以下错误:

File "FeatureExtraction.py", line 30, in <module>
    quote_data = DV.fit_transform(quote_data).toarray()
File "/usr/lib64/python2.6/site-packages/scipy/sparse/compressed.py", line 563, in toarray
    return self.tocoo(copy=False).toarray()
File "/usr/lib64/python2.6/site-packages/scipy/sparse/coo.py", line 233, in toarray
    B = np.zeros(self.shape, dtype=self.dtype)
MemoryError

有没有其他方法可以做到这一点?当我在具有256GB RAM的计算机上进行处理时,为什么会出现内存错误。

感谢任何帮助!

6 个答案:

答案 0 :(得分:4)

问题是toarray()。 来自sklearn的 DictVetorizer (用于对具有高基数的分类特征进行矢量化)默认情况下输出稀疏矩阵。 由于您需要通过调用 fit_transform().toarray()来进行密集表示,因此内存不足。

只需使用:

quote_data = DV.fit_transform(quote_data)

答案 1 :(得分:2)

如果您的数据具有高基数,因为它代表文字,您可以尝试使用资源友好的矢量化工具,例如HashingVectorizer

答案 2 :(得分:1)

我正在使用DictVectorizer将分类数据库条目转换为一个热向量,并不断得到此内存错误。我正在制造以下致命缺陷:d = DictVectorizer(稀疏=假)。当我在2000或更多类别的某些字段上调用d.transform()时,python会崩溃。解决方案有效是使用稀疏为True来实例化DictVectorizer,顺便提一下,这是默认行为。如果您正在对具有多个类别的项目进行热表示,则密集阵列不是最有效的结构。在这种情况下调用.toArray()是非常低效的。

矩阵乘法中的一个热矢量的目的是从某个矩阵中选择行或列。这可以通过使用向量中存在1的索引来更有效地完成。这是一种隐式的乘法形式,它需要比显式乘法所需的操作数量级少的操作。

答案 3 :(得分:1)

执行fit_transform时,不是将整个字典传递给它,而是创建一个只有唯一出现的字典。 这是一个例子:

转换字典:

[ {A:1,B:22.1,C:Red,D:AB12},
      {A:2,B:23.3,C:Blue,D:AB12},
  {A:3,B:20.2,C:Green,D:AB65},
    ]

    [ {A:1,B:22.1,C:Red,D:AB12},
      {C:Blue},
  {C:Green,D:AB65},
    ]

这节省了很多空间。

答案 4 :(得分:1)

@Serendipity使用fit_transform函数,我也遇到了内存错误。在我的情况下删除列不是一个选项。所以我删除了.toarray(),代码运行正常。

我使用带有和不带.toarray()选项的较小数据集运行两个测试,并且在两种情况下都生成了相同的矩阵。

简而言之,删除.toarray()完成了这项工作!

答案 5 :(得分:0)

除了上述答案外,您还可以尝试使用易于存储的LabelBinarizer()函数来构建自己的自定义矢量化程序。这是代码:

from sklearn.preprocessing import LabelBinarizer

def dictsToVecs(list_of_dicts):
    X = []

    for i in range(len(list_of_dicts[0].keys())):
        vals = [list(dict.values())[i] for dict in list_of_dicts]

        enc = LabelBinarizer()
        vals = enc.fit_transform(vals).tolist()
        print(vals)
        if len(X) == 0:
            X = vals
        else:
            dummy_res = [X[idx].extend(vals[idx]) for idx, element in enumerate(X)]

    return X

另外,在不同的火车测试数据集的情况下,保存在火车时刻拟合的每一项字典的二进制化器实例可能会有所帮助,以便通过加载来调用transform()方法在测试时这些。