在机器学习中,面对海量样本数据时,我们常常面临内存不足的挑战。一般性的解决办法如降低样本数量、调整算法或者升级硬件等方案虽简单直接,却不一定总能实现目标。机器学习算法常常要求数据集如常见的DataFrame数据保存在内存中,因为内存读取速度远超磁盘读取,因此单纯地升级硬件并不总是最佳方案。那么,我们该如何有效地保存信息又节约内存呢?科学家们提出了一种有效的方案——“稀疏矩阵”。
在机器学习领域,Pandas的DataFrame无疑是处理数据的标配工具。但当数据规模达到数百万行或列时,DataFrame的存储方式可能成为瓶颈。比如一个名为Santander Customer Satisfaction的数据集,从CSV文件导入前后,其磁盘与内存的使用情况就可能产生显著差异,这主要是由于数据中存在大量零值或空值所导致的。
稀疏矩阵的概念深入人心。简单来说,矩阵可以分两大类:密集和稀疏。其显著差异在于稀疏矩阵包含很多零值。让我们考虑一个拥有4行4列的稀疏矩阵示例。在这个矩阵中,16个元素中有12个是零。那么我们是否可以在机器学习任务中仅存储非零值来压缩矩阵大小呢?答案是肯定的。
接下来让我们以CSR格式为例深入理解。设想将一个普通矩阵转化为CSR格式的过程,利用scipy的sparse模块可以实现这一转化。原矩阵虽然以二维数组形式存储数据,但在CSR格式中,这些数据被存储在三个一维数组中:值数组、列索引数组和行索引数组。
值数组不言而喻,它存储了原始矩阵中的所有非零元素;列索引数组则记录了值数组中元素的列索引;而行索引数组的编码方式稍显复杂些,它记录了每一行及之前行中非零值的累积计数,其长度为行数加一。这样即使面对庞大的数据集,我们也能有条不紊地管理并访问其中的非零元素。
对于如何直观地理解并应用稀疏矩阵,我们可以通过图表来一窥究竟。比如plt.spy()函数就可以用来绘制二维数组的稀疏模式,黑点代表非零值。这使我们能够清晰地看到哪些数据点是重要的非零值。为了更好地了解数据的稀疏程度,我们可以使用NumPy计算数据的稀疏度。以Santander Customer Satisfaction数据集为例,其计算结果可能为0.906的稀疏度,意味着超过90%的数据点都是用零填充的。
使用稀疏矩阵的好处显而易见:节省大量内存并减少模型训练时间。值得欣喜的是,在sklearn API中几乎所有算法都支持csr_matrix作为输入格式,如RandomForestClassifier等,这使得我们能够更加方便地将稀疏矩阵应用于模型训练中。
下面我们开始利用实际的数据集进行实验吧!我们的数据集在应用稀疏矩阵后,其内存占用会大大减少。通过比较模型训练时间,我们会发现LogisticRegression和GradientBoostingClassifier等算法的训练效率有明显提升。虽然LinearSVC算法在初看上去效率提升不明显,但它的运行机制与其他算法有所差异(比如可能涉及到高维度的投影),其真实性能可能在实际使用中有更显著的提升。