0Pricing
Pandas & NumPy Academy · レッスン

行列式、逆行列、転置行列

np.linalg.detで行列式を、np.linalg.invで逆行列を、.Tで転置行列を計算します。

「行列式、逆行列、転置行列」はCoddyKit上の無料Pandas & NumPy Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPandas & NumPy Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

行列の転置

行列の転置とは、対角線を軸に行列を反転する操作です。行は列になり、列は行になります。Aの形状が(m, n)の場合、A.Tの形状は(n, m)です。転置は線形代数のさまざまな場面で登場します。たとえば、共分散行列の計算、勾配の逆伝播の実装、行ベクトルと列ベクトルの規約の変換などです。NumPyでは.T属性で転置にアクセスできます。コピーは作成されず、ストライドの順序を変更したビューが返されます。

import numpy as np

A = np.array([[1, 2, 3],
              [4, 5, 6]])
print('A shape:', A.shape)       # (2, 3)
print('A.T shape:', A.T.shape)   # (3, 2)
print(A.T)

転置の実践

よく使われるパターンにA.T @ Aの計算があります。これは、最小二乗回帰、PCA、正規方程式などで登場する対称な正方行列を生成します。Aの形状が(n, p)の場合、A.T @ Aの形状は(p, p)です。(A.T @ A)[i,j] == (A.T @ A)[j,i]が成り立つため、結果は常に対称です。この性質は、多くの数値ソルバーで効率化のために利用されています。

import numpy as np

A = np.array([[1.0, 2.0],
              [3.0, 4.0],
              [5.0, 6.0]])  # shape (3, 2)

ATA = A.T @ A   # shape (2, 2), symmetric
print('A.T @ A:')
print(ATA)
print('Is symmetric:', np.allclose(ATA, ATA.T))

行列式が表すもの

正方行列の行列式は、幾何学的な情報を表すスカラー値です。行列によって面積(2次元)や体積(高次元)が何倍になるかを示します。行列式が0の場合、その行列は特異であり、空間をより低い次元の部分空間へ押しつぶすため、逆行列を持ちません。行列式が0でなければ、その行列は可逆です。NumPyではnp.linalg.det()で計算できます。

import numpy as np

# Non-singular matrix
A = np.array([[3.0, 1.0],
              [2.0, 4.0]])
print('det(A):', np.linalg.det(A))   # 3*4 - 1*2 = 10

# Singular matrix (row 2 = 2 * row 1)
B = np.array([[1.0, 2.0],
              [2.0, 4.0]])
print('det(B):', np.linalg.det(B))   # ~0

np.linalg.inv()で逆行列を計算する

行列Aの逆行列はA⁻¹と表し、A @ A⁻¹ = Iを満たします。ここでIは単位行列です。逆行列が存在するのは、正方かつ非特異な行列だけです。np.linalg.inv(A)は逆行列を数値的に計算します。ただし、数値的に不安定になるため、実際には逆行列を明示的に計算することはほとんど避け、連立方程式には代わりにnp.linalg.solve()を使用してください。それでも、逆行列の概念を理解することは重要です。

import numpy as np

A = np.array([[3.0, 1.0],
              [2.0, 4.0]])

A_inv = np.linalg.inv(A)
print('Inverse:')
print(A_inv)

# Verify: A @ A_inv should be identity
I = A @ A_inv
print('A @ A_inv (should be I):')
print(np.round(I, 10))

直接逆行列を計算する際の数値的不安定性

行列の逆行列を計算してから乗算すると、浮動小数点誤差が蓄積します。たとえば、A_inv @ bで解くよりも、np.linalg.solve(A, b)を直接呼び出すほうが正確です。適切に条件付けされた行列(行列式が0から十分離れている行列)は、こうした誤差の影響を受けにくくなります。条件数(np.linalg.cond(A))は、行列がどの程度特異行列に近いかを数値化します。条件数が大きい場合は、数値計算上の問題が起きる可能性があります。

import numpy as np

A = np.array([[1.0, 2.0],
              [1.0001, 2.0]])
print('Condition number:', np.linalg.cond(A))
# Very high condition number -> near-singular, unstable inversion

b = np.array([3.0, 3.0001])
# Prefer solve over inv @ b
print('Solution via solve:', np.linalg.solve(A, b))

直交行列とその転置

行列には、A.T @ A = Iを満たす直交行列という特別な種類があります。これは転置行列が逆行列と同じであることを意味し、直交行列は非常に低コストで逆行列を求められます。回転行列やQR分解のQ因子は直交行列です。直交行列の各列は正規直交基底を形成します。つまり、各列の長さは1で、他のすべての列と垂直です。

import numpy as np

# 90-degree rotation matrix is orthogonal
theta = np.pi / 2
R = np.array([[np.cos(theta), -np.sin(theta)],
              [np.sin(theta),  np.cos(theta)]])

print('R.T @ R (should be identity):')
print(np.round(R.T @ R, 10))
print('Is orthogonal:', np.allclose(R.T @ R, np.eye(2)))

非正方行列の擬似逆行列

通常の逆行列は正方行列にしか存在しませんが、Moore-Penrose擬似逆行列を使うと、任意の行列に対して逆行列の概念を一般化できます。np.linalg.pinv(A)はSVDを使って擬似逆行列を計算します。これは、過剰決定系(未知数より方程式の数が多い系)に対する最小二乗解の基礎となります。線形回帰がまさに解いているのがこの問題です。Aが正方かつ可逆であれば、pinv(A)はinv(A)と等しくなります。

import numpy as np

# Over-determined system: 3 equations, 2 unknowns
A = np.array([[1.0, 1.0],
              [1.0, 2.0],
              [1.0, 3.0]])
b = np.array([2.0, 3.0, 5.0])

# Least-squares solution using pseudo-inverse
x = np.linalg.pinv(A) @ b
print('Best-fit solution:', x)
# Or use lstsq directly
x2, _, _, _ = np.linalg.lstsq(A, b, rcond=None)
print('lstsq solution:', x2)

行列式の符号と体積の拡大縮小

行列式の符号は、変換によって向きが保たれるか反転するかを示します。行列式が正なら向きは保たれ(回転など)、負なら向きは反転します(鏡映など)。絶対値は体積の拡大縮小率を表します。2×2行列[[a,b],[c,d]]の場合、det = a*d - b*cです。NumPyは任意のサイズの正方行列を効率的に処理できます。

import numpy as np

# Identity: det = 1 (no scaling, no flip)
I = np.eye(3)
print('det(I):', np.linalg.det(I))    # 1.0

# Scaling by 2 in all directions: det = 8 = 2^3
S = 2 * np.eye(3)
print('det(2I):', np.linalg.det(S))   # 8.0

# Reflection: det = -1
F = np.array([[-1.0, 0.0],
              [ 0.0, 1.0]])
print('det(reflection):', np.linalg.det(F))

安定性のためにnp.linalg.slogdet()を使う

大きな行列では、行列が非特異であっても、行列式がオーバーフローしたり、アンダーフローによって0になったりすることがあります。np.linalg.slogdet(A)は(sign, log_abs_det)、つまり行列式の符号と行列式の絶対値の自然対数を返すため、数値のオーバーフローを回避できます。これは確率モデル(ガウス尤度など)で広く使われています。こうしたモデルでは、数値を扱いやすい範囲に保つため、対数空間で計算します。

import numpy as np

A = np.random.rand(100, 100)

# Direct det might underflow for large matrices
sign, logdet = np.linalg.slogdet(A)
print('Sign:', sign)
print('Log|det|:', logdet)
print('Actual det (may be ~0 due to float):', np.linalg.det(A))
print('Reconstructed |det|:', np.exp(logdet))

実践:2×2行列を手計算する場合とNumPyを使う場合

2×2行列[[a, b], [c, d]]の逆行列は、det = ad - bcとしたとき、(1/det) * [[d, -b], [-c, a]]です。この公式を知っていると、NumPyの計算結果を簡単に検算できます。それより大きな行列では、逆行列を解析的に計算するのは現実的ではありません。まさにそのためにnp.linalg.inv()を使います。数値結果は必ずnp.allclose(A @ A_inv, np.eye(n))で検証してください。

import numpy as np

a, b, c, d = 3.0, 1.0, 2.0, 4.0
A = np.array([[a, b], [c, d]])
det = a*d - b*c

# Manual inverse
A_inv_manual = (1/det) * np.array([[d, -b], [-c, a]])
print('Manual inv:')
print(A_inv_manual)

# NumPy inverse
print('np.linalg.inv:')
print(np.linalg.inv(A))
print('Match:', np.allclose(A_inv_manual, np.linalg.inv(A)))

パイプラインで転置と逆行列を組み合わせる

線形代数でよく使われるパターンに、転置と逆行列の組み合わせがあります。(A.T @ A)⁻¹ @ A.Tを計算すると、通常の最小二乗法で使われる射影行列が得られます。NumPyではnp.linalg.inv(A.T @ A) @ A.Tと記述できますが、ここでも数値的にはnp.linalg.lstsqのほうが適しています。この基本パターンを知っておくと、ソルバーが何をしているのかを理解し、行列がほぼ特異な場合の問題をデバッグするのに役立ちます。

import numpy as np

# Design matrix for simple linear regression (with bias)
X = np.column_stack([np.ones(5), np.array([1., 2., 3., 4., 5.])])
y = np.array([2.1, 3.9, 6.2, 8.1, 9.8])

# OLS via normal equations: beta = (X.T @ X)^-1 @ X.T @ y
beta = np.linalg.inv(X.T @ X) @ X.T @ y
print('Coefficients (intercept, slope):', np.round(beta, 3))

# Verify with lstsq
beta2, _, _, _ = np.linalg.lstsq(X, y, rcond=None)
print('lstsq result:', np.round(beta2, 3))

理解度チェック

このレッスンで扱ったデータ分析の概念について、理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、A.Tは行と列を入れ替える転置であること、np.linalg.inv()は行列の逆行列を計算するものの直接使うことはほとんど避け(solveまたはlstsqを優先すること)、np.linalg.det()は特異行列では0になる行列式を返すことを学びました。次は、np.linalg.solveを使って連立一次方程式を直接解く方法を学びます。

よくある質問

「行列式、逆行列、転置行列」レッスンは無料ですか?

はい。「行列式、逆行列、転置行列」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Pandas & NumPy Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

「行列式、逆行列、転置行列」で何を学びますか?

np.linalg.detで行列式を、np.linalg.invで逆行列を、.Tで転置行列を計算します。 ブラウザで直接実行するハンズオンコードでPandas & NumPy Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Pandas & NumPy Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPandas & NumPy Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「行列式、逆行列、転置行列」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPandas & NumPy Academyレッスンでコードを書いて実行できますか?

はい。すべてのPandas & NumPy Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. np.matmulと@による行列の乗算
  2. 行列式、逆行列、転置行列
  3. 連立一次方程式を解く
  4. 固有値とSVDの概要
← Pandas & NumPy Academyに戻る