機械学習のための0からのPython入門~numpyの基本と行列・ベクトルの計算~

どうも~むるむるです~

この記事では数値計算によく使われるPythonのライブラリであるnumpyについての基本と,numpyを使ったベクトル・行列の計算を解説していきたいと思います.

機械学習をPythonで実装したいならnumpyはまず間違いなく使うことになります.この記事でしっかりと基礎を抑えてしまいましょう.

numpyの基本

numpyは外部ライブラリですが,Anacondaを使っている方であれば最初からインストールされているはzなので,インストールをする必要はありません.

インストールする方は...

pipを使う場合:
pip install numpy
condaを使う場合:
conda install numpy

では早速numpyを使っていきましょう.numpyを使うにはまず,ライブラリをインポートする必要があります.「np」と略してインポートするのが一般的です.

import numpy as np
np.array([1, 2])

上ではnp.array( )関数にリストを渡すことで1次元のベクトルを作りました.クラスがどうなっているか調べてみましょう.

x = np.array([1, 2])
print(type(x))
'''
出力結果:
<class 'numpy.ndarray'>
'''

type関数でクラスを確認したところ「numpy.ndarray」クラスであることがわかりました.numpyのndarrayは名前の「n-d array」が示す通り多次元(n dimensional array)のデータを扱うためのクラスです.

数学の用語を使えば,1次元のときベクトル,2次元のとき行列,3次元のときテンソルとなります.

例えば二次元のデータ(行列)は以下のようにして作ることができます.

x = np.array([[1, 2], [3, 4]])
print(x)
print('---')
print(x.shape)
'''
出力結果:
[[1 2]
 [3 4]]
---
(2, 2)
'''

「ndarray.shape」とすることで,各次元ごとの要素数を確認することができます.上のコードでは「x」は2×2行列の行列となっています.

numpyでベクトルの計算

要素同士の四則演算

まず手始めにnumpyでベクトルの要素同士の四則演算をしていきましょう.

vec1 = np.array([1,2,3])
vec2 = np.array([4,5,6])
print(vec1 + vec2)
print(vec2 - vec1)
print(vec1 * vec2)
print(vec2 / vec1)
'''
出力結果:
[5 7 9]
[3 3 3]
[ 4 10 18]
[4.  2.5 2. ]
'''

以上のように,要素数が同じndarray同士に「+, -, *, /」を使うと要素同士の四則演算になります.要素数が違う以下のような場合はエラーが出ます.

vec1 = np.array([1,2,3])
vec2 = np.array([4,5,6,7])
print(vec1 + vec2)
print(vec2 - vec1)
print(vec1 * vec2)
print(vec2 / vec1)
'''
エラー
'''

ちなみにスカラーとの演算は,すべての要素に対象のスカラーを計算した結果が得られます.

vec1 = np.array([1,2,3])
print(vec1 + 2)
print(vec1 - 2)
print(vec1 * 2)
print(vec1 / 2)
'''
出力結果:
[3 4 5]
[-1  0  1]
[2 4 6]
[0.5 1.  1.5]
'''

内積とノルム

ベクトルの内積を求めたい場合はnp.dot( )を,ノルムを求めたい場合はnp.linalg.norm( )を使って求めることができます.

vec1 = np.array([1,2,3])
vec2 = np.array([4,5,6])
print(np.dot(vec1, vec2))# 内積
print(np.linalg.norm(vec1, ord=2))# L2ノルム
'''
出力結果:
32
3.7416573867739413
'''

numpyで行列の計算

要素同士の計算,アダマール積

ベクトルの時と同様,同じ次元,同じ要素数の行列の要素同士の計算は以下のようにしてできます.

mat1 = np.array([[1, 2],[3, 4]])
mat2 = np.array([[5, 6], [7, 8]])
print(mat1 + mat2)
print('---')
print(mat2 - mat1)
print('---')
print(mat1 * mat2)
print('---')
print(mat2 / mat1)
'''
出力結果:
[[ 6  8]
 [10 12]]
---
[[4 4]
 [4 4]]
---
[[ 5 12]
 [21 32]]
---
[[5.         3.        ]
 [2.33333333 2.        ]]
'''

ベクトルの要素同士の積にはアダマール積という名前がついています.

スカラーとの四則演算はベクトルの時と同様,すべての要素にスカラーの値が計算されます

mat1 = np.array([[1, 2],[3, 4]])
print(mat1 + 2)
print('---')
print(mat1 - 2)
print('---')
print(mat1 * 2)
print('---')
print(mat1 / 2)
'''
出力結果:
[[3 4]
 [5 6]]
---
[[-1  0]
 [ 1  2]]
---
[[2 4]
 [6 8]]
---
[[0.5 1. ]
 [1.5 2. ]]
'''

行列の要素へアクセス

ndarrayの要素を抜き出したいときは[ ]を使って,抜き出す要素を指定できます.要素の番号の数え方はリストなどのときと同様0から数えるので注意が必要です.

[n, m]でn行目m列目の要素へアクセスできます.

[:, n]でn番目の列,[n, :]でn番目の行を抜き出すこともできます.

また「n:m」とすることで,n番目からm-1番目の要素を抜き出すことができます.

以下の例を見た方がわかりやすいかもしれません.

A = np.array([[1, 2, 3, 4],[5, 6, 7, 8]])
print(A[0, 0])# 0列0行目の要素
print(A[:, 0])# 列0
print(A[0, :])# 行0
print(A[0, 1:3])# 行0の1番目から(3-1)番目の要素を抜き出す
'''
出力結果:
1
[1 5]
[1 2 3 4]
[2 3]
'''

行列の内積

行列の内積もベクトルの時と同様,np.dot( )でできます.

mat1 = np.array([[1, 2],[3, 4]])
mat2 = np.array([[5, 6], [7, 8]])
print(np.dot(mat1, mat2))
'''
出力結果:
[[19 22]
 [43 50]]
'''

逆行列

逆行列はnp.linalg.inv( )を使って計算できます.以下の例では行列「A」とその逆行列「Ainv」の内積を取って単位行列となっているのが確認できます.対角要素は1で非対角要素は数値計算上ぴったり0にはなっていませんが,10 の―16乗とほぼ0に近い数字になっています.

A = np.array([[1, 2],[3, 4]])
Ainv = np.linalg.inv(A)
print(np.dot(A, Ainv))
'''
出力結果:
[[1.00000000e+00 1.11022302e-16]
 [0.00000000e+00 1.00000000e+00]]
'''

行列の固有値・固有ベクトル

np.linalg.eig( ) で固有値・固有ベクトルを求めることができます.一つ目のarrayが固有値のリスト.二つ目のarrayが対応する固有ベクトルです.

以下の場合固有ベクトルが「9」と「4」.固有値「9」に対応する固有ベクトルが「0.70710678,0.70710678」で固有値「4」に対応する固有ベクトルが「-0.24253563,0.9701425」となっています.

A = np.array([[8, 1],[4, 5]])
print(np.linalg.eig(A))
'''
出力結果:
(array([9., 4.]),
 array([[ 0.70710678, -0.24253563],
        [ 0.70710678,  0.9701425 ]]))
'''

行列の転置

行列の転置はndarray.transpose()とやるだけです.

A = np.array([[1, 2],[3, 4]])
At = A.transpose()
print(A)
print('===')
print(At)
'''
出力結果:
[[1 2]
 [3 4]]
===
[[1 3]
 [2 4]]
'''

確認クイズ

クイズ1

内積と要素同士の積(アダマール積)の違いを以下のコードで確認しましょう.どっちが内積でどっちが要素同士の積ですか?

A = np.array([[1, 1, -1],[-2, 0, 1], [0, 2, 1]])
B = np.array([[0, 1, 2],[-3, -2, 0], [1, 1, 1]])
print(np.dot(A,B))
print(A*B)

クイズ2

以下の行列Aの逆行列,転置を求めてみましょう.

A = np.array([[1, 1, -1],[-2, 0, 1], [0, 2, 1]])

次回

次回は「numpy:よく使う機能まとめ」について学習します.

次の記事はこちら.

機械学習のためにしっかりとPythonを勉強したいなら,ある程度の基礎を身に着けた後に下の本を読むのがお勧めです.この本をこなせば,より高いレベルへ到達できるでしょう.

最新情報をチェックしよう!