在推荐系统中,我们通常使用非常稀疏的矩阵,因为项目总体非常大,而单个用户通常与项目总体的一个非常小的子集进行交互。以YouTube为例——用户通常会观看数百个(可能是数千个)视频,而YouTube的语料库中有数百万个视频,这导致了>99%的稀疏性。
这意味着当我们在一个矩阵中表示用户(行)和行为(列)时,结果是一个由许多零值组成的极其稀疏的矩阵。
在真实的场景中,我们如何最好地表示这样一个稀疏的用户-项目交互矩阵?
为什么我们不能只使用Numpy数组或panda数据流呢?
要理解这一点,我们必须理解计算的两个主要约束——时间和内存。前者就是我们所知道的“程序运行所需的时间”,而后者是“程序使用了多少内存”。前者非常简单,但对于后者,确保程序不消耗所有内存非常重要,尤其是在处理大型数据集时,否则会遇到著名的“内存不足”错误。
我们PC上的每个程序和应用程序都使用一些内存(见下图)。当我们运行矩阵计算并希望将这些稀疏矩阵存储为Numpy数组或panda DataFrame时,它们也会消耗很多内存。
为了形式化这两个约束,它们通常被称为时间和空间(内存、硬盘等存储)复杂性。
空间复杂度
当处理稀疏矩阵时,将它们存储为一个完整的矩阵(从这里开始称为密集矩阵)是非常低效的。这是因为一个完整的数组为每个条目占用一块内存,所以一个n x m数组需要n x m块内存。从简单的逻辑角度来看,存储这么多零是没有意义的!
从数学的角度来看,如果我们有一个100,000 x 100,000矩阵,这将要求我们有100,000 x 100,000 x 8 = 80gb的内存来存储这个矩阵(因为每个double使用8字节)!
时间复杂度
除了空间复杂性之外,密集的矩阵也会加剧运行时。我们将用下面的一个例子来说明。
那么我们如何表示这些矩阵呢?