『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

ベクトルの大きさと単位ベクトル

【Pythonで学ぶ線形代数学講座(2)】ベクトルの大きさと単位ベクトル

ベクトルの大きさ

スカラーには数直線上のある点 $x$ について、原点からの距離を表す 絶対値 $|x|$ が定義されています。ベクトルについても同じように、その大きさのみに着目した値を定義できます。

ユークリッドノルム

$2$ 次元ベクトル $\boldsymbol{v}=\begin{bmatrix}v_1\\v_2\end{bmatrix}$ の大きさ(長さ)は
 \[\parallel\boldsymbol{v}\parallel=\sqrt{v_1^2+v_2^2}\]
によって定義されます。一般に$n$ 次元ベクトルについても同様に、
 \[\parallel\boldsymbol{v}\parallel=\sqrt{v_1^2+v_2^2+\ \cdots\ +v_n^2}\tag{1}\]
と定義します。一般に (1) によって定義された量を ユークリッドノルム (Euclidean norm) とよびます。ユークリッドノルムは numpy.sqrt() と numpy.sum() を使って実装できます。

# numpy_vector_norm

# In[1]

import numpy as np

# ベクトルを定義
v = np.array([1, 2, 3])

# ベクトルvの大きさ(ノルム)を計算
v_n = np.sqrt(np.sum(v**2))

print(v_n)
# 3.742

scipy.linalg.norm()

scipy.linalg.norm() を使ってベクトルの大きさを計算することができます。

scipy.linalg.norm(a, ord=None, axis=None, keepdims=False)

第 1 引数 a にベクトル (1次元配列) を渡すと、ベクトルの大きさ (ユークリッドノルム) を返します。

# scipy_vector_norm

# In[1]

import numpy as np
from scipy.linalg import norm

# ベクトルを定義
v = np.array([1, 2, 3])

# ベクトルvの大きさ(ノルム)を計算
v_n = norm(v)

print(v_n)
# 3.742

第 1 引数に 2 次元配列を渡して axis で軸を指定すると、軸に沿ってノルムを計算します。たとえば、ベクトル [1 2 3] の大きさと、ベクトル [4 5 6] の大きさをまとめて計算することができます:

# In[2]

# 2次元配列を定義
a = np.array([[1, 2, 3],
              [4, 5, 6]])

# 第1軸(axis=1)に沿ってノルムを計算
a_n = norm(a, axis=1)

# 数値を丸める
a_n = np.round(a_n, 3)

print(a_n)
# [3.742 8.775]

NumPy にも numpy.linalg.norm() という関数が用意されていますが、機能は scipy.linalg.norm() とほとんど同じなので解説は割愛します。

単位ベクトル

長さ $1$ のベクトルは単位ベクトルとよばれます。
任意のベクトル $\boldsymbol{v}$ を自身の長さ $\parallel\boldsymbol{v}\parallel$ で割れば単位ベクトルとなります。
 
たとえば、$\boldsymbol{v}=\begin{bmatrix}1\\1\end{bmatrix}$ の長さは $\sqrt{1^2+1^2}=\sqrt{2}$ なので、
 \[\boldsymbol{v}=\frac{1}{\sqrt{2}}\begin{bmatrix}1\\1\end{bmatrix}\]
は単位ベクトルです。

# python_unit_vector

# In[1]

import numpy as np
from scipy.linalg import norm
np.set_printoptions(precision=3)

# ベクトルを定義
v = np.array([1, 1])

# 単位ベクトルを作成
u = v / norm(v)

print(u)
# [0.707 0.707]

複数のベクトルの大きさを $1$ に揃えることもできます。

# In[2]

# 2次元配列を定義
a = np.array([[1, 2, 3],
              [4, 5, 6]])

# 行ベクトルを正規化
a = a / norm(a, axis = 1, keepdims=True)

print("a:\n{}".format(a))

# 行ベクトルのノルムを確認
a_norm = norm(a, axis = 1, keepdims=True)

print("aの行ごとのノルム:\n{}".format(a_norm))
# a:
# [[0.267 0.535 0.802]
#  [0.456 0.57  0.684]]

# aの行ごとのノルム:
# [[1.]
#  [1.]]

コメント

  1. あとりえこばと より:

    【AI連載小説】科学とコードの交差点(61)
    「Pythonでベクトルの大きさを計算しよう」
     
    サークルのプロジェクトメンバーが、Pythonでベクトルの大きさを計算する関数を定義する場面です。
    開誠(ホワイトボードに手書きのベクトルを描きながら):「まずはベクトルの大きさを計算する関数を作ろう」
    美純:「それって、ユークリッドノルムってやつ?」
    開誠:「その通り。ベクトル $\mathbf{v}$ のユークリッドノルムは $\|\mathbf{v}\|=\sqrt{v_1^2+v_2^2+\ldots+v_n^2}$ で表される」
    明信(ノートパソコンを開いて):「では、これを関数にしてみよう」

    def calculate_vector_magnitude(vector):
        # ベクトルの各要素の2乗を計算し、合計を取る
        squared_sum = sum([component**2 for component in vector])
        
        # ルートを取ってノルムを計算
        magnitude = math.sqrt(squared_sum)
        
        return magnitude

    馬締美純(手元のノートにメモをとりながら):「なるほど、シンプルで分かりやすい関数ね」
    開誠:「これで、任意の次元のベクトルに対してユークリッドノルムを計算できる。例えば、$\mathbf{v}=[3, 4]$ の場合、$\|\mathbf{v}\|=5$ になる」
    明信:「ちょっと試してみよう」

    # ベクトルを定義
    vector_v = [3, 4]
    
    # ノルムを計算
    magnitude_v = calculate_vector_magnitude(vector_v)
    
    print(f"The magnitude of the vector {vector_v} is {magnitude_v}")
    
    # 実行結果:
    # The magnitude of the vector [3, 4] is 5.0

    開誠(満足げに):「これでベクトルの大きさを計算する関数が完成したね。これを活用して、次はプロジェクトの中でさらに高度な線形代数の実装に進んでいけそうだ」