In [12]:
%matplotlib inline
%config InlineBackend.figure_formats = {'png', 'retina'}
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib as mpl
In [7]:
import numpy as np
a = np.array([1, 1])
np.linalg.norm(a)
Out[7]:
In [8]:
a = np.array([1, 0])
b = np.array([0, 1])
c = np.array([1/np.sqrt(2), 1/np.sqrt(2)])
np.linalg.norm(a), np.linalg.norm(b), np.linalg.norm(c)
Out[8]:
In [13]:
a = np.array([1, 2])
b = np.array([2, 1])
c = a + b
plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=b, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=c, xytext=(0,0), arrowprops=dict(facecolor='black'))
plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)
plt.plot(b[0], b[1], 'ro', ms=10)
plt.plot(c[0], c[1], 'ro', ms=10)
plt.plot([a[0], c[0]], [a[1], c[1]], 'k--')
plt.plot([b[0], c[0]], [b[1], c[1]], 'k--')
plt.text(0.35, 1.15, "$a$", fontdict={"size": 18})
plt.text(1.15, 0.25, "$b$", fontdict={"size": 18})
plt.text(1.25, 1.45, "$c$", fontdict={"size": 18})
plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.4, 4.4)
plt.ylim(-0.6, 3.8)
plt.show()
두 벡터 $a$와 $b$가 이루는 각이 90도이면 서로 직교(orthogonal)라고 하며 $ a \perp b $로 표시한다.
서로 직교인 두 벡터의 벡터 내적(inner product, dot product)는 0이된다.
$ a^T b = b^T a = 0 \;\;\;\; \leftrightarrow \;\;\;\; a \perp b $
In [15]:
a = np.array([1, 1])
b = np.array([-1, 1])
np.dot(a, b)
Out[15]:
$ a^Tb = \| a \|\| b \|\cos\theta $
$ a^Tb = (a_1 + a_2)^Tb = a_1^Tb + a_2^Tb = a_2^Tb \;\; (a_1^Tb = 0,\; a_1\perp b) $
$ \| a_2 \| = a^T\dfrac{b}{\|b\|} = \dfrac{a^Tb}{\|b\|} = \dfrac{b^Ta}{\|b\|} $
In [52]:
a = np.array([1, 2])
b = np.array([2, 0])
c = np.array([1, 2])
plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='black'))
plt.annotate('', xy=b, xytext=(0,0), arrowprops=dict(facecolor='black'))
plt.plot(1, 0, 'ro', ms=10)
plt.plot([1, 1], [0, 2], 'k--')
plt.plot([1, 1.2], [0.2, 0.2], "b")
plt.plot([1.2, 1.2], [0.2, 0], "b")
plt.text(0.85, 2.05, "$a$", fontdict={"size": 18})
plt.text(1.85, -0.35, "$b$", fontdict={"size": 18})
plt.text(1.10, 0.95, "$a1$", fontdict={"size": 18})
plt.text(0.50, -0.35, "$a2$", fontdict={"size": 18})
plt.xticks(np.arange(-1, 4))
plt.yticks(np.arange(-1, 4))
plt.show()
$f(x) = w^T(x - w) = w^Tx - w^Tw = w^Tx - \| w \|^2 = w^Tx - w_0 = 0$
example :
$ w = \begin{bmatrix}1 \\ 2\end{bmatrix} ,\;\; w_0 = 5 $
$ \begin{bmatrix}1 & 2\end{bmatrix} \begin{bmatrix}x_1 \\ x_2 \end{bmatrix} - 5 = x_1 + 2x_2 - 5 = 0 $
이면 벡터 $w$가 가리키는 점 (1, 2)를 지나면서 벡터 $w$에 수직인 선을 뜻한다.
In [53]:
w = np.array([1, 2])
x1 = np.array([3, 1])
x2 = np.array([-1, 3])
w0 = 5
plt.annotate('', xy=w, xytext=(0,0), arrowprops=dict(facecolor='red'))
plt.annotate('', xy=x1, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=x2, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.plot(0, 0, 'ro', ms=10)
plt.plot(w[0], w[1], 'ro', ms=10)
plt.plot(x1[0], x1[1], 'ro', ms=10)
plt.plot(x2[0], x2[1], 'ro', ms=10)
plt.plot([-3, 5], [4, 0], 'r-', lw=5)
plt.text(0.35, 1.15, "$w$", fontdict={"size": 18})
plt.text(1.55, 0.25, "$x_1$", fontdict={"size": 18})
plt.text(-0.9, 1.40, "$x_2$", fontdict={"size": 18})
plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.7, 4.2)
plt.ylim(-0.5, 3.5)
plt.show()
직선 $ w^Tx - w_0 = 0 $ 과 이 직선 위에 있지 않은 점 $x'$의 거리는 단위 벡터 $\dfrac{w}{\|w\|}$에 대한 $x'$의 투영에서 $\|w\|$를 뺀 값의 절대값이다. 따라서 다음과 같이 정리할 수 있다.
$ \left| \dfrac{w^Tx'}{\|w\|} - \|w\| \right| = \dfrac{\left|w^Tx' - \|w\|^2 \right|}{\|w\|}= \dfrac{\left|w^Tx' - w_0 \right|}{\|w\|} $
아래 그림에서 $w \;line$과 $x'$ 사이의 거리
$ w + w1 = \dfrac{w^Tx'}{\|w\|} $
$ w = \|w\| $
$ w1 = \dfrac{w^Tx'}{\|w\|} - \|w\| = \dfrac{w^Tx' - \|w\|^2}{\|w\|} $
In [113]:
w = np.array([1, 2])
w1 = np.array([2, 4])
w0 = 5
plt.annotate('', xy=w, xytext=(0,0), arrowprops=dict(facecolor='red'))
plt.annotate('', xy=w1, xytext=(1,2), arrowprops=dict(facecolor='blue'))
plt.plot(0, 0, 'ro', ms=10)
plt.plot(w[0], w[1], 'ro', ms=10)
plt.plot(0, 5, 'bo', ms=10)
plt.plot([-3, 5], [4, 0], 'r-', lw=5)
plt.plot([-3, 5], [6.5, 2.5], 'b-', lw=5)
plt.text(0.2, 1.15, "$w$", fontdict={"size": 18})
plt.text(5.2, 0, "$w\;line$", fontdict={"size": 18})
plt.text(1, 3, "$w1$", fontdict={"size": 18})
plt.text(-0.3, 4.5, "$x'$", fontdict={"size": 18})
plt.xticks(np.arange(-2, 6))
plt.yticks(np.arange(-1, 6))
plt.xlim(-1.7, 6.2)
plt.ylim(-0.5, 5.5)
plt.show()
벡터들의 선형 조합이 0이 되는 모두 0이 아닌 스칼라값들이 존재하면 그 벡터들은 선형 종속(linearly dependent)이라고 한다.
$ a = \begin{bmatrix}1 \\ 2\end{bmatrix} ,\;\; b = \begin{bmatrix}3 \\ 3\end{bmatrix} \;\; c = \begin{bmatrix}10 \\ 14\end{bmatrix} \;\; $
$ 2a + b - \frac{1}{2}c = 0 $
벡터들의 선형 조합이 0이 되는 모두 0이 아닌 스칼라값들이 존재하지 않으면 그 벡터들은 선형 독립(linearly independent)이라고 한다.
$ \alpha_1 a_1 + \cdots + \alpha_K a_K = 0 \;\;\;\; \leftrightarrow \;\;\;\; \alpha_1 = \cdots = \alpha_K = 0 $
In [54]:
# Linearly Dependent
a = np.array([1, 2])
b = np.array([3, 3])
c = np.array([10, 14])
2*a + b - 0.5*c
Out[54]:
벡터 공간에 속하는 벡터의 집합이 선형 독립이고 다른 모든 벡터 공간의 벡터들이 그 벡터 집합의 선형 조합으로 나타나면 그 벡터 집합을 벡터 공간의 기저 벡터(basis vector)라고 한다.
예를 들어 다음과 같은 두 벡터는 2차원 벡터 공간의 기저 벡터이다.
$ a = \begin{bmatrix}1 \\ 0\end{bmatrix} ,\;\; b = \begin{bmatrix}0 \\ 1\end{bmatrix} \;\; $
또는
$ a = \begin{bmatrix}1 \\ 1\end{bmatrix} ,\;\; b = \begin{bmatrix}2 \\ 3\end{bmatrix} \;\; $
다음과 같은 두 벡터는 2차원 벡터 공간의 기저 벡터가 될 수 없다.
$ a = \begin{bmatrix}1 \\ 2\end{bmatrix} ,\;\; b = \begin{bmatrix}2 \\ 4\end{bmatrix} \;\; $
In [56]:
# Linearly Dependent : No Basis Vector
a = np.array([1, 2])
b = np.array([2, 4])
2*a - b
Out[56]:
행렬은 열 벡터의 집합으로 볼 수 있다. 이 때 열 벡터들의 조합으로 생성되는 벡터 공간을 열 공간(column space)이라고 한다.
$ A = \begin{bmatrix} 1 & 5 & 6 \\ 2 & 6 & 8 \\ 7 & 1 & 8 \end{bmatrix} \;\;\;\; \rightarrow \;\;\;\; \alpha_1 \begin{bmatrix} 1 \\ 2 \\ 7 \end{bmatrix} + \alpha_2 \begin{bmatrix} 5 \\ 6 \\ 1 \end{bmatrix} + \alpha_3 \begin{bmatrix} 6 \\ 8 \\ 8 \end{bmatrix} \; \in \; \text{column space} $
In [59]:
A = np.array([[1, 5, 6], [2, 6, 8], [3, 11, 14]])
np.linalg.matrix_rank(A)
Out[59]:
In [115]:
e1 = np.array([1, 0])
e2 = np.array([0, 1])
a = np.array([1, 2])
plt.annotate('', xy=e1, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=e2, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)
plt.text(1.05, 1.35, "$a$", fontdict={"size": 18})
plt.text(-0.2, 0.5, "$e_1$", fontdict={"size": 18})
plt.text(0.5, -0.2, "$e_2$", fontdict={"size": 18})
plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.5, 3.5)
plt.ylim(-0.5, 3)
plt.show()
새로운 기저 벡터를에 대해 벡터 투영을 계산하는 것을 좌표 변환(coordinate transform)이라고 한다.
좌표 변환은 새로운 기저 벡터로 이루어진 변환 행렬(transform matrix) $A$ 와의 내적으로 계산한다.
$$ Aa' = a $$$$ a' = A^{-1}a $$예를 들어, 기존의 기저 벡터가
$$ e_1 = \begin{bmatrix}1 \\ 0\end{bmatrix} ,\;\; e_2 = \begin{bmatrix}0 \\ 1\end{bmatrix} \;\; $$이면 벡터 $a$는 사실
$$ a = \begin{bmatrix}2 \\ 2\end{bmatrix} = 2 \begin{bmatrix}1 \\ 0\end{bmatrix} + 2 \begin{bmatrix}0 \\ 1 \end{bmatrix} = 2 e_1 + 2 e_2 $$새로운 기저 벡터가
$$ g_1 = \begin{bmatrix} \dfrac{1}{\sqrt{2}} \\ \dfrac{1}{\sqrt{2}} \end{bmatrix} ,\;\; g_2 = \begin{bmatrix} -\dfrac{1}{\sqrt{2}} \\ \dfrac{1}{\sqrt{2}} \end{bmatrix} ,\;\; $$이면 벡터 $a$의 좌표는 다음과 같이 바뀐다.
$$ a = \begin{bmatrix}2 \\ 2\end{bmatrix} \;\;\;\; \rightarrow \;\;\;\; a' = A^{-1}a = \begin{bmatrix} e'_1 & e'_2 \end{bmatrix} a = \begin{bmatrix} \dfrac{1}{\sqrt{2}} & -\dfrac{1}{\sqrt{2}} \\ \dfrac{1}{\sqrt{2}} & \dfrac{1}{\sqrt{2}} \end{bmatrix}^{-1} \begin{bmatrix}2 \\ 2\end{bmatrix} = \begin{bmatrix} \dfrac{1}{\sqrt{2}} & \dfrac{1}{\sqrt{2}} \\ -\dfrac{1}{\sqrt{2}} & \dfrac{1}{\sqrt{2}} \end{bmatrix} \begin{bmatrix}2 \\ 2\end{bmatrix} = \begin{bmatrix}2\sqrt{2}\\0\end{bmatrix} $$
In [124]:
e1 = np.array([1, 0])
e2 = np.array([0, 1])
a = np.array([2, 2])
g1 = np.array([1, 1])/np.sqrt(2)
g2 = np.array([-1, 1])/np.sqrt(2)
plt.annotate('', xy=e1, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=e2, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=g1, xytext=(0,0), arrowprops=dict(facecolor='red'))
plt.annotate('', xy=g2, xytext=(0,0), arrowprops=dict(facecolor='red'))
plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray', alpha=0.5))
plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)
plt.text(1.05, 1.35, "$a$", fontdict={"size": 18})
plt.text(-0.2, 0.5, "$e_1$", fontdict={"size": 18})
plt.text(0.5, -0.2, "$e_2$", fontdict={"size": 18})
plt.text(0.2, 0.5, "$g_1$", fontdict={"size": 18})
plt.text(-0.6, 0.2, "$g_2$", fontdict={"size": 18})
plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.5, 3.5)
plt.ylim(-0.5, 3)
plt.show()
# e1,e2 좌표계에서 g1,g2 좌표계로 변환
# a는 (2,2)에서 (2.82842712, 0)으로 변환됨
A = np.vstack([g1, g2]).T
Ainv = np.linalg.inv(A)
Ainv.dot(a)
Out[124]:
In [ ]: