Scikit 和 Pandas:拟合大数据
Posted
技术标签:
【中文标题】Scikit 和 Pandas:拟合大数据【英文标题】:Scikit and Pandas: Fitting Large Data 【发布时间】:2012-07-27 07:30:13 【问题描述】:如何使用 scikit-learn 在大型 csv 数据(约 75MB)上训练模型而不会遇到内存问题?
我使用 IPython notebook 作为编程环境,使用 pandas+sklearn 包来分析来自 kaggle 数字识别器教程的数据。
数据在webpage,链接到my code,这里是error message:
KNeighborsClassifier
用于预测。
问题:
使用 read_csv 加载大型数据集时发生“MemoryError” 功能。要暂时绕过这个问题,我必须重新启动 内核,然后 read_csv 函数成功加载文件,但是 当我再次运行同一个单元格时,也会出现同样的错误。
read_csv
函数成功加载文件后,在对dataframe
进行更改后,我可以将特征和标签传递给 KNeighborsClassifier 的 fit() 函数。此时出现类似的内存错误。
我尝试了以下方法:
逐块迭代CSV文件,并相应地拟合数据,但问题是每次数据块都会覆盖预测模型。
您认为我可以做些什么来成功训练我的模型而不会遇到内存问题?
【问题讨论】:
您的代码 + 数据在我的笔记本电脑上运行良好。它需要大约 1.2 GB 的内存。你的系统有多少内存? 使用 loadtxt 让它工作。即使没有发生内存错误,在算法上仅运行约 75mb 的数据也会占用超过 1GB 的内存......我不确定我的代码是否做错了什么。 (pastie.org/4354911) (ipython 笔记本)。如果只是算法需要这么长时间,你如何在算法上加载千兆字节的数据而不需要这么长时间来创建模型? 您可以使用可以增量训练的算法,从而一次只处理(小)部分数据。如果 scikit-learn 中的估算器实现了partial_fit
方法,它就能够做到这一点。
【参考方案1】:
注意:当您使用 pandas 加载数据时,它会创建一个 DataFrame
对象,其中每列对于所有行都有同质数据类型,但 2 列可以有不同的数据类型(例如整数、日期、字符串)。
当您将 DataFrame
实例传递给 scikit-learn 模型时,它将首先分配一个 dtype 为 np.float32 或 np.float64 的同质 2D numpy 数组(取决于模型的实现)。此时,您将在内存中拥有 2 个数据集副本。
为避免这种情况,您可以编写/重用一个 CSV 解析器,该解析器直接以 scikit-learn 模型所期望的内部格式/dtype 分配数据。例如,您可以尝试numpy.loadtxt
(查看参数的文档字符串)。
此外,如果您的数据非常稀疏(许多零值),最好使用 scipy.sparse 数据结构和可以处理这种输入格式的 scikit-learn 模型(检查文档字符串以了解)。但是 CSV 格式本身不太适合稀疏数据,我不确定是否存在直接的 CSV-to-scipy.sparse
解析器。
编辑: 供参考 KNearestNeighborsClassifer 分配形状为(n_samples_predict, n_samples_train)
的临时距离数组,这在只需要(n_samples_predict, n_neighbors)
时非常浪费。可以在此处跟踪此问题:
https://github.com/scikit-learn/scikit-learn/issues/325
【讨论】:
scikit-learn 模型也不会导致任何内存异常。现在唯一的问题是......由于数据如此之大,该算法需要很长时间才能创建模型。我希望有一种方法可以使这更快... 你应该尝试在蛮力模式下使用KNeighborsClassifier
(而不是balltree),但是预测时间可能太慢了。或者,您可以使用简单的模型,例如 sklearn.linear_model.Perceptron
、sklearn.naive_bayes.MultinomialNB
或 sklearn.neighbors.NearestCentroidClassifier
。最后,您还可以尝试在数据的一小部分子样本上训练模型,以快速了解预测准确性,然后将数据集的大小加倍并进行迭代。以上是关于Scikit 和 Pandas:拟合大数据的主要内容,如果未能解决你的问题,请参考以下文章