本文要点:
1、几个稀疏矩阵的应用场景
2、scipy得到稀疏格式矩阵后专用的方程组求解器
3、用稀疏格式求解方程组的速度对比
4、稀疏矩阵与原矩阵内存大小对比
5、python稀疏格式与array格式的互换
在矩阵中有大量零元素的矩阵叫做稀疏矩阵(Sparse Matrix),相反那些非零数值占大多数元素的矩阵即是稠密矩阵(Dense Matrix)。矩阵中零元素如果特别多的话,不但占用了本没必要用的内存,而且在涉及到矩阵运算的过程上拉低了程序效率:例如求解方程组和矩阵乘法。所以为了着眼于矩阵运算中真正起作用的那些非零元素,就有了如CCS(列优先存储),CRS(行优先存储)之类存储稀疏矩阵的方法,本质都是只关注稀疏矩阵中非零元素的值和位置。
理论可以参考下文:
稀疏格式矩阵经常在以下几个场景出现:三对角阵系数的线性方程组求解、机器学习中存在大量0数据的训练集、矩阵乘积
一、求解方程组
1.时长对比
作为示例这里创建一个计算数学专业里有限元和有限差分经常用到的三对角阵,维度为10000*10000
import numpy as np
import sys
import time
#创建一个10000*10000的三对角矩阵A和10000*1的向量b
A = np.diag([i for i in range(1,10001)])+ np.diag([i for i in range(2,10001)],1)+np.diag([i for i in range(2,10001)],-1)
b = np.ones_like(A[0])
#计算用原array矩阵来求解方程组AX=b
start =time.time()
X1 = np.linalg.solve(A,b) #求解
end=time.time()
print(end-start)
计算时间为5.853S,下面看利用稀疏矩阵
from scipy.sparse import coo_matrix
from scipy.sparse.linalg import spsolve #稀疏矩阵求解器
coo_A =coo_matrix(A) #转为稀疏矩阵
start =time.time()
X2 = spsolve(coo_A,b) #求解
end=time.time()
print(end-start)
计算时间为0.004S,运算时间大幅减少。
2.两者内存对比
print("原矩阵A的内存大小:"+str(sys.getsizeof(A)/1024**2)+" MB")
print("转为稀疏矩阵后的内存大小:"+str(sys.getsizeof(coo_a)/ 1024 ** 2)+" MB")
原矩阵A的内存大小:381.46984100341797 MB
转为稀疏矩阵后的内存大小:4.57763671875e-05 MB
3.稀疏矩阵与array的互换
coo_A =coo_matrix(A) #转为稀疏矩阵
A =coo_A.toarray() #转为array矩阵
二、机器学习训练
在机器学习中使用稀疏矩阵并不是没有缺点,虽然稀疏矩阵传入模型训练一般可以提高速度并且降低内存消耗,但在array中的切片操作基本都用不了了,所以一般在数据预处理结束、传入训练的时候采用稀疏矩阵。
拿一个以前比赛时用到的数据集,黄色部分为值为0的部分,可以看到0元素特别多,可以看作一个稀疏矩阵。
原先的数据集有130万条,压缩前后的内存大小为160MB
随便创建一个lgb分类器,训练时间对比:运行时长大概减少了15%
在其他地方验证也是一样,在0元素较多的情况下传入稀疏矩阵进行训练,大部分时候可以提高训练速度。