線形代数

線形代数は、線形空間における代数の学問ですが、ここでは、NumPyのベクトルや行列についても紹介します。

Pythonでは NumPy を使って 多次元配列 を表現できます。NumPyの多次元配列では、各次元によって次のような言葉を使います。「NumPyの用語や計算」が数学の定義と異なる場合、本ページでは「NumPyのベクトル」のように記述します。

多次元配列の次元 言葉
0 スカラー
1 ベクトル
2 行列
3以上 テンソル(広義には0次元以上)

スカラー は「1つの数値」を「ベクトルや行列」と対比させた言い方ですが、NumPyのスカラーは「整数や浮動小数点数」とは別の多次元配列です。以降では、NumPyのスカラーは用いません。スカラーという場合、「1つの数字」という意味です。

ベクトル

ベクトル とは、 (139.75, 35.68) のように、数字の並びを丸括弧でくくったものです。要素数をベクトルの次元といいます(多次元配列の次元とは別の概念です)。 (5, 2, 7) は3次元ベクトルです。N次元ベクトルをN次元空間で表現するとき、矢印を使います。ベクトルの要素は、矢印の各軸の増加量で表します。例えば、 (1, 2) は下図のようになります。

../../_images/math_07.png

ベクトル のi番目の要素を と記述します。すなわち、N次元ベクトルの場合、 です。ベクトルであることを示すために、 のように記述することもあります。

NumPyのベクトルは、 numpy.array([1, 2]) のように記述します。 v がNumPyのベクトルのとき、i番目の要素は v[i - 1] です。

単位ベクトル

単位ベクトルは、ノルム(後述)が1のベクトルです。 と記述することが多いです。

零ベクトル

全要素が0のベクトルです。ゼロベクトルともいいます。 や と記述します。 NumPyのN次元零ベクトルは、 numpy.zeros(N) です。

行列

行列 とは、下図のように縦方向(行)と横方向(列)に数字がならんだ構造です。N行M列の行列をN×M行列といいます。 は2×3行列です。

NumPyの行列は、 numpy.array([[3, 1, 4], [1, 7, 3]]) のように記述します。 m がNumPyの行列のとき、i行目j列目の要素は m[i - 1, j - 1] です。

正方行列

N×N行列をN次正方行列または単に 正方行列 といいます。

単位行列

正方行列 において、対角要素が1で、それ以外が0であるとき、行列 を 単位行列 といいます。 と記述することが多いです(以降、 を単位行列とします)。

NumPyでは、 numpy.eye(N) で、N×N単位行列を作成できます。

零行列

全要素が0の行列です。ゼロ行列ともいいます。 と記述します。

NumPyでは、 numpy.zeros((N, N)) で、N×N零行列を作成できます。

逆行列

正方行列 と に対し、 となる を の逆行列といい、 と表します。 は と の積(後述)です。

NumPyでは、 numpy.linalg.inv(A) で計算できます。

転置

要素と軸の対応を反転することを 転置 といいます。 を行列としたとき、「i行目j列目の要素をAのj行目i列目の要素とした行列」を の転置行列といい、 と記述します。 また、 となる行列を 対称行列 といいます。

N×1行列、1×N行列を、それぞれ列ベクトルと行ベクトルといいます。このとき、列ベクトルの転置ベクトルは、行ベクトルになります。ただし、列ベクトルや行ベクトルを単にベクトルと呼ぶこともあります。

なお、NumPyでは、列ベクトルや行ベクトルは行列として作成します。NumPyの転置も A^T と記述します。

行列のランク

行列のランク は、一次独立な行ベクトルの最大本数です。 階数 とも呼ばれます。

NumPyでは、 numpy.linalg.matrix_rank で計算できます。 「 が一次独立」とは、「 がどちらも零ベクトルでなく、内積(後述)が0」ということです。

行列のノルム

行列ノルム は、ベクトルのノルムを行列に対し自然に一般化したものです。

NumPyでは、 numpy.linalg.norm で計算できます。

固有値と固有ベクトル

となる零でないベクトル とスカラー が存在するとき、xを の 固有ベクトル 、xをAの 固有値 といいます。 NumPyでは、 numpy.linalg.eig で計算できます。

行列式

行列式 正方行列に対して計算でき、 あるいは と表記されます。

NumPyでは、 numpy.linalg.det で計算できます。 の行列式は、 a * d - b * c になります。

行列式は、全ての固有値を掛けた値と等しく、行列式が0だと逆行列は存在しません。

演算

ベクトルの演算

をスカラー、 をベクトルとしたとき、以下のように計算します。

../../_images/math_08.png

NumPyのベクトルも同様に計算できます。

  • ベクトル v * 2 は、ベクトル v を2倍に伸ばしたものになります。
  • ベクトル v + w は、 v の先から w の分さらに進んだものになります。
  • ベクトル v - w は、 v の先から w の分、逆向きに進んだものになります。

をベクトルの 内積 といい、 で計算します。結果はスカラーになるので、スカラー積ともいいます。 が列ベクトルの場合、 と書くこともあります。

NumPyでは、 numpy.dot(v, w) または v @ w で内積を計算できます。

ノルム は、ベクトルの大きさを概念です。主なノルムを以下に示します。

  • ノルム:
  • ノルム:

※ ノルムを距離と捉えた場合、 ノルムをユークリッド距離(いわゆる距離)、 ノルムをマンハッタン距離ともいいます。 ノルムは、単に と書くこともあります。

内積は、ベクトルの間の角 と ノルムを使って で計算できます。

NumPyでは、 ノルムを np.linalg.norm(v) 、 ノルムを np.linalg.norm(v, 1) で計算できます。

行列の演算

をスカラー、 、 を行列としたとき、以下のように計算します。

NumPyでは通常の式のように書けます。

サンプルコード

α = 2
A = numpy.array([[10, 20], [30, 40]])
B = numpy.array([[1, 2], [3, 4]])
print(α * A)
print(A + B)
print(A - B)

出力

[[20 40]
 [60 80]]
[[11 22]
 [33 44]]
[[ 9 18]
 [27 36]]

なお、NumPyに限り、 A + αα + A も計算可能で、全要素にαを足した多次元配列になります。 詳しくは、 ブロードキャスト を参照ください。

行列とベクトルの積

、 としたとき、以下のように計算します。

NumPyでは @ を使います。 * は、別の計算になるので注意してください。

サンプルコード

v = numpy.array([1, -1])
A = numpy.array([[5, 2], [3, 1]])
print(A @ v)  # [3 2]
print(v @ A)  # [2 1]

行列の積

、 としたとき、以下のように計算します。

NumPyでは @ を使います。 * は、要素ごとの掛け算になるので注意してください。

サンプルコード

A = numpy.array([[1, -1], [-1, 3]])
B = numpy.array([[5, 2], [3, 1]])
print(A @ B)

出力

[[2 1]
 [4 1]]

これは、下記のように計算しています。

[[ 1*5-1*3  1*2-1*1]
 [-1*5+3*3 -1*2+3*1]]

M×L行列 とL×N行列 の積 は、M×N行列になります。たとえば、下記のように10×50行列と50×20行列の積は、10×20行列になります。

print((np.zeros((10, 50)) @ np.zeros((50, 20))).shape)  # 10, 20

連立一次方程式

、 としたとき、 となる変数 を求めることを 連立一次方程式 を解くといいます。

NumPyでは、以下のように numpy.linalg.solve を使って計算できます。

b = numpy.array([1, -1])
A = numpy.array([[5, 2], [3, 1]])
x = numpy.linalg.solve(A, b)
print(A @ x)  # [ 1. -1.]