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

必ずしも必要ではありませんが,独学がどうしても苦手で,いつもどこかで詰まってしまったり,勉強が続かない方はプログラミングスクールへ登録して,わからないことがあったらすぐに人に質問をできる環境で勉強するという手もあります.

Tech Academyは時間がない方でもオンラインで完結する受講携帯で質問もできます.

手っ取り早く短期間で集中してPythonを勉強したい方はプログラミングスクールも考えてみてはいかがでしょうか.

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