用于机器学习的稀疏矩阵2025年6月19日 | 阅读 12 分钟 稀疏矩阵在机器学习中发挥着不可或缺的作用,尤其是在处理具有许多零值的高维数据时。这可以减少计算量和内存使用量,最小化内存占用,并提高处理大型数据集的速度。本文旨在全面介绍稀疏矩阵:它们是什么,在机器学习中的用途,以及对可扩展高效建模的贡献。 稀疏矩阵是一种矩阵,其中大部分元素是零;而稠密矩阵则包含大部分非零元素。稀疏矩阵的实际应用通常出现在自然语言处理(NLP)、计算机视觉和推荐系统中,这些领域包含大量数据,其中包含大量零。稀疏矩阵在内存方面更轻量,因为它只存储非零元素的位置和值,从而优化了内存和功耗。 稀疏矩阵在机器学习中至关重要,因为它们具有内存和计算效率,尤其是在处理具有许多零的大型数据集时。通过仅存储非零值,它们可以显著减少内存使用并加快计算速度,因为算法可以跳过零。这使得矩阵乘法等运算更快。稀疏矩阵还优化了存储,能够更好地管理NLP和大数据等领域中常见的海量数据集。 处理稀疏矩阵使用 Python 的 scipy.sparse 模块有多种处理稀疏矩阵的方法。以下是一些广泛使用的稀疏矩阵格式:
稀疏矩阵在机器学习中的应用稀疏矩阵在机器学习领域的不同领域得到了广泛应用,包括但不限于以下方面:
机器学习中稀疏矩阵的挑战在使用稀疏矩阵时,需要考虑各种挑战和注意事项。
现在,我们将通过稀疏矩阵来演示内存使用量的减少。 稀疏矩阵的内存使用量减少该数据集对于可用的 16 GB 内存来说太大了。具体来说,训练输入由 105,942 列和 228,942 行组成,总计 97 GB。另一方面,训练目标占 105,942 列和 23,418 行,约为 10 GB。测试输入则占 55,935 列和 228,942 行,总计 13 GB。由于数据量巨大,无法一次性全部加载到内存中。然而,数据本身包含大量零,因此具有高度稀疏性。 我们无法加载整个数据集。因此,为了研究数据集的稀疏性,我们只取前 5000 行,以便在内存限制内进行分析。 输出 ![]() 现在,我们将计算每列中的非零值数量。 输出 ![]() 可以通过计算非零值占总值的比例来确定 DataFrame 的整体稀疏性。 输出 0.021427460230101947 由于非零值的数量仅占加载数据集总量的 2%,因此我们可以轻松地说该数据集非常稀疏。因此,数据集的其余部分也应如此;如果我们使用不同的数据结构,就可以消除这种内存浪费。 输出 63 内存优化Multiome 中的数据本质上是稀疏的,而稀疏矩阵是处理内存使用效率最高的方式,可以让我们以更少的内存开销加载数据。更具体地说,CSR 矩阵通过三个一维数组在内存使用方面是最佳的,同时还具有与矩阵稀疏性相关的某些特殊结构。数据数组仅包含非零元素,并以最紧凑的形式存储,直接对应于数据的实际值。索引数组的形状与数据数组相同;它包含每个非零值的列索引。然后,ptr_ind 数组通过标记数据数组和索引数组中每个行的边界,方便地访问行。从给定的数据数组中获取行 `i` 的所有条目就像在数据数组中切片索引 `ptr_ind[i]` 到 `ptr_ind[i+1]` 之间一样。索引数组也是如此。由于这是一个内存密集型数据集 Train-Multi-Inputs,我们可以通过分块数据按顺序构建这三个数组,从而在内存限制内管理大型数据集。 为了进一步优化性能,我们还在 Cython 代码中计算了 ptr_ind 数组,这可以将处理时间减少几个数量级,因为它使得行索引的压缩最优化,从而有效将时间缩短一半。 输出 ![]() 我们可以向数组添加最后一个元素,它表示索引或数据数组的长度,因为 ptr_ind 数组的形状是 (行数),而不是 (行数 + 1)。 输出 ![]() 其他 Multiome 文件(如 target_trains 和 test_inputs)也可以以更少的内存使用量保存。许多最先进的模型都可以使用稀疏矩阵作为训练数据,这加速了计算,并避免了繁琐且缓慢的迭代器。 现在,我们也可以使用稀疏矩阵对稀疏矩阵相关数据进行 EDA。 使用稀疏矩阵进行 EDA稀疏矩阵在这方面非常有用,尤其是在处理 Multiome 数据时,因为 Multiome 数据集中 98% 的单元格包含零。将数据编码为稀疏矩阵可以节省大量内存。稀疏表示可以更有效地利用内存;内存需求低于 8GB,而不是稠密格式所需的约 90GB;这使得可以将完整的训练数据加载到内存中。现在,让我们通过 AmbrosM 来实际操作,我们将介绍一种处理 Multiome 数据的更优方法,并为 Kaggle 竞争者提供稀疏与稠密数据表示的直观比较。与 AmbrosM 的笔记本相比,关键区别在于数据以稀疏 CSR 格式呈现,并且 PCA 或 TruncatedSVD 应用于整个训练集,而不是仅限于 6000 行 x 4000 列的选定子集。 保留了 16 个组件,而不是 AmbrosM 笔记本中的 4 个,并且 Ridge 回归应用于 50,000 行,而不是 6,000 行。尽管此笔记本处理的数据量更大,但仅需约 10 分钟即可完成,而 AmbrosM 的方法需要一个小时。竞赛数据已预先编码为稀疏矩阵,可直接用于 Multiome 预测,而 CITEseq 预测则来自 VuongLam 的公开笔记本,目前该笔记本仍保持最高评分。 以下函数计算 true_y 和 pred_y 之间每行的皮尔逊相关系数,然后对所有这些相关系数取平均值。 首先,我们加载 Multiome 的所有训练输入数据。这应该不到一分钟。 输出 ![]() PCA我们无法直接将 PCA 应用于稀疏矩阵,因为 PCA 首先需要“中心化”数据,这会破坏稀疏性。我们改用 TruncatedSVD,它基本上是“无中心化的 PCA”。我们可能需要对其进行一些更好的归一化,但出于简化的目的,我们将省略它。 输出 ![]() 然而,Sklearn 的 Ridge 回归不接受稀疏矩阵作为目标值,尽管它们可以作为输入。因此,目标值需要转换为稠密格式。稀疏输入数据和稠密目标数据都可以存储在内存中,但这会导致 Ridge 回归过程内存不足。因此,从现在开始,我们将使用训练数据的一个子集(50,000 行)。 输出 ![]() 输出 124 Sklearn 抱怨说数组比矩阵更好。遗憾的是,Kaggle 上可用的旧版 Scipy 版本不支持稀疏数组,只支持稀疏矩阵。因此,警告将被抑制。 输出 ![]() 输出 ![]() 下一个主题机器学习的概率和统计书籍 |
我们请求您订阅我们的新闻通讯以获取最新更新。