はじめに: なぜ線形代数と機械学習の言語を使うのか
機械学習モデルが画像を処理したり、テキストを分類したり、予測を生成したりするたびに、 ボンネットの下でパフォーマンスを行っています 線形代数演算。入力データがプロットされます どうやって ベクトル、モデルの重みは次のようになります 行列、および推論プロセス全体 要約すると、一連の 行列の乗算 そして線形変換。
この記事では、基本的な概念から始めて、 固有値、SVD、分解 PCA、推奨などのアルゴリズムの基礎となる そしてモデル圧縮。各式には 1 つの式が付属します。 直感的な説明 e 1つからNumPyの実装.
何を学ぶか
- ベクトル、ノルム、スカラー積: データの幾何学
- 行列: 乗算、転置、逆行列とその意味
- 決定要因とランク: 変革について教えてくれる事
- 固有値と固有ベクトル: 不変の方向
- 特異値分解 (SVD): ML の最も強力なツール
- NumPy での実践的な実装
ベクター: 基本的な構成要素
Un ベクター そして番号の順序付きリスト。 ML では、ベクトルは単一の要素を表します。 データポイント: 画像の特徴、フレームのピクセル、文のエンコードされた単語。ベクトル で \\mathbb{R}^n ha n コンポーネント。
たとえば、3 次元ベクトルは次のようになります。
ベクトルノルム: サイズの測定
La 標準 ベクトルの「長さ」を測定します。 ML で最もよく使用される 2 つの規範は次のとおりです。
L2 ノルム (ユークリッド) - 原点からの幾何学的距離:
ノーマ L1 (マンハッタン) - 絶対値の合計。スパース性を促進するのに役立ちます。
ML では、L2 ノルムが使用されます。 リッジの正則化 体重が多すぎるとペナルティを与える L1 ノルムは大きいですが、 なげなわ正則化 分散重みを取得するには (多くの ゼロまで)、特徴の選択に役立ちます。
スカラー積: 類似性の測定
Il スカラー積 2 つのベクトル間の (ドット積)、およびおそらく最も重要な演算 MLで。 2 つのベクトルがどの程度「同じ方向を向いているか」を測定します。
幾何学的には、スカラー積は角度に関係します。 \\シータ ベクトルの中では:
いつ \\cos\\シータ = 1、ベクトルは平行です (類似度が最大)。 いつ \\cos\\シータ = 0、は直交(関係なし)です。これは まさにその原理 少し似ている 推奨システムで使用される そしてセマンティック検索でも。
重要な洞察: ニューラル ネットワークでは、各ニューロンがドット積を計算します。 入力ベクトルの間 \\mathbf{x} そして重みベクトル \\mathbf{w}、バイアスを追加します b、 そして活性化関数を適用します。 \\sigma(\\mathbf{w} \\cdot \\mathbf{x} + b).
import numpy as np
# Vettori
a = np.array([2, -1, 4])
b = np.array([1, 3, 2])
# Prodotto scalare
dot = np.dot(a, b) # 2*1 + (-1)*3 + 4*2 = 7
print(f"Dot product: {dot}")
# Norme
l2_norm = np.linalg.norm(a) # sqrt(4 + 1 + 16) = sqrt(21)
l1_norm = np.linalg.norm(a, ord=1) # 2 + 1 + 4 = 7
print(f"L2 norm: {l2_norm:.4f}")
print(f"L1 norm: {l1_norm}")
# Cosine similarity
cos_sim = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
print(f"Cosine similarity: {cos_sim:.4f}")
行列: データ変換
Una マトリックス そして数値の長方形配列。 ML では、行列は次のことを表します。 データセット (行 = サンプル、列 = 特徴) e 重み ニューラルネットワークのこと。 マトリックス \\mathbf{A} \\in \\mathbb{R}^{m \\times n} ha m 線と n 列。
行列乗算: 深層学習の核心
行列間の乗算 \\mathbf{A} \\in \\mathbb{R}^{m \\times n} そしてベクトル \\mathbf{x} \\in \\mathbb{R}^n 新しいベクトルを生成します \\mathbf{y} \\in \\mathbb{R}^m:
この操作は 1 つです 線形変換: 入力空間内のベクトルを受け取ります そしてそれを出力空間にマッピングします。ニューラル ネットワーク層はまさにこれを行います。
どこ \\mathbf{W} そして重み行列、 \\mathbf{x} 入力、 \\数学{b} バイアス、e \\シグマ アクティベーション関数。
転置と対称
La 転置された \\mathbf{A}^T 行と列を交換します。 (\\mathbf{A}^T)_{ij} = A_{ji}。これは次の理由から基本的なものです。
- スカラー積は次のように書かれます \\mathbf{a}^T \\mathbf{b}
- 共分散行列 e \\frac{1}{n}\\mathbf{X}^T\\mathbf{X}
- バックプロパゲーションでは、勾配は重みの転置で伝播されます。
決定要因: 体積と可逆性
Il 決定的 正方行列の値は、変換によってボリュームがどのようにスケールされるかを測定します。 2x2 行列の場合:
Se \\det(\\mathbf{A}) = 0、行列 e 特異 (非可逆): 変換により空間が「押しつぶされ」、情報が失われます。これはサインです の 共線性 これは線形回帰で問題を引き起こします。
ランク: 有効サイズ
Il ランク 行列の数と線形に独立した行 (または列) の数。 マトリックスの場合 \\mathbf{A} \\in \\mathbb{R}^{m \\times n} 彼には地位がある r < \\min(m, n)、データが部分空間に存在することを意味します サイズ的に r、完全な空間ではありません。これが原則です の基礎 寸法縮小.
import numpy as np
# Matrice dei pesi (layer neurale: 3 input -> 2 output)
W = np.array([[0.5, -0.3, 0.8],
[0.2, 0.7, -0.4]])
x = np.array([1.0, 2.0, 3.0])
# Forward pass: trasformazione lineare
y = W @ x # oppure np.dot(W, x)
print(f"Output: {y}") # [-0.1 + ... = risultato]
# Trasposta
print(f"W shape: {W.shape}") # (2, 3)
print(f"W^T shape: {W.T.shape}") # (3, 2)
# Determinante (solo matrici quadrate)
A = np.array([[3, 1], [2, 4]])
det = np.linalg.det(A)
print(f"Determinante: {det:.2f}") # 10.0
# Rango
rank = np.linalg.matrix_rank(W)
print(f"Rango: {rank}") # 2
固有値と固有ベクトル: 特別な方向性
Gli 固有ベクトル 行列の方向は、次の場合に方向が変化しない方向です。 変換が適用されます。それらは、と呼ばれる係数によってのみスケールされます。 固有値。 正式には、正方行列の場合、 \\mathbf{A}:
どこ \\mathbf{v} と固有ベクトル e \\ラムダ 対応する固有値。
幾何学的な直感: ゴムシートにアイロンをかけているところを想像してください。最多ポイント さまざまな方向に動きますが、回転せずに伸張または圧縮されるだけの方向もあります。それら は固有ベクトルの方向であり、どれだけ引き伸ばされるかは固有値によって与えられます。
固有値を見つけるには、特性方程式:
ML では、共分散行列の固有値からわかります。 どのくらいの差異があるのか 長いものがあります それぞれの主な方向。これがPCA(主成分分析)の基礎です。
ML アプリケーション: PCA では、共分散行列の固有ベクトルは次のとおりです。 主なコンポーネント、固有値は、それぞれがどの程度の分散を捉えているかを示します。 コンポーネント。上位 k 個の固有ベクトルを選択することで、ほとんどの要素を維持しながら次元を削減します。 情報の一部。
import numpy as np
# Matrice simmetrica (come una matrice di covarianza)
A = np.array([[4, 2],
[2, 3]])
# Calcolo autovalori e autovettori
eigenvalues, eigenvectors = np.linalg.eigh(A)
print(f"Autovalori: {eigenvalues}")
print(f"Autovettori:\n{eigenvectors}")
# Verifica: A @ v = lambda * v
for i in range(len(eigenvalues)):
v = eigenvectors[:, i]
lam = eigenvalues[i]
lhs = A @ v
rhs = lam * v
print(f"A*v = {lhs}, lambda*v = {rhs}, uguale: {np.allclose(lhs, rhs)}")
特異値分解 (SVD): 万能ツール
La SVD そして、ML にとって最も重要で多用途な線形代数の分解です。 任意の行列 \\mathbf{A} \\in \\mathbb{R}^{m \\times n} 次のように分解できます。
どこ:
- \\mathbf{U} \\in \\mathbb{R}^{m \\times m} - 直交行列(出力方向)
- \\boldsymbol{\\Sigma} \\in \\mathbb{R}^{m \\times n} - i を含む対角行列 特異値 \\sigma_1 \\geq \\sigma_2 \\geq \\cdots \\geq 0
- \\mathbf{V}^T \\in \\mathbb{R}^{n \\times n} - 直交行列(入力方向)
直感: SVD は、線形変換を 3 つのステップに分割します: 回転 (\\mathbf{V}^T)、軸に沿ったスケーリング (\\boldsymbol{\\シグマ})、そして別の回転 (\\mathbf{U}).
切り詰められた SVD: スマート圧縮
最初のものだけを保持する k 特異値を使用すると最良の結果が得られます ランクの近似値 k 元の行列の:
これは、画像圧縮、推奨システム (行列分解)、 ノイズリダクション、およびテキストの潜在意味分析 (LSA)。
import numpy as np
# Matrice (es. ratings utenti-prodotti)
A = np.array([[5, 4, 0, 0],
[4, 5, 0, 0],
[0, 0, 4, 5],
[0, 0, 5, 4]])
# SVD completa
U, sigma, Vt = np.linalg.svd(A)
print(f"Valori singolari: {sigma}")
# SVD troncata (rank-2 approssimazione)
k = 2
U_k = U[:, :k]
sigma_k = np.diag(sigma[:k])
Vt_k = Vt[:k, :]
A_approx = U_k @ sigma_k @ Vt_k
print(f"Matrice originale:\n{A}")
print(f"Approssimazione rank-{k}:\n{np.round(A_approx, 2)}")
# Errore di ricostruzione
error = np.linalg.norm(A - A_approx, 'fro')
print(f"Errore Frobenius: {error:.4f}")
# Varianza spiegata
explained = np.sum(sigma[:k]**2) / np.sum(sigma**2) * 100
print(f"Varianza spiegata con k={k}: {explained:.1f}%")
NumPy でのブロードキャストと効率的な操作
NumPy がサポートしているのは、 放送、操作を実行できる仕組み コピーを作成せずに、異なるサイズの配列間で共有できます。これは ML コードを記述するための基本です 効率的です。
import numpy as np
# Dataset: 1000 campioni, 10 feature
X = np.random.randn(1000, 10)
# Normalizzazione: sottrai media, dividi per std
mean = X.mean(axis=0) # shape: (10,)
std = X.std(axis=0) # shape: (10,)
X_norm = (X - mean) / std # Broadcasting automatico!
# Batch matrix multiplication
# W: (10, 5), X: (1000, 10) -> output: (1000, 5)
W = np.random.randn(10, 5)
output = X_norm @ W # Equivalente a np.dot(X_norm, W)
print(f"Output shape: {output.shape}")
# Moltiplicazione element-wise vs matrix
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(f"Element-wise: {a * b}") # [[5, 12], [21, 32]]
print(f"Matrix mult: {a @ b}") # [[19, 22], [43, 50]]
実用的な応用: ニューラル ネットワークのフォワード パス
2 層ニューラル ネットワークの完全な前方パスを実装して、すべてをまとめてみましょう 線形代数のみを使用する場合:
import numpy as np
def relu(x):
return np.maximum(0, x)
def softmax(x):
exp_x = np.exp(x - np.max(x, axis=1, keepdims=True))
return exp_x / np.sum(exp_x, axis=1, keepdims=True)
# Architettura: 4 input -> 8 hidden -> 3 output (classificazione)
np.random.seed(42)
W1 = np.random.randn(4, 8) * 0.1 # Pesi layer 1
b1 = np.zeros(8) # Bias layer 1
W2 = np.random.randn(8, 3) * 0.1 # Pesi layer 2
b2 = np.zeros(3) # Bias layer 2
# Input: batch di 5 campioni, 4 feature ciascuno
X = np.random.randn(5, 4)
# Forward pass (pura algebra lineare!)
# Layer 1: trasformazione lineare + attivazione
z1 = X @ W1 + b1 # (5, 4) @ (4, 8) + (8,) = (5, 8)
h1 = relu(z1) # (5, 8) - attivazione ReLU
# Layer 2: trasformazione lineare + softmax
z2 = h1 @ W2 + b2 # (5, 8) @ (8, 3) + (3,) = (5, 3)
probs = softmax(z2) # (5, 3) - probabilità per 3 classi
print(f"Probabilità output:\n{np.round(probs, 4)}")
print(f"Somma per riga: {probs.sum(axis=1)}") # Deve essere ~1.0
print(f"Classi predette: {np.argmax(probs, axis=1)}")
概要と ML との関係
覚えておくべき重要なポイント
- スカラー積 \\mathbf{a} \\cdot \\mathbf{b}: 類似性と各ニューロンの基本動作を測定します。
- 行列乗算 \\mathbf{W}\\mathbf{x}: 線形変換、フォワードパスの核心
- 固有値: 最大分散 (PCA) の方向を示します。
- SVD: 圧縮、推奨、ノイズ除去のための汎用分解
- L2規格: リッジの正則化に使用され、過学習を防止します。
- ランク: 実際のデータ サイズ、次元削減の基礎
次の記事で: を探索してみます 微分積分 深い学習のために。 勾配によってニューラル ネットワークがどのように学習できるか、また連鎖規則がどのように適用されるかを見ていきます。 バックプロパゲーションが可能になります。







