机器学习中的稀疏矩阵简介

沉舟侧畔千帆进,病树前头万木春。这篇文章主要讲述机器学习中的稀疏矩阵简介相关的知识,希望能为你提供帮助。
      主要包含零值的矩阵称为稀疏矩阵,而大多数值不为零的矩阵则称为密集矩阵。      大型稀疏矩阵在一般情况下很常见,尤其是在应用机器学习中,例如在包含计数的数据、将类别映射到计数的数据编码中,甚至在机器学习的整个子领域(如自然语言处理)中。
      表示和使用稀疏矩阵在计算上是昂贵的,就好像它们是密集的一样,并且可以通过使用专门处理矩阵稀疏性的表示和操作来实现性能的很大提高。
在本教程中,您将了解稀疏矩阵、它们存在的问题以及如何直接在 python 中使用它们。
      完成本教程后,您将了解:
【机器学习中的稀疏矩阵简介】 1)稀疏矩阵主要包含零值并且与密集矩阵不同。
2)您可能会在数据、数据准备和机器学习的子领域中遇到稀疏矩阵的无数领域。
3)有许多有效的方法来存储和处理稀疏矩阵,SciPy 提供了可以直接使用的实现。
      教程总览
      本教程分为以下5个部分:
1)稀疏矩阵
2)稀疏性问题
3)机器学习中的稀疏矩阵
4)使用稀疏矩阵
5)Python 中的稀疏矩阵



1 稀疏矩阵      稀疏矩阵是主要由零值组成的矩阵。稀疏矩阵与主要为非零值的矩阵不同,后者被称为密集矩阵。
“如果矩阵的许多系数为零,则该矩阵是稀疏矩阵。 之所以对稀疏性感兴趣,是因为它的利用可以节省大量的计算量,而且在实践中出现的许多大型矩阵问题都是稀疏的。”——Page 1, ??Direct Methods for Sparse Matrices???, Second Edition, 2017
      矩阵的稀疏性可以用分数来量化,分数是矩阵中零值的数量除以矩阵中元素的总数。
sparsity = count zero elements / total elements
下面是一个小的 3 x 6 稀疏矩阵的例子。
        1,0,0,1,0,0
A = (0,0,2,0,0,1)
        0,0,0,2,0,0
      该示例具有矩阵中 18 个元素的 13 个零值,使该矩阵的稀疏性得分为 0.722 或约 72%。
2 稀疏性问题      稀疏矩阵会导致空间和时间复杂度方面的问题。
1)空间复杂度
      非常大的矩阵需要大量内存,而我们希望处理的一些非常大的矩阵是稀疏的。
      “在实践中,大多数大型矩阵都是稀疏的——几乎所有的条目都是零。”——Page 465, ??Introduction to Linear Algebra???, Fifth Edition, 2016
一个太大而无法存储在内存中的超大矩阵的一个例子是一个链接矩阵,它显示了从一个网站到另一个网站的链接。
      较小稀疏矩阵的一个示例可能是一本书中的单词与英语中所有已知单词的单词或术语出现矩阵。
      在这两种情况下,包含的矩阵都是稀疏的,零值比数据值多得多。 将这些稀疏矩阵表示为密集矩阵的问题在于需要内存,并且必须为矩阵中的每个 32 位甚至 64 位零值分配内存。
      这显然是一种内存资源的浪费,因为那些零值不包含任何信息。
2)实践复杂度
      假设一个非常大的稀疏矩阵可以放入内存,我们将要对这个矩阵执行操作。
      简单地说,如果矩阵主要包含零值,即没有数据,那么在这个矩阵上执行操作可能需要很长时间,其中执行的大部分计算将涉及将零值相加或相乘。
      “在此类问题上使用线性代数的一般方法是浪费的,因为大多数 算术运算专门用于求解方程组或矩阵求逆涉及零操作数。”
      这是随着矩阵的大小而增加的矩阵运算的时间复杂度增加的问题。
当我们考虑到即使是微不足道的机器学习方法也可能需要对每一行、每一列甚至整个矩阵进行多次操作时,这个问题就变得复杂了,从而导致执行时间大大延长。
3 机器学习中的稀疏矩阵
      稀疏矩阵在应用机器学习中出现了很多。在本节中,我们将查看一些常见示例,以激励您了解稀疏性问题。
1)数据
      稀疏矩阵出现在某些特定类型的数据中,最显着的是记录活动发生或计数的观察。以下是三个常见的例子:


  • 用户是否看过电影目录中的电影。
  • 用户是否购买了产品目录中的产品。
  • 歌曲目录中歌曲的听数计数。

2)数据准备
      稀疏矩阵出现在用于准备数据的编码方案中。以下是三个常见的例子:

  • One-hot 编码,用于将分类数据表示为稀疏二进制向量。
  • 计数编码,用于表示一个文档的词汇表中单词出现的频率。
  • TF-IDF 编码,用于表示词汇表中归一化的词频分数。

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

  • 用于处理文本文档的自然语言处理。
  • 用于在目录中处理产品使用的推荐系统。
  • 处理包含大量黑色像素的图像时的计算机视觉。

      “如果语言模型中有 100,000 个单词,则特征向量的长度为 100,000,但对于一封简短的电子邮件消息,几乎所有特征的计数为零。”
4 使用稀疏矩阵
      表示和使用稀疏矩阵的解决方案是使用替代数据结构来表示稀疏数据。
零值可以被忽略,只有稀疏矩阵中的数据或非零值需要被存储或操作。
      有多种数据结构可用于高效构建稀疏矩阵; 下面列出了三个常见的例子。

  • 键的字典。 字典用于将行和列索引映射到值的地方。
  • 列表的列表。 矩阵的每一行都存储为一个列表,每个子列表包含列索引和值。
  • 坐标列表。 元组列表与包含行索引、列索引和值的每个元组一起存储。
还有更适合执行高效操作的数据结构; 下面列出了两个常用的例子。
  • 压缩稀疏行。 稀疏矩阵使用三个一维数组表示非零值、行的范围和列索引。
  • 压缩稀疏列。 与压缩稀疏行方法相同,除了列索引在行索引之前被压缩和读取。
      压缩稀疏行,也简称为 CSR,鉴于其支持的高效访问和矩阵乘法,通常用于表示机器学习中的稀疏矩阵。
5 Python 中的稀疏矩阵
      SciPy 提供了使用多种数据结构创建稀疏矩阵的工具,以及将稠密矩阵转换为稀疏矩阵的工具。
      许多在 NumPy 数组上运行的线性代数 NumPy 和 SciPy 函数可以透明地在 SciPy 稀疏数组上运行。 此外,使用 NumPy 数据结构的机器学习库也可以在 SciPy 稀疏数组上透明地运行,例如用于一般机器学习的 scikit-learn 和用于深度学习的 Keras。
      通过调用 csr_matrix() 函数,可以使用 CSR 表示将存储在 NumPy 数组中的密集矩阵转换为稀疏矩阵。
      在下面的示例中,我们将一个 3 x 6 的稀疏矩阵定义为稠密数组,将其转换为 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 表示,然后是重建的密集矩阵。

NumPy 没有提供计算矩阵稀疏度的函数。尽管如此,我们可以通过首先找到矩阵的密度并将其从 1 中减去来轻松计算它。 NumPy 数组中非零元素的数量可以由 count_nonzero() 函数给出,数组中元素的总数可以由数组的 size 属性给出。 因此,阵列稀疏度可以计算为:
sparsity = 1.0 - count_nonzero(A) / A.sizesparsity = 1.0


下面的示例演示了如何计算数组的稀疏性。



# 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)

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




    推荐阅读