「ベクトル・行列からはじめる最適化数学」でお勉強 -Vol.1-

Pythonを理解して使いこなせているわけではなく、膨大なライブラリをある程度覚えることやオブジェクト指向の理解など、まだまだ課題はあり相変わらず地道に勉強を続けているところだが、私がPythonを勉強する気になったキッカケとなった「機械学習」「統計分析」についてそろそろ勉強してみたいと思った。

そんで現在所属させて頂いているコミュニティのメンバーさんにご紹介された本[ベクトル・行列からはじめる最適化数学](https://amzn.to/3F09pRp)を使って勉強を進めていこうと思う。

私、学生の頃も真面目に勉強した試しがないので、こちらに記載している事に関しては一切責任は持てないのでご留意を。

# ベクトルとは

> ベクトル（vector）は有限個数の数値を並べた順序付きのリストである。
>> 引用：[ベクトル・行列からはじめる最適化数学](https://amzn.to/3F09pRp)

ベクトルの定義はこんな感じだそう。ちなみに、同じ次元のベクトルを複数並べたものが行列っていう記事をどこかで読んだ気がする。ベクトルや行列は丸かっこや角かっこで囲むのが一般的だそう。

```math
\begin{bmatrix}-1.1 \\ 0.0 \\3.6 \\ -7.2\end{bmatrix} または \begin{pmatrix}-1.1 \\ 0.0 \\3.6 \\ -7.2\end{pmatrix}
```

または上のベクトルは数値をカンマで区切って並べ、丸かっこで囲む書き方もあるようだ。

```math
(-1.1, 0.0, 3.6, -7.2)
```

# ベクトル・行列の積の結果
## 行列と縦ベクトルの積：ベクトル
行列と縦ベクトルの積は縦ベクトルになる。

```math
\begin{pmatrix} a_{ 11 }  & a_{ 12 }\\a_{ 21 }&a_{ 22 }\end{pmatrix}\begin{pmatrix} b_{ 1 }  \\ b_{ 2 }\end{pmatrix}=\begin{pmatrix} a_{ 11 }b_{1}  + a_{ 12 }b_{2}\\a_{ 21 }b_{1}+a_{ 22 }b_{2}\end{pmatrix}
```

## 行列と縦ベクトルの積：ベクトル
横ベクトルと行列の積は横ベクトルになる。

```math
\begin{pmatrix} a_{ 1 } & a_{ 2 }\end{pmatrix}\begin{pmatrix} b_{ 11 }  & b_{ 12 }\\b_{ 21 }&b_{ 22 }\end{pmatrix}=\begin{pmatrix} a_{1}b_{11}  + a_{2}b_{21}&a_{1}b_{12}+a_{2 }b_{22}\end{pmatrix}
```

## 横ベクトルと縦ベクトルの積：スカラー
横ベクトルと縦ベクトルの積はスカラーになる。

```math
\begin{pmatrix} a_{ 1 } & a_{ 2 }\end{pmatrix}\begin{pmatrix} b_{ 1 }\\b_{ 2 }\end{pmatrix}=\begin{pmatrix} a_{1}b_{1}  + a_{2}b_{2}\end{pmatrix}
```

## 縦ベクトルと横ベクトルの積：行列
縦ベクトルと横ベクトルの積は行列になる。

```math
\begin{pmatrix} a_{ 1 }\\a_{ 2 }\end{pmatrix}\begin{pmatrix} b_{ 1 } & b_{ 2 }\end{pmatrix}=\begin{pmatrix} a_{1}b_{1}  + a_{1}b_{2}\\a_{2}b_{1}+a_{2}b_{2}\end{pmatrix}
```

横ベクトル×縦ベクトル」なのか、「縦ベクトル×横ベクトル」なのかで結果が変わってくるので注意する。

# ベクトルをPythonで表現する
Numpyを使って、ベクトル・行列を表現したり、計算したりする。まずは、ベクトルから。
```math
\begin{pmatrix} 1 & 2 & 3\end{pmatrix}
```

上の横ベクトルをNumpyを使って表現する。

```python:matrix.py
import numpy as np


a_1d = np.array([[1,2,3]])

print(type(a_1d))
# 出力：<class 'numpy.ndarray'>
print(a_1d)
# 出力：[[1 2 3]]
print(a_1d.shape)
# 出力：(1, 3) ← 列要素:1,行要素:3
print(a_1d.ndim)
# 出力：2 ← 2次元配列の2を取得
```

次は縦ベクトル

```math
\begin{pmatrix} 1 \\ 2 \\ 3\end{pmatrix}
```

上の縦ベクトルをNumpyで表現

```python:matrix.py
import numpy as np


a_1d = np.array([[1],[2],[3]])

print(type(a_1d))
# 出力：<class 'numpy.ndarray'>
print(a_1d)
# 出力：[[1]
#       [2]
#       [3]]
print(a_1d.shape)
# 出力：(3, 1) ← 列要素:3,行要素:1
print(a_1d.ndim)
# 出力：2 ← 2次元配列の2を取得
```

上を参考に、2次元配列

```math
\begin{pmatrix} 1 & 2 \\ 3 & 4\end{pmatrix}
```

の表現をNumpyでやってみる。

```python:matrix.py
import numpy as np


a_2d = np.array([[1,2],[3,4]])
# reshapeメソッドを使って、変換する
a_col = a_2d.reshape(2, 2)

print(a_2d)
# 出力:[[1 2]
#      [3 4]]

print(a_2d.shape)
# 出力:(2, 2) ← 列要素:2,行要素:2

print(a_2d.ndim)
# 2 ← 2次元配列の2を取得
```

OK。

# ベクトル・行列の積を求めてみる
## 行列と縦ベクトルの積：ベクトル

```math
A=\begin{pmatrix}1&2\\3&4\end{pmatrix},B=\begin{pmatrix} 1\\2\end{pmatrix}とするときの積AB
```

```python:matrix.py
import numpy as np


A = np.array([[1,2],[3,4]])
B = np.array([[1],[2]])

# AとBの積を求めて出力する
print(A@B)

# 出力：[[ 5]
        [11]]
```
実際に計算するとこんな感じ。

```math
\begin{pmatrix}1\times1 + 2\times2\\3\times1 + 4\times2\end{pmatrix}=\begin{pmatrix}5\\11\end{pmatrix}
```

## 行列と縦ベクトルの積：ベクトル

```math
A=\begin{pmatrix} 1&2\end{pmatrix},B=\begin{pmatrix}1&2\\3&4\end{pmatrix}とするときのAとBの積
```

```python:matrix.py
import numpy as np


A = np.array([1,2])
B = np.array([[1,2],[3,4]])

# AとBの積を求めて出力する
print(np.dot(A, B))

# 出力：[ 7 10]
```

実際に計算してみると下の結果になる。

```math
\begin{pmatrix}1\times1 + 2\times3&1\times2 + 2\times4\end{pmatrix}=\begin{pmatrix}7&10\end{pmatrix}
```

ちょっと分かってきたかも。

# 活用分野
もちろん機械学習の基礎ともなるようだが、ゲームなどの物体移動の計算や画像処理などにも活用されているとのこと。とりあえずこれだけではあまりピンとこないので、もっと勉強をすすめる必要がありそう。

# まとめ
久しぶりに勉強してみると、なんか楽しい。学生の時はあんなに嫌だった勉強なのに。今後も自分の記録用として残していけたらと考えている。
もし間違っている所があれば修正依頼をお願いいたします。