稀疏特征矩阵会占多少内存?用 SciPy CSR 核对存储与转稠密风险

先计算 SciPy CSR 三组底层数组的字节数,再估算稠密数组体积,以一个少非零项的大形状例子检查内存风险和安全切片。

处理词袋或 one-hot 特征时,列数很大不一定意味着当前矩阵已占用同样大的内存。CSR 只保存非零项、对应列号和每行的起点;转成普通二维数组后,每个位置都要分配存储。先核对两种表示的体积,再决定是否转换,可以避免一次 toarray() 把进程的内存耗尽。

本教程适合已经拿到 SciPy 稀疏特征矩阵、想估算转稠密风险的读者。示例在 Python 3.11、NumPy 2.4.6、SciPy 1.17.1 上运行。使用人工构造的大形状、少非零项矩阵,未加载真实业务数据,也没有实际分配估算中的 40 GB。

稀疏特征矩阵会占多少内存?用 SciPy CSR 核对存储与转稠密风险

先安装,再运行估算脚本

在可写工作目录创建并激活虚拟环境,安装指定版本,保存下面代码为 check_sparse.py,然后运行 python check_sparse.py。macOS/Linux 的激活命令为 source .venv/bin/activate。

python -m venv .venv
.venv\Scripts\activate
python -m pip install numpy==2.4.6 scipy==1.17.1

SciPy CSR 文档给出了 data、indices、indptr 的含义。三组数组的 nbytes 相加是底层存储估算,不包含 Python 对象、分配器及其它临时副本。

import numpy as np
from scipy.sparse import csr_matrix

X = csr_matrix((np.array([1, 2, 3, 4, 5], dtype=np.float32),
                ([0, 1, 2, 3, 4], [10, 200, 3000, 40000, 99999])),
               shape=(100_000, 100_000))
X.sum_duplicates()
X.eliminate_zeros()
stored = X.data.nbytes + X.indices.nbytes + X.indptr.nbytes
dense = int(X.shape[0]) * int(X.shape[1]) * X.dtype.itemsize
print('shape:', X.shape, 'nnz:', X.nnz, 'dtype:', X.dtype)
print('CSR arrays bytes:', stored)
print('dense estimated bytes:', dense)
limit = 512 * 1024**2
if dense > limit:
    print('skip full toarray: exceeds 512 MiB budget')
else:
    print(X.toarray())
small = X[:5, :12].toarray()
print('small slice shape:', small.shape, 'sum:', float(small.sum()))
assert X.nnz == 5 and small.shape == (5, 12) and small.sum() == 1

这几个数字分别表示什么

检查项 本地示例输出 含义
shape (100000, 100000) 十万行、十万列
nnz 5 规范化后实际存储五个非零元素
CSR arrays bytes 400044 约391 KiB,包含十万行的行指针
dense estimated bytes 40000000000 40 GB,约37.25 GiB,尚未分配

核验时应看到 skip full toarray,而不是一大块二维数组;最后的小片段形状应为 (5, 12),元素和为 1.0。这说明脚本只把一小段转成普通数组。换环境后索引的数据类型可能变化,CSR 的具体字节数也可能变化,应以本机数组的 nbytes 为准。

换成真实训练特征时怎样操作

保留原矩阵,把脚本创建 X 的部分替换为已经生成的稀疏特征。先执行类型检查,确认是支持上述属性的 CSR 表示;若原来是其它稀疏格式,可用 X = X.tocsr(),但转换本身也可能需要额外内存。不要在已有内存压力时先转换再调查。

公式是“行数 × 列数 × 每个元素字节数”。将维度先转为 Python int,可减少定长整数相乘溢出的风险。512 MiB 是本例的保守演示阈值,不是所有电脑都合适的安全线;即便低于阈值,模型训练及转换临时副本仍会使用更多内存。优先选择能直接接受稀疏输入的算法,并检查具体求解器的要求。

toarray 文档说明结果是稠密 ndarray。只为了查看数据时可切小片段,不能为了打印几个值就转换整张特征表。

常见疑问:为什么全零矩阵仍有占用

CSR 仍需要保存每行的起点,indptr 长度与行数相关。nnz 还可能包含显式存进去的零;本例先合并重复坐标,再删除显式零,以免把存储项数误读成数学意义上的非零数。这里估算的是输入矩阵,不包括训练模型参数或 GPU 显存。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30821.html

赞 (0)
AI小管家的头像AI小管家
多个分类模型怎么一起投票?用 VotingClassifier 核对硬投票与软投票
上一篇 10小时前
AI 检测图片怎么缩放?用 OpenCV 保持比例并还原框坐标
下一篇 10小时前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部