愛伊米

這是程式設計師學數學的獨特方式

作者:Ian Rowan

翻譯:機器之心

簡潔的程式碼不僅能執行程式,還能用來學數學。

∑、∏、∈……如果你學習過數學,你一定知道這些符號的含義,而如果我們能用最喜歡的程式語言來理解它們,也許還能帶來更加透徹的領悟。近日,MindbuilderAI & nurio 創始人、機器學習專家 Ian Rowan 介紹了自己藉助程式碼來理解數學計算過程的經驗。

這是程式設計師學數學的獨特方式

對於想要在機器學習和資料科學領域創出一番事業或做出一些研究成果的人來說,終有一天會在鼓搗 Python 軟體庫的基礎上更進一步,跟隨自己的好奇心進入背後的數學領域。這通常會將你引向那些描述了各種原理的數量龐大的公開論文集。你對核心數學機制的理解越深入,你就越可能靈光閃現,成為一種新方法的創造者。在讀第一篇論文時,可能一開始一切都還很容易理解,但當你遇到下面這種公式時,你可能就會開始疑惑了:

對於學習過多年的數學或研究過機器學習的數學層面的人來說,這樣的等式可以透過精心的處理而解析為語言描述和程式碼。但對其他很多人來說,這看起來可能就像天書。事實上,這看起來就像是古代的數學領袖選擇了看起來最有意思的符號來描述相當直觀的方法。這就導致了一個結果:等式和變數看起來比實際表達的含義還要複雜得多。

我發現程式碼不僅能用來寫程式,而且還是用於解釋複雜問題的全球通用語言。當我學習資料科學背後的數學時,我總是發現理解數學的最佳方式是寫出描述這些等式的程式碼段。最終,我理解了這些符號,現在讀它們就像讀一篇普通論文一樣。我希望透過這篇文章分享一些示例,讓大家知道用程式碼描述數學竟會如此簡單!

求和與求積

在迭代數學方法中,求和符號是最有用且最常用的符號。儘管求和符號設計複雜,但實現方法卻非常簡單,而且也極其有用。

x = [1, 2, 3, 4, 5, 6]result = 0for i in range(6):

result += x[i]Output of print(result) -> 21

如前所示,這個符號表達的其實就是一個迴圈。求和符號上面的數字是這個迴圈的範圍,下面的數字是起始位置。下面的變數集會變成索引變數,每次迴圈的結果都被加起來,得到一個總和值。下面的符號則更少見一些:

這是程式設計師學數學的獨特方式

這個符號通常被稱為乘積運算元(Product Operator)。這個符號與求和符號的工作方式相似,只不過每次迴圈的結果不是相加,而是相乘。

x = [1, 2, 3, 4, 5, 1]

result = 1

for i in range(6):    result *= x[i]Output of print(result) -> 120

階乘

階乘的符號是 !,大多數計算器都有這個功能。對很多人來說,這個符號表達的含義可能很明顯和直白,但還是值得用程式碼來理解其原理。

5! 可以表示成:

result = 1for i in range(1,6):

result *= iOutput of print(result) -> 120

條件括號

條件括號的作用是基於一組條件來切換所要執行的等式。對於程式設計師來說,這其實就是簡單的 if 語句。上面的條件等式可表示為:

i = 3y = [-2, 3, 4, 1]result = 0if i in y:

result = sum(y)elif i > 0:    result = 1else:

result = 0print(result) -> 6

可以看到,等式右側括號中每一行都對應一個條件以及該條件下所要執行的路徑。我還在每個條件中增加了額外的「屬於」符號,以便提供更多見解。如前所示,我們檢查了 i 值是否在 y 列表中。如果在,則返回陣列的和。如果不在,我們則根據具體的值返回 0 和 1。

逐點乘法和笛卡爾矩陣乘法

最後,我想快速介紹幾個任何資料科學家都可以用自己最喜歡的語言庫輕鬆完成的運算——矩陣乘法。理解矩陣乘法的最簡單方式是逐點運算。這可以簡單地寫成:

注意,首要要求是每個矩陣都必須形狀一樣(即 # rows= & #Columns=)。其程式碼如下:

y = [[2,1],[4,3]]z = [[1,2],[3,4]]x = [[0,0],[0,0]]

for i in range(len(y)):    for j in range(len(y[0])):        x[i][j] = y[i][j] * z[i][j]print(x) -> [[2, 2], [12, 12]]

最後,我們來看一種典型的矩陣乘法過程,這在機器學習領域非常常用。用複雜的術語來說,這個運算的目的是求取每個主要行與每個次要列的點積。主要來說是下面的要求:假設 [#rows, #columns] → 矩陣 i x j 要求 #columns(i) == #rows(j) → 最終積的形狀為 [#rows(i), #columns(j)]

這看起來很令人困惑,我最好的建議是搜尋一下這些要求的視覺化圖片。

這是程式設計師學數學的獨特方式

這個等式的程式碼如下(使用了 numpy dot 方法):

y = [[1,2],[3,4]]z = [[2], [1]]# x has shape [2, 1]x = [[0], [0]]for i in range(len(y))    for j in range(len(z):        x[i][j] = np。dot(y[i], z[:, j])print(x) -> [[4],[10]]

本文僅給出了少量示例,但理解這些簡單程式碼能讓任何程式設計師都能踏足乍看之下難以深入的數學世界。當然,這些方法都可以合併簡化,實現更高的效率,而且通常很多軟體庫中都有現成的方法可用。用簡單程式碼寫出這些數學符號的意義在於透過寫出這些等式的真正計算過程來理解它們的含義。