Python 中的稀疏矩陣

Aditya Raj 2023年1月30日 2022年5月18日
  1. 什麼是 Python 中的稀疏矩陣
  2. 在 Python 中如何建立稀疏矩陣
  3. 使用 Python 中的 SciPy 模組將正態矩陣轉換為稀疏矩陣
  4. Python 中的壓縮稀疏列矩陣
  5. Python 中座標格式的稀疏矩陣
  6. Python 中基於鍵的稀疏矩陣字典
  7. まとめ
Python 中的稀疏矩陣

在 Python 中實現機器學習演算法時,我們經常需要以需要較少記憶體的格式來表示輸入資料。

通常,提供給機器學習演算法的輸入資料以矩陣形式表示。本文將討論在 Python 中使用稀疏矩陣儲存資料。

為此,我們將學習 Python 中稀疏矩陣的不同表示。我們還將看到如何使用 Python 的 scipy 模組中定義的函式將簡單矩陣轉換為稀疏表示。

什麼是 Python 中的稀疏矩陣

稀疏矩陣是大多數元素為 0 的矩陣。意思是,矩陣只包含幾個位置的資料。

稀疏矩陣的一個例子如下。

[[16,0,0,0],
[0,0,0,0],
[0,0,0,5],
[0,0,0,0]]

在這裡,你可以看到矩陣中的大多數元素都是 0

稀疏矩陣廣泛用於自然語言處理和資料編碼。如果矩陣中的大多數元素都是 0,則儲存所有矩陣元素在儲存方面變得昂貴。

之所以如此,是因為我們只有幾個資料點,而大部分儲存空間都被冗餘零佔用。

在 Python 中如何建立稀疏矩陣

為了避免任何給定矩陣中冗餘零的記憶體使用,我們可以將正常矩陣轉換為稀疏矩陣。

你可以將稀疏矩陣視為包含三個元素的列表。列表的內部列表儲存給定輸入矩陣的非零元素的行號、列號和值。這表示稀疏矩陣。

例如,考慮以下輸入矩陣。

[[16,0,0,0],
[0,0,0,0],
[0,0,0,5],
[0,0,0,0]]

該矩陣僅在兩個位置具有非零元素:(0,0)(2,3)

為了將此矩陣轉換為稀疏矩陣,我們將建立一個表示稀疏矩陣的列表。該列表將包含包含非零元素的行號、列號和值的列表。

因此,我們在稀疏矩陣中有兩個內部列表:[0,0,16][2,3,5]。最終的稀疏矩陣如下。

[[0,0,16],
[2,3,5]]

這裡,

  • 內部列表的第一個元素表示輸入矩陣的非零元素的行號。
  • 內部列表的第二個元素表示輸入矩陣的非零元素的列號。
  • 最後,內部列表的第三個元素包含非零元素的實際值。

要從給定矩陣建立稀疏矩陣,我們將首先建立一個表示稀疏矩陣的列表 sparse_matrix。之後,我們將使用 for 迴圈遍歷輸入矩陣。

在遍歷時,如果我們在矩陣中找到一個非零元素,我們將建立一個包含行號、列號和元素值的三元組的列表。之後,我們將使用 append() 方法將列表新增到 sparse_matrix

執行 for 迴圈後,我們將在列表 sparse_matrix 中擁有稀疏矩陣。你可以在以下示例中觀察到這一點。

import numpy as np
input_matrix = np.array([[16, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5], [0, 0, 0, 0]])
print("The input matrix is:")
print(input_matrix)
sparse_matrix = []
rows, cols = input_matrix.shape
for i in range(rows):
    for j in range(cols):
        if input_matrix[i][j] != 0:
            triplet = [i, j, input_matrix[i][j]]
            sparse_matrix.append(triplet)
print("The sparse matrix is:")
print(sparse_matrix)

輸出:

The input matrix is:
[[16  0  0  0]
 [ 0  0  0  0]
 [ 0  0  0  5]
 [ 0  0  0  0]]
The sparse matrix is:
[[0, 0, 16], [2, 3, 5]]

你可以觀察到與輸入矩陣相比,稀疏矩陣的元素非常少。

當輸入矩陣為 1024x1024 或更大尺寸(如在現實世界的機器學習應用程式中)時,使用稀疏矩陣變得非常有用。與輸入矩陣相比,稀疏矩陣的大小變得非常小。

請記住,如果矩陣中非零元素的數量大於矩陣中總元素的三分之一,則建立和使用稀疏矩陣會比使用原始矩陣更昂貴。如果矩陣有 n 個非零元素,則稀疏矩陣包含 3*n 個元素。

使用 Python 中的 SciPy 模組將正態矩陣轉換為稀疏矩陣

我們還可以使用 scipy 模組將普通矩陣轉換為稀疏矩陣。scipy 模組提供了多種方法將普通矩陣轉換為稀疏矩陣。

讓我們一一討論所有方法。

Python 中的壓縮稀疏行矩陣

壓縮稀疏行 (CSR) 矩陣是我們可以在算術運算中使用的稀疏矩陣。

CSR 矩陣支援加法、減法、乘法、除法和冪矩陣計算。你可以使用 Python 的 scipy 模組中定義的 csr_matrix() 方法將普通矩陣轉換為壓縮的稀疏行矩陣。

如下所示,csr_matrix() 方法將一個普通矩陣作為輸入,並返回一個稀疏矩陣。

import numpy as np
from scipy import sparse
input_matrix = np.array([[16, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5], [0, 0, 0, 0]])
print("The input matrix is:")
print(input_matrix)
sparse_matrix = sparse.csr_matrix(input_matrix)
print("The sparse matrix is:")
print(sparse_matrix)

輸出:

The input matrix is:
[[16  0  0  0]
 [ 0  0  0  0]
 [ 0  0  0  5]
 [ 0  0  0  0]]
The sparse matrix is:
  (0, 0)	16
  (2, 3)	5

壓縮稀疏行矩陣有助於高效的行切片和快速的矩陣向量乘積。但是,CSR 矩陣中的列切片操作很慢。

Python 中的壓縮稀疏列矩陣

我們可以在需要列切片的程式中使用壓縮稀疏列 (CSC) 矩陣代替 CSR 矩陣。

你可以使用 scipy 模組中定義的 csc_matrix() 方法在 Python 中建立 CSC 矩陣。csc_matrix() 方法接受一個普通矩陣作為輸入引數,並在下面返回一個稀疏矩陣。

import numpy as np
from scipy import sparse
input_matrix = np.array([[16, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5], [0, 0, 0, 0]])
print("The input matrix is:")
print(input_matrix)
sparse_matrix = sparse.csc_matrix(input_matrix)
print("The sparse matrix is:")
print(sparse_matrix)

輸出:

The input matrix is:
[[16  0  0  0]
 [ 0  0  0  0]
 [ 0  0  0  5]
 [ 0  0  0  0]]
The sparse matrix is:
  (0, 0)	16
  (2, 3)	5

與壓縮稀疏行矩陣相比,壓縮稀疏列矩陣有助於更快的列切片和慢速行切片。

Python 中座標格式的稀疏矩陣

座標格式是建立稀疏矩陣的更快方法。你可以使用 scipy 模組中定義的 coo_matrix() 方法以座標格式建立稀疏矩陣。

coo_matrix() 接受一個普通矩陣作為輸入引數,並以座標格式返回一個稀疏矩陣,如下所示。

import numpy as np
from scipy import sparse
input_matrix = np.array([[16, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5], [0, 0, 0, 0]])
print("The input matrix is:")
print(input_matrix)
sparse_matrix = sparse.coo_matrix(input_matrix)
print("The sparse matrix is:")
print(sparse_matrix)

輸出:

The input matrix is:
[[16  0  0  0]
 [ 0  0  0  0]
 [ 0  0  0  5]
 [ 0  0  0  0]]
The sparse matrix is:
  (0, 0)	16
  (2, 3)	5

如果需要將法線矩陣轉換為 CSR 或 CSC 矩陣,應先將法線矩陣轉換為座標格式的稀疏矩陣。之後,你可以將稀疏矩陣轉換為所需的格式。

座標格式的稀疏矩陣主要用於將矩陣從一種格式互連到另一種格式。它不支援算術運算或切片。

Python 中基於鍵的稀疏矩陣字典

基於鍵字典 (DOK) 的稀疏矩陣提供對矩陣中元素的 O(1) 訪問。

此外,基於 DOK 的矩陣不包含重複值。你可以使用 scipy 模組中定義的 dok_sparse() 方法建立基於鍵的稀疏矩陣的字典。

如下所示,dok_sparse() 方法接受一個普通矩陣並返回一個稀疏矩陣。

import numpy as np
from scipy import sparse
input_matrix = np.array([[16, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 5], [0, 0, 0, 0]])
print("The input matrix is:")
print(input_matrix)
sparse_matrix = sparse.dok_matrix(input_matrix)
print("The sparse matrix is:")
print(sparse_matrix)

輸出:

The input matrix is:
[[16  0  0  0]
 [ 0  0  0  0]
 [ 0  0  0  5]
 [ 0  0  0  0]]
The sparse matrix is:
  (0, 0)	16
  (2, 3)	5

まとめ

在本文中,我們討論了稀疏矩陣及其在 Python 中的實現。我們還看到了在 Python 中將普通矩陣轉換為稀疏矩陣的不同方法。

在建立稀疏矩陣時,你應該知道矩陣的預期用途。如果有很多列切片操作,你應該建立一個 CSC 矩陣。

對於行切片操作,你應該建立一個 CSR 矩陣。如果輸入矩陣很大,應先將其轉換為座標格式的稀疏矩陣。之後,就可以得到想要的稀疏矩陣了。

相關文章 - Python Matrix