如何使用scikit-learn在不遇到内存问题的条件下,训练一个大约75MB的csv数据模型?
我使用IPython笔记本作为编程环境,并使用pandas和sklearn包来分析kaggle的数字识别教程中的数据。
KNeighborsClassifier
用于预测。
问题:
使用read_csv函数加载大数据集时会发生“MemoryError”。为了暂时绕过这个问题,我不得不重启内核,然后read_csv函数成功加载文件,但当我再次运行同一个单元格时,同样的错误再次发生。
当read_csv
函数成功加载文件后,在对dataframe
进行更改后,我可以将特征和标签传递给KNeighborsClassifier的fit()函数。此时,类似的内存错误再次发生。
我尝试了以下方法:
以块的方式迭代CSV文件,并相应地拟合数据,但问题是每次处理一部分数据时,预测模型都会被覆盖。
你认为我可以做些什么来成功训练我的模型而不遇到内存问题?
回答:
注意:当你使用pandas加载数据时,它会创建一个DataFrame
对象,其中每一列对于所有行都具有相同的datatype,但两列可以有不同的datatype(例如,整数、日期、字符串)。
当你将一个DataFrame
实例传递给scikit-learn模型时,它首先会分配一个具有dtype np.float32或np.float64的同质2D numpy数组(取决于模型的实现)。此时,你的内存中将有数据集的两个副本。
为了避免这种情况,你可以编写/重用一个CSV解析器,直接将数据分配到scikit-learn模型期望的内部格式/dtype中。你可以尝试使用numpy.loadtxt
(查看其文档字符串以了解参数)。
另外,如果你的数据非常稀疏(有很多零值),最好使用scipy.sparse数据结构和能够处理这种输入格式的scikit-learn模型(查看文档字符串以了解)。然而,CSV格式本身并不适合稀疏数据,我不确定是否存在直接从CSV到scipy.sparse
的解析器。
编辑:作为参考,KNearestNeighborsClassifer会分配一个形状为(n_samples_predict, n_samples_train)
的临时距离数组,这在只需要(n_samples_predict, n_neighbors)
时非常浪费。这个问题可以在这里跟踪: