对于一个矩阵而言,若数值为零的元素远远多于非零元素的个数,且非零元素分布没有规律时,这样的矩阵被称作稀疏矩阵;与之相反,若非零元素数目占据绝大多数时,这样的矩阵被称作稠密矩阵。

稀疏矩阵在工程应用中经常被使用,尤其是在通信编码和机器学习中。若编码矩阵或特征表达矩阵是稀疏矩阵时,其计算速度会大大提升。对于机器学习而言,稀疏矩阵应用非常广,比如在数据特征表示、自然语言处理等领域。

用稀疏表示和工作在计算上代价很高,需要专门处理稀疏矩阵的表示和操作等,但是这些操作可以大幅提升性能。

在本教程中,读者可以学习稀疏矩阵的基本概念、存在的问题以及如何在Python中使用它。

稀疏矩阵

稀疏矩阵是由大部分为零的矩阵组成的矩阵,这是和稠密矩阵有所区别的主要特点。

如果它的许多元素为,则矩阵是稀疏的。对稀疏性感兴趣的原因是利用好这一特性能够大幅降低计算量,并且在实践中发现很多大型矩阵问题也是稀疏的。

矩阵的稀疏性可以用一个分数来量化,即矩阵中零元素的个数除以矩阵中元素的总数。

sparsity = count zero elements / total elements

下面是一个小的3x6的稀疏矩阵例子

     1, 0, 0, 1, 0, 0
A = (0, 0, 2, 0, 0, 1)0, 0, 0, 2, 0, 0

上面这个矩阵中总共有18个元素,其中有13个元素为0,则该矩阵的稀疏分数为0.722或72%左右。

稀疏存在的问题

稀疏矩阵会导致空间和时间复杂度方面的问题。

空间复杂度

大型矩阵需要大量的内存来存储,我们希望使用的一些大型矩阵是稀疏的。

实际上,大多数大型矩阵都是稀疏的,几乎所有的条目都是

一个例子是大型矩阵太大以至于不能存储在内存中,这个矩阵就是链接矩阵,它表示的从一个网站到另一个网站的链接。一个较小的稀疏矩阵例子可能是一本书中针对所有已知单词或术语出现矩阵。这两种情况所包含的矩阵都是稀疏的,其零值比非零数据值多,将这些矩阵表示为稠密矩阵的问题是需要内存,并且在矩阵中必须分配32位或64位零值。这显然是对内存资源的一种浪费,因为这些零值不包含任何信息。

时间复杂度

假设一个非常大型的稀疏矩阵可以存储在内存中,之后将在这个矩阵上执行一些操作。简单来说,若矩阵主要包含的是零值,即没有多少数据,那么对这个矩阵执行操作可能需要花费很长的时间,其中执行的大部分计算将涉及零值相加或相乘。

在这样的问题上使用线性代数的方法是浪费的,因为大多数O(N^3)的算术运算致力于求解方程组或矩阵求逆涉及的零操作数。

矩阵运算的时间复杂度随着矩阵大小增加而增加。对于机器学习而言,即使是最简单的方法也可能需要对每一行、每一列甚至整个矩阵进行许多操作运算,这会导致执行时间会变得很长,上述问题会变得更加复杂。

机器学习中的稀疏矩阵

稀疏矩阵在机器学习应用中经常出现。本节将讨论一些常见的示例,以便读者对其有个直观的了解,并深入的理解稀疏性问题。

数据

稀疏矩阵一般出现在一些特定类型的数据中,比如常见的记录活动发生的次数等。

这里有三个例子:

1.用户是否在电影目录中观看过电影;

2.用户是否购买产品目录中的产品;

3.歌曲目录中收听歌曲的次数;

数据准备

稀疏矩阵出现在用于编写数据的编码方案中。三个常见的例子如下:

1.独热编码,用于将分类数据表示为稀疏二元向量;

2.计数编码,用于表示文档词汇表中单词的频率;

3.TF-IDF编码,用于表示词汇表中词频逆文档频数;

研究领域

机器学习中一些研究领域必须开发专门的方法来直接解决稀疏性问题,这是因为输入数据几乎总是稀疏的。以下是三个例子:

1.处理文本文档的自然语言处理;

2.用于处理目录中的产品使用的推荐系统;

3.处理包含大量黑色像素图像时的计算机视觉问题;

若语言模型中有100000个单词,那么特征向量的长度为100000,但对于简短的电子邮件消息而言,几乎所有的特征计数为

使用稀疏矩阵

表示和使用稀疏矩阵的解决方案是使用替代的数据结构来表示稀疏矩阵。零元素值可以被忽略,只有稀疏矩阵中的非零元素值需要被存储或使用。有多种数据结构能有效地构造稀疏矩阵,下面列出三个常见示例:

1.字典:一个字典使用行和列索引映射出一个值;

2.列表的列表:矩阵的每一行都以列表形式存储,每个子列表包含列的索引和其值;

3.坐标列表:元组列表存储在包含行索引、列索引和其值的每个元组中;

还有一些更适合执行有效操作的数据结构,比如以下两个常见示例:

1.CSR(Compressed Sparse Row):稀疏矩阵用非零值的三个一维数组、行的范围和列索引表示;

2.CSC(Compressed Sparse Column):与CSR方法相同,只是列索引在行索引之前被压缩并首先被读取;

Python中的稀疏矩阵

SciPy使用多个数据结构为创建稀疏矩阵提供了工具,以及将稠密矩阵转化为稀疏矩阵的工具。许多在Numpy数组上运行的线性代数Numpy和SciPy函数可以在SciPy稀疏数组上操作。此外,使用Numpy数据结构的机器学习库也可以在Scipy稀疏数组上操作,例如,用于机器学习的scikit-learning和用于深度学习的Keras。

通过调用scr_matrix()函数,可以使用CSR表示将存储在Numpy数组中的稠密矩阵转换为稀疏矩阵。在下面的例子中,定义一个3x6稀疏矩阵作为一个密集数组,并将其转换为CSR稀疏表示,然后通过调用todense()函数将其转换回密集数组。

# dense to sparse
from numpy import array
from scipy.sparse import csr_matrix
# create dense matrix
A = array([[1, 0, 0, 1, 0, 0], [0, 0, 2, 0, 0, 1], [0, 0, 0, 2, 0, 0]])
print(A)
# convert to sparse matrix (CSR method)
S = csr_matrix(A)
print(S)
# reconstruct dense matrix
B = S.todense()
print(B)

运行该示例后,首先打印出定义的密集数组,然后打印出CSR表示,最后打印出重建的密集矩阵。

[[1 0 0 1 0 0][0 0 2 0 0 1][0 0 0 2 0 0]](0, 0)   1(0, 3) 1(1, 2) 2(1, 5) 1(2, 3) 2[[1 0 0 1 0 0][0 0 2 0 0 1][0 0 0 2 0 0]]

Numpy不提供函数来计算矩阵的稀疏性。不过,可以通过首先找到矩阵的密度并从中减去相关值来轻松地计算出来。Numpy数组中的非零元素的数量可以由count_nonzero()函数给出,数组中的元素总个数可以由数组的size属性给出。因此,可以将数组稀疏度计算为:

sparsity = 1.0 - count_nonzero(A) / A.size

下面的示例演示如何计算数组的稀疏度:

# calculate sparsity
from numpy import array
from numpy import count_nonzero
# create dense matrix
A = array([[1, 0, 0, 1, 0, 0], [0, 0, 2, 0, 0, 1], [0, 0, 0, 2, 0, 0]])
print(A)
# calculate sparsity
sparsity = 1.0 - count_nonzero(A) / A.size
print(sparsity)

运行示例后,首先打印定义的稀疏矩阵,然后是矩阵的稀疏度。

[[1 0 0 1 0 0][0 0 2 0 0 1][0 0 0 2 0 0]]0.7222222222222222

相关资源

如果您希望深入的了解稀疏矩阵,本节提供了有关该主题的一些资源:

书籍

线性代数简介,第五版,2016.

科学计算的艺术,第三版,2007.

人工智能:现代方法,第三版,2009.

直接稀疏矩阵的方法,第二版,2017.

API

Sparse matrices(scipy.sparse)API

Scipy.sparse.csr_matrix()API

Numpy.count_nonzero()API

Numpy.ndarray.size API

文章

稀疏矩阵(维基百科)

数十款阿里云产品限时折扣中,赶紧点击领劵开始云上实践吧!

作者信息

Jason Brownlee,机器学习专家,专注于机器学习的推广教育。

Linkedin: http://www.linkedin.com/in/jasonbrownlee/

本文由阿里云云栖社区组织翻译,文章原标题《A Gentle Introduction to Sparse Matrices for Machine Learning》,作者:Jason Brownlee,译者:海棠。

文章为简译,更为详细的内容,请查看原文

机器学习稀疏矩阵简介(附Python代码)相关推荐

  1. 10种机器学习算法(附Python代码)

    sklearn python API LinearRegression from sklearn.linear_model import LinearRegression # 线性回归 # modul ...

  2. python重点知识归纳_一文了解机器学习知识点及其算法(附python代码)

    一文了解机器学习知识点及其算法(附python代码) 来源:数据城堡 时间:2016-09-09 14:05:50 作者: 机器学习发展到现在,已经形成较为完善的知识体系,同时大量的数据科学家的研究成 ...

  3. 机器学习系列(12)_XGBoost参数调优完全指南(附Python代码)

    机器学习系列(12)_XGBoost参数调优完全指南(附Python代码) 原文链接:http://blog.csdn.net/han_xiaoyang/article/details/5266539 ...

  4. 教程 | 理解和实现自然语言处理终极指南(附Python代码)

     教程 | 理解和实现自然语言处理终极指南(附Python代码) 时间 2017-02-16 14:41:39 机器之心 原文  http://www.jiqizhixin.com/article ...

  5. XGBoost参数调优完全指南(附Python代码)

    XGBoost参数调优完全指南(附Python代码) 译注:文内提供的代码和运行结果有一定差异,可以从这里下载完整代码对照参考.另外,我自己跟着教程做的时候,发现我的库无法解析字符串类型的特征,所以只 ...

  6. python随机森林变量重要性_推荐 :一文读懂随机森林的解释和实现(附python代码)...

    原标题:推荐 :一文读懂随机森林的解释和实现(附python代码) 作者:WilliamKoehrsen:翻译:和中华:校对:李润嘉 本文约6000字,建议阅读15分钟. 本文从单棵决策树讲起,然后逐 ...

  7. 基于ANFIS的股票价格预测附Python代码

    基于ANFIS的股票价格预测附Python代码 在金融领域,股票价格预测一直是一个重要的问题.随着机器学习技术的发展,人们开始尝试使用神经网络等方法进行股票价格的预测. ANFIS(自适应网络基石推理 ...

  8. 基于TextRank算法的文本摘要(附Python代码)

    基于TextRank算法的文本摘要(附Python代码): https://www.jiqizhixin.com/articles/2018-12-28-18

  9. python 合并工作簿_Excel:快速合并多张表格或多个文件(工作簿)的数据(附Python代码)...

    Excel:快速合并多张表格或多个文件(工作簿)的数据(附Python代码) 现实工作中经常遇到将零散的原始数据合并统计的工作要求,如月度统计或年度统计等.原始数据的收集大多是按时间(如日期或小时)进 ...

最新文章

  1. 3D视觉工坊——一个有趣有料的星球
  2. iOS架构-c++工程在Mac下编译成.a库并调用(12)
  3. NanoPi NEO Air使用十三:使用自带的fbtft驱动点亮SPI接口TFT屏幕,ST7789V,模块加载的方式
  4. 3行代码给你的python提速4倍!
  5. linux find命令详解--转
  6. java四则运算器算法_java写的四则运算器
  7. TreeView,TreeNode,TreeNodeCollection 的使用
  8. maven添加本地包命令mvn install:install-file
  9. linux使用rename批量修改文件扩展名
  10. 美妆海报不会做? PSD分层模板带你轻松掌握!
  11. C#控制 计算机中“服务”的启动与停止 转
  12. 2018圆通科技面试题目
  13. 【HighCharts系列教程】七、导出属性——exporting
  14. 小黄鸡.Net版(Simsimi.Net)
  15. 不忘初心,持之以恒,笔耕不辍,利人利己
  16. 公司要抽奖活动?50行Python代码制作了一个转盘抽奖小程序
  17. 《大话计算机》动图一则展示
  18. ofo小黄车仍在自动续费!如何关闭微信自动扣费?
  19. 记账想要简单又安全,使用电脑记账是最佳的选择
  20. Java等额本息年化利率,转等本等息月利率

热门文章

  1. 金融帝国——美国金融霸权的来源和基础
  2. (血泪篇)MySQL 5.7首登及修改密码--2020.8.18
  3. 《暗恋是一种美丽的情愫》
  4. 从《后台》找到编辑的落脚点
  5. 985毕业,土木工程工作两年后转行Python,摸爬滚打三年目前年薪40K
  6. 谁是“少数幸福的人”?
  7. VMI-TOOS/VBS编程
  8. assemblyScript:一款前端的高效运算wasm工具
  9. 径向基神经网络及MATLAB实现
  10. windows10配置mysql数据源_将数据库添加为数据源