我正试图在我的数据上实现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()
方法。