Python のスパース行列

Aditya Raj 2023年1月30日
  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 でスパース行列を作成する方法

任意の行列の冗長ゼロのメモリ使用量を回避するために、正規行列をスパース行列に変換できます。

スパース行列は、3つの要素を含むリストと考えることができます。リストの内部リストには、指定された入力行列のゼロ以外の要素の行番号、列番号、および値が格納されます。これはスパース行列を表します。

たとえば、次の入力行列について考えてみます。

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

この行列には、(0,0)(2,3) の 2つの場所にのみ非ゼロ要素があります。

この行列をスパース行列に変換するために、スパース行列を表すリストを作成します。リストには、ゼロ以外の要素の行番号、列番号、および値を含むリストが含まれます。

したがって、スパース行列には、[0,0,16][2,3,5] の 2つの内部リストがあります。最終的なスパース行列は次のようになります。

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

ここ、

  • 内部リストの最初の要素は、入力行列のゼロ以外の要素の行番号を表します。
  • 内部リストの 2 番目の要素は、入力行列のゼロ以外の要素の列番号を表します。
  • 最後に、内部リストの 3 番目の要素には、ゼロ以外の要素の実際の値が含まれています。

与えられた行列からスパース行列を作成するには、最初にスパース行列を表すリスト 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 以上の場合に非常に役立ちます。スパース行列のサイズは、入力行列と比較して大幅に小さくなります。

行列内の非ゼロ要素の数が行列内の全要素の 3 分の 1 より大きい場合、スパース行列の作成と使用は元の行列を使用するよりもコストがかかることに注意してください。行列にゼロ以外の要素が n ある場合、スパース行列には 3*n 要素が含まれます。

Python の SciPy モジュールを使用して、正規行列をスパース行列に変換する

scipy モジュールを使用して、正規行列をスパース行列に変換することもできます。scipy モジュールは、正規行列をスパース行列に変換するためのさまざまなメソッドを提供します。

すべての方法を 1つずつ説明しましょう。

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 の圧縮スパース列行列

列のスライスが必要なプログラムでは、CSR 行列の代わりに圧縮スパース列(CSC)行列を使用できます。

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 マトリックスを作成する必要があります。入力行列が大きい場合は、最初に座標形式のスパース行列に変換する必要があります。その後、目的のスパース行列を取得できます。

著者: Aditya Raj
Aditya Raj avatar Aditya Raj avatar

Aditya Raj is a highly skilled technical professional with a background in IT and business, holding an Integrated B.Tech (IT) and MBA (IT) from the Indian Institute of Information Technology Allahabad. With a solid foundation in data analytics, programming languages (C, Java, Python), and software environments, Aditya has excelled in various roles. He has significant experience as a Technical Content Writer for Python on multiple platforms and has interned in data analytics at Apollo Clinics. His projects demonstrate a keen interest in cutting-edge technology and problem-solving, showcasing his proficiency in areas like data mining and software development. Aditya's achievements include securing a top position in a project demonstration competition and gaining certifications in Python, SQL, and digital marketing fundamentals.

GitHub

関連記事 - Python Matrix