我們來看一下特徵值有什麼幾何上的意義。也就是一個由矩陣 $A$ 定義出來的線性轉換, 我們由特徵值和特徵向量能不能看出對整個定義域上的點做了什麼事?
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
我們介紹個耍寶技巧, 在 Jupyter Notebook 要用希臘字母, 例如 $\alpha$ 做變數, 只要打入 (和 LaTeX 一樣):
\alpha
然後立刻按 Tab
鍵。接著當場看到 $\alpha$ 出現!
α = 3
真的可以用哦。
α*5
15
畫個圓其實就是把點點出, 再連起來, 和以前一樣! 我們用極座標找出圓的參數式會方便一點。
θ = np.linspace(0, 2*np.pi, 200)
r = 1
x = r*np.cos(θ)
y = r*np.sin(θ)
一些小細節解釋, 要顯示正圓, 我們要把 x, y 軸比例設一樣的。然後我們設定 x, y 範圍都是 -10 到 10。
ax = plt.gca()
ax.set_aspect('equal')
plt.xlim(-10,10)
plt.ylim(-10,10)
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x107dc3860>]
我們現在想要一個 eigenvalues 分別為 10, 1 的矩陣。最簡單的大概就是:
$$A = \begin{bmatrix} 10 & 0 \\ 0 & 1 \end{bmatrix}$$A = np.array([[10,0],[0,1]])
A
array([[10, 0], [ 0, 1]])
矩陣純量乘法。
3*A
array([[30, 0], [ 0, 3]])
這個其實是 array 的 broadcasting 的動作!
再來我們令一個 $B$ 矩陣, 來計算兩個矩陣相乘。
B = np.array([[1,2],[3,4]])
B
array([[1, 2], [3, 4]])
相乘其實是用 dot product 的指令! (為什麼請好好參一下)
np.dot(A,B)
array([[10, 20], [ 3, 4]])
新式的做法是
A@B
A@B
array([[10, 20], [ 3, 4]])
因為我們線性代數太常用這個動作, 所以好好解說一下。假設我們有
$$\mathbf{u} = \begin{bmatrix}1 \\ 7\end{bmatrix}$$我們要計算
$$A\mathbf{u}$$照說我應該這樣令 $\mathbf{u}$。
u = np.array([[1],[7]])
A@u
array([[10], [ 7]])
真的也是這樣, 不過其實我們可以用更簡單的手法做到, 請看:
v=np.array([1,7])
A@v
array([10, 7])
這是為什麼呢? 原因請參一下, 就記得 broadcasting 這件事。
還記得我們的 x, y 是單位圓的座標嗎? 我們的 A 會把它映到什麼呢?
xy = A@np.array([x,y])
我們來比較原本的圓, 和被 A 轉換過去的結果。我們用了 subplot
這個多圖放一起的技巧。基本上這是 copy paste 的碼, 所以看來很白痴。
plt.subplot(1,2,1)
ax = plt.gca()
ax.set_aspect('equal')
plt.xlim(-10,10)
plt.ylim(-10,10)
plt.plot(x,y)
#
plt.subplot(1,2,2)
ax = plt.gca()
ax.set_aspect('equal')
plt.xlim(-10,10)
plt.ylim(-10,10)
plt.plot(xy[0], xy[1])
[<matplotlib.lines.Line2D at 0x107eb26d8>]
我們在數據分析, 如果有資料 $(x,y)$, 兩個變數都是由標準常態分布來的。
x = np.random.randn(100)
y = np.random.randn(100)
plt.scatter(x,y)
<matplotlib.collections.PathCollection at 0x107a0a358>
是否可以看一下剛剛的 A 對這資料的影響?
xy = A@np.array([x,y])
plt.subplot(1,2,1)
ax = plt.gca()
ax.set_aspect('equal')
plt.xlim(-10,10)
plt.ylim(-10,10)
plt.scatter(x,y)
#
plt.subplot(1,2,2)
ax = plt.gca()
ax.set_aspect('equal')
plt.xlim(-10,10)
plt.ylim(-10,10)
plt.scatter(xy[0], xy[1])
<matplotlib.collections.PathCollection at 0x107b50160>
假設右邊的才是我們的數據, 我們會發現 x (eigenvalue 大的那個方向) 是重點方向。也就是如果我們需要減少一個變數, 保留 x 會是比較好的。
本節純耍寶...
r = 1-np.sin(θ)
x = r*np.cos(θ)
y = r*np.sin(θ)
plt.plot(x,y,'r')
[<matplotlib.lines.Line2D at 0x108057780>]