使用Scikit Learn的DictVectorizer时,toarray中出现内存错误



我正试图在我的数据上实现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的机器上处理时出现内存错误?

感谢任何帮助!

我把问题解决了。

当我删除一个具有非常高基数的列时,DictVectorizer工作得很好。那一列有几百万个不同的唯一值,因此dictortorizer给出了一个内存错误

问题是toarray()。sklearn中的DictVetorizer(专为向量化具有高基数的分类特征而设计)默认输出稀疏矩阵。由于调用 fit_transform().toarray()需要密集表示,内存即将耗尽。

只使用:

quote_data = DV.fit_transform(quote_data)

如果您的数据具有较高的基数,因为它表示文本,您可以尝试使用资源友好的矢量器,如HashingVectorizer

在执行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},
    ]

我正在使用DictVectorizer将分类数据库条目转换为一个热向量,并且不断得到此内存错误。我犯了以下致命的错误:d = DictVectorizer(sparse=False)。当我在一些包含2000个或更多类别的字段上调用d.transform()时,python会崩溃。解决方案是实例化sparse为True的DictVectorizer,顺便说一下,这是默认行为。如果要对具有多个类别的项进行一次热表示,那么密集数组并不是最有效的结构。在这种情况下调用. toarray()效率非常低。

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

@Serendipity使用fit_transform函数,我也遇到了内存错误。在我的情况下,删除一列是不可能的。所以我删除了。toarray(),代码工作得很好。

我使用一个较小的数据集运行了两个测试,有和没有。toarray()选项,在这两种情况下,它都产生了相同的矩阵。

简而言之,删除。toarray()完成了任务!

除了上面的答案,您还可以尝试使用存储友好的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()方法。

最新更新