數聚點

數聚點

Share this post

數聚點
數聚點
約維安計畫:NumPy 與矩陣運算
Copy link
Facebook
Email
Notes
More
高級約維安

約維安計畫:NumPy 與矩陣運算

第三十四週

Yao-Jen Kuo's avatar
Yao-Jen Kuo
May 29, 2023
∙ Paid
1

Share this post

數聚點
數聚點
約維安計畫:NumPy 與矩陣運算
Copy link
Facebook
Email
Notes
More
Share
black and white checkered illustration
Photo by Vlado Paunovic on Unsplash

科學計算語言的定義

在「約維安計畫:NumPy」我們認識了 NumPy 模組給予的 ndarray 資料結構,儲存同質資料的 n 維數值陣列提供了與 Python 內建資料結構截然不同的功能面向,前者專注於計算效率、後者則著重於儲存彈性。事實上 NumPy 模組被命名為 Numeric Python(or Numerical Python) 就意味著這是一個位 Python 實踐數值計算的模組,也是科學計算的入門磚,簡而言之,假使我們提出一個問題:究竟是什麼原因能夠讓 Python 從「泛用程式語言」搖身一變為「科學計算語言」呢?答案呼之欲出:NumPy 模組。

看到這裡讀者不免感到納悶,怎麼說 Python 不是「科學計算語言」呢?Python 不是數據分析、資料科學與機器學習的首選程式語言嗎?這時我們應該要探究「科學計算語言」的廣義或嚴格定義:

廣義而言,科學計算語言指的是被多數科學研究者用於計算、數學或科學程式語言,因此,C/C++ 和 Python 可以被認為是廣義的科學計算語言。

嚴格定義而言,科學計算語言是為數學公式計算以及矩陣計算而設計、優化的程式語言,這類型的語言不僅要具備能夠相關的模組與套件,還要具備數學與科學計算的語法,例如,C/C++ 和 Python 都沒有內建的矩陣資料結構類別,亦沒有內建的矩陣運算函數、運算符號,這些功能必須仰賴標準或者第三方模組與套件提供。因此在嚴格定義下 C/C++ 和 Python 並不是科學計算語言,符合嚴格定義的科學計算語言包括 ALGOL、APL、Fortran、J、Julia、Maple、MATLAB 和 R。

來源:https://en.wikipedia.org/wiki/Scientific_programming_language

如何關聯 ndarray 與數學

ndarray 資料結構類型的設計和數學對待資料維度的概念一致,在數學上我們有純量、向量、矩陣與張量分別去描述零維、一維、二維與 n 維的資料,在 ndarray 的建立上,同樣也有零維陣列、一維陣列、二維陣列與 n 維陣列,我們可以用一張示意圖來暸解資料維度:

來源:https://dev.to/juancarlospaco/tensors-for-busy-people-315k

矩陣運算

矩陣是一個由 m 列(row)n 欄(column)元素所組成的二維陣列,其中一個重要用途是解線性方程組,也常見於數值計算、統計分析與電腦科學等,在 NumPy 模組中我們就用二維的 ndarray 來建立與操作矩陣,因此像是列向量(row-vector)或者欄向量(column-vector)雖然在命名中是向量,我們仍會以外型 (1, n) 或者 (m, 1) 的二維陣列來對應,藉此確保維度的一致性。

u = np.array([5, 6, 7, 8]).reshape(-1, 1)
v = np.array([5, 6, 7, 8]).reshape(-1, 1)

ndarray 與 list 的其中一個差異處就在於元素對應運算(Element-wise),有時亦稱為向量化運算(Vectorization),我們可以讓 ndarray 和一個純量直接運算。

print(u * 5)
print(v * 6)

常見的矩陣處理技巧為轉置(Transpose),能夠將外型 (m, n) 的矩陣轉換為外型 (n, m),這樣能使得位於 m 列 n 欄的元素,更動到 n 列 m 欄的位置。我們可以使用 np.transpose() 函數或者 ndarray 的 T 屬性。

A = np.arange(1, 7).reshape(2, 3)
transpose_A = np.transpose(A)
A_T = A.T
print(A)
print(transpose_A)
print(A_T)

列向量或欄向量的「相乘運算」除了元素對應運算外還有矩陣相乘,也就是所謂的乘積運算(Dot product),相乘的前提是左側向量的欄數和右側向量的列數必須相等。

\(\vec{u} \cdot \vec{v} = \vec{u}^T \cdot \vec{v} \\ = u_1v_1 + \dots +u_nv_n\)
\(\vec{u} \cdot \vec{v} = \vec{u} \cdot \vec{v}^T = \begin{bmatrix} u_1v_1 & \dots & u_1v_n \\ \vdots & \ddots & \vdots \\ u_nv_1 & \dots & u_nv_n \end{bmatrix}\)

我們可以使用 np.dot() 函數或者 ndarray 的 dot() 方法來進行欄向量相乘。

print(np.dot(u.T, v))
print(u.dot(v.T))

同樣的道理,矩陣相乘的前提也是左側矩陣的欄數和右側矩陣的列數必須相等。

\(AB = \begin{bmatrix} a_{11}b_{11} + \dots + a_{1n}b_{n1} & \dots & a_{11}b_{1m} + \dots + a_{1n}b_{nm} \\ \vdots & \ddots & \vdots \\ a_{m1}b_{11} + \dots + a_{mn}b_{n1} & \dots & a_{m1}b_{1m} + \dots + a_{mn}b_{nm} \end{bmatrix}\)
A = np.arange(1, 7).reshape(2, 3)
B = np.arange(1, 7).reshape(3, 2)
print(A.dot(B))

利用 np.eye() 函數建立單位矩陣(Identity matrix),單位矩陣是一個方矩陣(意即列數與欄數相等),其對角線上的元素都是 1。

I_22 = np.eye(2)
I_33 = np.eye(3)
I_44 = np.eye(4)
print(I_22)
print(I_33)
print(I_44)

單位矩陣在矩陣運算中的作用與常數 1 在代數運算中的作用相似,在代數中變數與其倒數相乘可以得到常數 1,解此來求解方程式,例如在解下列代數方程式的時候我們會將等號兩邊乘上 a 的倒數來求解。

\(ax = b \)
\(x = \frac{b}{a}\)

面對矩陣代數的時候,矩陣與其反矩陣相乘可以得到單位矩陣,因此在解下列矩陣代數方程式的時候,是將等號兩邊乘上 A 的反矩陣來求解,我們可以使用 np.linalg.inv() 函數計算 A 的反矩陣。

\(Ax = B \)
\(A^{-1}Ax = A^{-1}B\)
\(x = A^{-1}B\)

以下列的線性方程組為例:

\(\begin{cases} x + 3y = 5 \\ x + 2y = 3 \end{cases}\)
A = np.array([1, 3, 1, 2]).reshape(2, 2)
B = np.array([5, 3]).reshape(2, 1)
inv_A = np.linalg.inv(A)
x = inv_A.dot(B)
print(x)

入門矩陣運算之後,我們就能夠在未來的電子報中透過 ndarray 運算認識機器學習的資料預處理與模型訓練,這週也是我第一次使用了 Substack 的 LaTex 功能,非常開心!在認識了 NumPy 與矩陣運算之後,第三十四週約維安計畫來到尾聲,希望您也和我一樣期待下一篇文章。

對於這篇文章有什麼想法呢?喜歡😻、留言🙋‍♂️或者分享🙌

約維安計畫學員專區

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2025 DATAINPOINT, INC.
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share

Copy link
Facebook
Email
Notes
More