機械学習の紹介スパース行列(Pythonコード付き)

行列の場合、ゼロを持つ要素の数が非ゼロ要素の数よりはるかに多く、非ゼロ要素の分布が不規則である場合、そのような行列はスパース行列と呼ばれ、対照的に、非ゼロ要素の数が占める場合ほとんどの場合、このような行列は密行列と呼ばれます。

スパース行列は、エンジニアリングアプリケーション、特に通信コーディングと機械学習でよく使用されます。 符号化行列または特徴表現行列が疎行列である場合、その計算速度は大幅に改善される。 機械学習のために、データ特徴表現、自然言語処理の分野のように、疎マトリックスアプリケーションは非常に広い。

スパース表現や作業の使用は計算コストが高く、疎なマトリックス表現や演算を特別に処理する必要がありますが、これらの操作はパフォーマンスを大幅に向上させる可能性があります。

このチュートリアルでは、疎な行列の基本的な概念、既存の問題、Pythonでそれらを使用する方法を学習することができます。

スパース行列

スパース行列は、ほとんどがゼロ行列からなる行列です。これは、行列を密行列と区別するための大きな特徴です。

要素の多くがゼロの場合、行列は疎です。 スパース性に関心がある理由は、この機能を使用すると計算量を大幅に削減でき、実際には多くの大きな行列問題も疎であることが分かったからです。

行列の希薄さは、小数部、すなわち、行列のゼロ要素の数を行列の要素の総数で割った数で量子化することができます。

sparsity = count zero elements / total elements

以下は、小さな3×6スパース行列の例です

  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%です。

スパース問題

スパース行列は、空間および時間の複雑さの点で問題を引き起こす可能性があります。

空間の複雑さ

大きな行列は記憶に多くのメモリを必要とし、使用したい大行列のいくつかはまばらです。

実際、ほとんどの大きな行列は疎であり、ほとんどすべてのエントリはゼロです。

一例は、大きな行列が大きすぎてメモリに格納できないことです。この行列は、あるWebサイトから別のWebサイトへのリンクを表すリンク行列です。 より小さい疎行列の例は、本の中のすべての既知の単語または用語に対する出現の行列であってもよい。 これらの行列を密行列として表現する問題は、メモリが必要であり、32または64ビットのゼロ値が行列内に割り当てられなければならないということである。 これらのゼロ値には情報が含まれていないため、これは明らかにメモリリソースの無駄です。

時間の複雑さ

非常に大きなスパース行列をメモリに格納することができ、その後、この行列に対していくつかの演算が実行されると仮定します。 単純に言えば、マトリックスが主にゼロ値を含む場合、すなわちデータがあまりない場合、実行される計算の大部分がゼロ値の加算または乗算を含むこのマトリックス上で演算を実行するのに時間がかかることがあります。

そのような問題に対する線形代数の使用は、ほとんどのO(N ^ 3)算術演算が方程式または行列逆変換に含まれるゼロオペランドを解くことに専念しているので無駄である。

行列演算の時間複雑度は、行列のサイズが大きくなるにつれて増加する。 機械学習では、最も単純な方法であっても、各行、列、または行列全体で多くの操作を必要とすることがあり、実行時間が長くなり、上記の問題がより複雑になります。

機械学習におけるスパース行列

スパース行列は機械学習アプリケーションによく現れる。 このセクションでは、読者が直感的に理解できるように、まばらな問題について深く理解できるように、いくつかの一般的な例について説明します。

データ

スパース行列は、一般的な記録活動が発生する回数など、特定の種類のデータに一般的に現れます。

ここに3つの例があります:

  • ユーザーがムービーカタログでムービーを見たかどうか。
  • ユーザーがカタログで製品を購入するかどうか。
  • 曲が曲カタログで聴かれた回数。

データ準備

スパース行列は、データを書き込むために使用されるコーディング方式に現れます。 3つの一般的な例は次のとおりです。

  1. 分類されたデータを疎バイナリベクトルとして表現するワンホットコーディング。
  2. 文書の語彙における単語の頻度を示すのに使用されるカウントコード。
  3. 語彙における語頻度逆文書の頻度を表すために使用されるTF-IDFコードと、

研究分野

入力データがほとんど常に疎であるため、機械学習の研究分野によっては、まばらな問題に直接対処する特殊な方法を開発する必要があります。 ここに3つの例があります:

1.テキスト文書の自然言語処理の処理。

前記カタログ内の製品の使用を処理するための推奨システムであって、

多くの黒画素画像を含む場合のコンピュータ視覚問題の取り扱い; 4。

言語モデルに100,000語がある場合、特徴ベクトルの長さは100,000ですが、短い電子メールメッセージの場合、ほとんどすべての特徴数はゼロです。

スパース行列を使用する

スパース行列を表現し使用するためのソリューションは、代替データ構造を使用してスパース行列を表現することです。 ゼロ要素値は無視することができ、スパース行列内の非ゼロ要素値のみを格納または使用する必要があります。 スパース行列を効果的に構築できるいくつかのデータ構造があります。以下に3つの一般的な例を示します。

1.辞書:辞書は行と列のインデックスを使用して値をマッピングします。

リストのリスト:行列の各行はリストに格納され、各サブリストは列のインデックスとその値を含みます。

3.座標リスト:タプルリストは、行インデックス、列インデックス、およびその値を含む各タプルに格納されます。

以下の2つの一般的な例のように、効率的な操作を実行するのに適したデータ構造もいくつかあります。

  1. CSR(Compressed Sparse Row):スパース行列は、非ゼロ値、行の範囲、および列インデックスの3つの1次元配列で表されます。
  2. CSC(Compressed Sparse Column):列インデックスが行インデックスの前に圧縮されて最初に読み取られることを除いて、CSRメソッドと同じです。

Pythonのスパース行列

SciPyは、複数のデータ構造を使用して、密度の高い行列を疎行列に変換するための疎行列とツールを作成するためのツールを提供します。 Numpyアレイで動作する多くの線形代数NumpyとSciPy関数は、SciPyの疎配列で動作します。 さらに、Numpyデータ構造を使用する機械学習ライブラリは、機械学習のためのscikit学習や深い学習のためのKerasなど、Scipyの疎な配列でも動作することができます。

scr_matrix()関数を呼び出すことで、CSR表現を使用して、Numpy配列に格納された密行列を疎行列に変換することができます。 次の例では、3×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表現が印刷され、再構成された密行列が印刷されます。

[[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

「機械学習のためのスパース行列にやさしい入門」というタイトルの記事、著者:ジェイソン・ブラウンリー、翻訳:ベゴニア。

記事の詳細な内容については、 元の内容を確認してください

元のリンク