Scikit-Learn Logistic回归内存错误

时间:2012-06-25 18:47:47

标签: scikit-learn

我正在尝试使用sklearn 0.11的LogisticRegression对象来拟合200,000个观测值的模型,其中包含大约80,000个特征。目标是将短文本描述分为800个类中的1个。

当我尝试使用分类器时,pythonw.exe给了我:

应用程序错误“......引用内存为0x00000000的指令”。内存无法写入“。

这些功能非常稀疏,每次观察大约10次,并且是二进制的(1或0),所以通过我的信封计算,我的4 GB RAM应该能够处理内存需求,但这并不是似乎是这样的。只有当我使用较少的观察值和/或较少的特征时,模型才适合。

如果有的话,我想使用更多的观察和功能。我天真的理解是,在幕后运行的liblinear库能够支持它。关于如何在其中进行更多观察的任何想法?

我的代码如下所示:

y_vectorizer = LabelVectorizer(y) # my custom vectorizer for labels
y = y_vectorizer.fit_transform(y)

x_vectorizer = CountVectorizer(binary = True, analyzer = features)
x = x_vectorizer.fit_transform(x)

clf = LogisticRegression()
clf.fit(x, y)

我传递给分析器的features()函数只返回一个字符串列表,表明每次观察中检测到的特征。

我正在使用Python 2.7,sklearn 0.11,Windows XP和4 GB RAM。

1 个答案:

答案 0 :(得分:21)

liblinear(sklearn.linear_model.LogisticRegression的后备实现)将托管自己的数据副本,因为它是一个C ++库,其内部内存布局无法直接映射到scipy中预先分配的稀疏矩阵,例如{{ 1}}或scipy.sparse.csr_matrix

在您的情况下,我建议您将数据加载为scipy.sparse.csc_matrix并将其提供给scipy.sparse.csr_matrix(如果您需要逻辑回归模型并且能够调用sklearn.linear_model.SGDClassifier loss='log' predict_proba方法)。 SGDClassifier如果已经使用scipy.sparse.csr_matrix内存布局,则不会复制输入数据。

期望它在内存中分配800 *(80000 + 1)* 8 /(1024 ** 2)= 488MB的密集模型(除了输入数据集的大小)。

编辑:如何优化数据集的内存访问

要在数据集提取后释放内存,您可以:

x_vectorizer = CountVectorizer(binary = True, analyzer = features)
x = x_vectorizer.fit_transform(x)
from sklearn.externals import joblib
joblib.dump(x.tocsr(), 'dataset.joblib')

然后退出此python进程(强制完全释放内存)并在新进程中退出:

x_csr = joblib.load('dataset.joblib')

在linux / OSX下,您可以通过以下方式更有效地记忆地图:

x_csr = joblib.load('dataset.joblib', mmap_mode='c')