使用Scikit Learn的DictVectorizer时出现MemoryError错误
我正在尝试在我的数据上实现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内存的机器上处理时会出现内存错误呢?
任何帮助都非常感谢!
7 个回答
我在使用DictVectorizer把分类数据库里的数据转换成独热编码(one hot vectors)时,老是遇到内存错误。我犯了一个致命的错误:d = DictVectorizer(sparse=False)。当我对一些有2000个以上类别的字段调用d.transform()时,Python就崩溃了。解决这个问题的办法是把DictVectorizer的sparse参数设置为True,实际上这也是默认的设置。如果你在处理有很多类别的项目的独热编码时,使用稠密数组(dense arrays)并不是最有效的选择。在这种情况下调用.toArray()会非常低效。
独热编码在矩阵乘法中的作用是从某个矩阵中选择一行或一列。其实可以更高效地通过查找向量中1出现的索引来完成。这是一种隐式的乘法方式,所需的操作次数比显式乘法少得多。
如果你的数据包含很多不同的文本内容,导致数据种类非常多(我们称之为高基数),你可以试试使用一种更节省资源的工具,叫做 HashingVectorizer。
问题出在 toarray()
这个方法上。DictVectorizer 是 sklearn 里的一个工具,主要用来处理类别特征(也就是分类数据),特别是那些种类很多的特征。默认情况下,它输出的是稀疏矩阵,也就是只存储非零值的矩阵,这样可以节省内存。
你之所以内存不够,是因为你调用了 fit_transform().toarray()
,这会要求用更占内存的方式来表示数据。
你只需要使用:
quote_data = DV.fit_transform(quote_data)
我找到了问题所在。
当我删除了一个包含非常多不同值的列后,DictVectorizer就正常工作了。那个列有好几百万个独特的值,所以DictVectorizer才出现了内存错误。
在进行 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},
]
这样做可以节省很多存储空间。