初心者向け!特異値分解(SVD)とは?仕組みから活用例まで分かりやすく解説

はじめに:特異値分解(SVD)ってなんだろう?

特異値分解(Singular Value Decomposition、略してSVD)は、データサイエンスや機械学習の世界で非常に重要な役割を果たす、行列を分解するための一手法です。 一言で言うと、どんな複雑な行列(数字が並んだ表のようなもの)でも、「回転」「拡大・縮小」「また回転」という3つの単純な行列の積に分解する技術です。

なぜこれが便利なのでしょうか? それは、データを分解することで、そのデータが持つ「本質的な情報」や「重要な特徴」だけを抽出できるようになるからです。 ノイズの多いデータから重要な部分だけを取り出したり、大量のデータをより少ない情報量で表現したり(次元削減)することが可能になります。

特異値分解の仕組み

特異値分解では、元の行列Aを次の3つの行列の積に分解します。

A = UΣVT

それぞれの行列には、以下のような役割があります。

行列 名称 役割 概要
U 左特異ベクトル (Left Singular Vectors) データの「回転」を担当 元の行列の行の情報を集約したベクトル(左特異ベクトル)を含んだ直交行列です。 データの主要な「方向」を示します。
Σ (シグマ) 特異値 (Singular Values) データの「拡大・縮小」を担当 対角成分に「特異値」と呼ばれる値が並んだ対角行列です。 特異値はデータの重要度を表しており、値が大きいほど重要です。
VT 右特異ベクトル (Right Singular Vectors) データの「回転」を担当 元の行列の列の情報を集約したベクトル(右特異ベクトル)を含んだ直交行列の転置行列です。 これもデータの「方向」を示します。

この分解の最大のポイントは、対角行列Σに並ぶ特異値です。特異値は大きい順に並んでおり、値が大きいものほど、元のデータにとって重要な情報を持っていることを意味します。 そのため、小さい特異値を無視する(0とみなす)ことで、データの情報をほとんど失うことなく、データ量を削減(低ランク近似)できるのです。

特異値分解の応用例

特異値分解は、その強力な特性から様々な分野で応用されています。

  • 次元削減・データ圧縮
    特異値分解の最も代表的な応用例です。例えば、画像データはピクセルの集まりであり、巨大な行列として表現できます。SVDを用いて重要度の低い特異値とそれに対応するベクトルを削除することで、画質を大きく損なうことなくファイルサイズを圧縮できます。
  • 推薦システム
    オンラインショッピングサイトや動画配信サービスなどで「あなたへのおすすめ」を表示するシステムにもSVDが使われています。 ユーザーの評価履歴を行列で表し、SVDで分解することで、ユーザーの潜在的な好みやアイテムの潜在的な特徴を抽出します。 これにより、まだ評価していないアイテムに対する評価値を予測し、おすすめを生成します。2006年から開催されたNetflix Prizeというコンテストで、SVDを用いた手法が上位を占めたことで有名になりました。
  • 自然言語処理 (NLP)
    文章中の単語の出現頻度を行列にし、SVDを適用することで、単語や文書の背後にある潜在的な意味(トピック)を抽出するLSI(Latent Semantic Indexing)という手法があります。 これにより、単語が完全に一致しなくても、文脈的に似ている文書を検索することが可能になります。
  • ノイズ除去
    データに含まれる特異値のうち、小さいものはノイズに対応する場合が多いと考えられます。これらの小さい特異値を取り除くことで、データからノイズを除去し、よりクリーンなデータを得ることができます。

Pythonで特異値分解を試してみよう

PythonのライブラリであるNumPyを使うと、簡単に特異値分解を計算できます。


import numpy as np

# 2x3の行列を定義
A = np.array([, 
             ])

print("Original Matrix A:")
print(A)

# 特異値分解を実行
U, s, Vt = np.linalg.svd(A)

print("\nU (Left Singular Vectors):")
print(U)

# sはベクトルとして返されるので、対角行列に変換する
Sigma = np.zeros(A.shape)
Sigma[:A.shape, :A.shape] = np.diag(s)

# A.shapeが(2,3)なので、Sigmaを(2,3)に合わせる
# np.diag(s)は(2,2)なので、Sigmaの左側に埋め込む
Sigma = np.zeros(A.shape)
Sigma[:min(A.shape), :min(A.shape)] = np.diag(s)


print("\nSigma (Singular Values):")
print(Sigma)

print("\nVt (Right Singular Vectors, transposed):")
print(Vt)

# 分解した行列を再構成して、元の行列に戻ることを確認
A_reconstructed = U @ Sigma @ Vt

print("\nReconstructed Matrix A:")
print(A_reconstructed)
      

このコードでは、`np.linalg.svd()` を使うだけで、行列AをU、s(特異値のベクトル)、Vt(Vの転置行列)に分解できます。 そして、分解された行列を掛け合わせる(`U @ Sigma @ Vt`)ことで、元の行列Aが復元できることが確認できます。

まとめ

特異値分解(SVD)は、一見すると複雑な数学の道具に思えるかもしれません。しかし、その本質は「複雑なデータを、回転と拡大・縮小というシンプルな要素に分解し、データの重要な部分を見つけ出す」という強力なアイデアです。

データ圧縮から推薦システム、自然言語処理まで、幅広い分野で活躍するこの技術は、現代のデータサイエンスを支える基本的なツールの一つと言えるでしょう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です