從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究

人工智慧頻道發表於2018-10-09

寫一個機器學習演算法是一次非常有意義的學習經歷(https://www.dataoptimal.com/machine-learning-from-scratch/)。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


它為你提供了"啊哈!原來是這樣"的經歷感受。只有你點選它的時候,你才會明白究竟發生了什麼。

有些演算法比其他演算法複雜,所以我們從一些簡單的開始,例如單層感知器(https://en.wikipedia.org/wiki/Perceptron)。

我將向你介紹以下6步過程,從零開始編寫演算法,使用感知器作為案例研究:

1.對演算法有基本的瞭解

2.尋找不同的學習來源

3.將演算法分解為塊

4.從一個簡單的例子開始

5.使用確信的案例進行驗證

6.寫下你探索的過程

基本瞭解

這可以追溯到我最初所說的。如果你不瞭解基本知識,就不要從頭開始處理演算法。

至少,你應該能夠回答以下問題:

它是什麼?

它通常用於什麼?

我什麼時候不能用這個?

對於感知器,讓我們繼續回答以下問題:

單層感知器是最基本的神經網路。它通常用於二進位制分類問題(1或0,"是"或"否")。

一些簡單的用途可能是情緒分析(正面或負面反應)或貸款違約預測("將違約"、"不會違約")。對於這兩種情況,決策邊界都需要是線性的。

如果決策邊界是非線性的,那麼你不能使用(單層)感知器。對於非線性問題,你需要的是其他東西。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


使用不同的學習來源

在你對模型有了基本的理解之後,就該開始做你的研究了。

有些人通過書本學得更好,有些人通過視訊學得更好。

就我個人而言,我喜歡兩者合用和使用各種資源。

關於數學細節,教科書做得很好(https://www.dataoptimal.com/data-science-books-2018/),但是對於更多的實際例子,我更喜歡部落格文章和YouTube視訊。

這裡有一些很好的學習資源:

書籍方面

統計學習的要素(SEC)。4.5.1 連結:https://web.stanford.edu/~hastie/Papers/ESLII.pdf

理解機器學習:從理論到演算法(SEC)。21.4 連結:https://www.cs.huji.ac.il/~shais/UnderstandingMachineLearning/understanding-machine-learning-theory-algorithms.pdf

部落格

如何在Python中從無到有地實現感知器演算法。作者:Jason Brownlee 連結:https://machinelearningmastery.com/implement-perceptron-algorithm-scratch-python/

單層神經網路與梯度下降。作者:Sebastian Raschka 連結:https://sebastianraschka.com/Articles/2015_singlelayer_neurons.html

視訊

感知器訓練(https://www.youtube.com/watch?v=5g0TPrxKK6o)。

感知器演算法的工作原理(https://www.youtube.com/watch?v=1XkjVl-j8MM)。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


將演算法分解為塊

既然我們已經收集了我們的資料,現在是開始學習的時候了。

與其一路上閱讀文章或部落格,不如從瀏覽章節標題和其他重要資訊開始。

然後寫下要點,並試圖勾勒出演算法。

在檢視了眾多資料後,我將感知器演算法分解為以下5塊:

1.初始化權重

2.按輸入乘以權重,並將它們加起來

3.將結果與閾值進行比較以計算輸出(1或0)

4.更新權重

5.重複

讓我們把每一個細節都看一遍。

1.初始化權重

首先,我們將初始化權重向量。

權重的數量需要與特徵的數量相匹配。假設我們有三個特性,下面是權重向量的樣子

權重向量通常是用零初始化,所以我將繼續在這個例子中堅持我的理念。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


2.將權值乘以輸入,並將它們加起來。

接下來,我們將把權重乘以輸入,然後把它們加起來。

為了便於跟蹤,我在第一行中對權重和它們的相應特性進行了著色。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


在我們把權重乘以特徵後,我們把它們加起來。這也被稱為點積。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


最終結果是0。我將這個臨時結果稱為"f"。

3.與閾值比較

在計算了點積之後,我們需要將它與閾值進行比較。

我選擇了使用0作為我的閾值,但是你可以使用這個,或嘗試一些不同的數字。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


由於我們計算的點積"f"不大於我們的閾值(0),所以我們的估計等於零。

我將估計值表示為"y hat",帶有0下標,以對應於第一行。你可以用1代替第一行,但這並不重要。我只是選擇從0開始。

如果我們將這一結果與實際值進行比較,我們可以看到,我們當前的權重並沒有做出正確的預測。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


由於我們的預測是錯誤的,我們需要更新權重,這就把我們帶到了下一步。

4.更新權重

接下來,我們將更新權重。下面是我們將要使用的公式:

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


基本思想是在迭代"n"時調整當前的權重,以便在下一次迭代中使用新的權重,"n+1"。

為了調整權重,我們需要設定一個"學習速率"。這是用希臘字母"ETA"表示的。

我選擇使用0.1作為學習速率,但是你可以使用不同的數字,就像閾值一樣。

以下是我們到目前為止所做的簡要總結:

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


現在讓我們繼續計算迭代n=2的新權重。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


我們成功地完成了感知器演算法的第一次迭代。

5.重複

因為我們的演算法沒有計算出正確的輸出,所以我們需要繼續下去。

通常,我們需要多次迭代。迴圈遍歷資料集中的每一行,我們將每次更新權重。

一個完整的掃描資料集被稱為"epoch"(輪迴)。

因為我們的資料集有3行,所以我們需要三次迭代才能完成一個"epoch"。

我們可以設定總迭代次數或時間來繼續執行該演算法。也許我們需要指定30次迭代(或10次迭代)。

與閾值和學習速率一樣,epoch數(即輪迴數)是你可以使用的引數。

在下一次迭代中,我們繼續討論第二行的特性。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


我不會重複每一步,但下面是點積的新計算:

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


接下來,我們將點積與閾值進行比較,以計算一個新的估計值,更新權重,然後繼續進行。如果我們的資料是線性可分的,感知器就會收斂。

從一個簡單的例子開始

現在我們已經手工將演算法分解成塊,現在是開始在程式碼中實現它的時候了。

為了保持簡單,我總是喜歡從一個非常小的資料集開始。

這類問題的一個很好的、小的、線性可分離的資料集是NAND gate(https://en.wikipedia.org/wiki/NAND_gate)。這是數位電子學中常用的一個資料集。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


由於這是一個相當小的資料集,我們只需手動將其輸入Python。

我將新增一個虛擬特性"X0",這是一個1的列。我這樣做是為了讓我們的模型計算偏置項。

你可以將偏差看作是擷取項,它正確地允許我們的模型分離這兩個類。

以下是輸入資料的程式碼:

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


與上一節一樣,我將以塊的形式逐步完成演算法,編寫程式碼,並在我們進行測試時對其進行測試。

1.初始化權重

第一步是初始化權重。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


請記住,權重向量的長度需要匹配特徵的數量。對於這個NAND gate例子,長度是3。

2.將權值乘以輸入,並將它們加起來。

接下來,我們將把權重乘以輸入,然後把它們加起來。

它的另一個名字是"點積"。

同樣,我們可以使用Numpy輕鬆地執行此操作。我們將使用的方法是.dot()。

讓我們從權向量和第一行特徵的點積開始。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


正如預期的那樣,結果是0。

為了與前文保持一致,我將點積賦給變數f。

3.與閾值比較

在計算了點積之後,我們準備將結果與閾值進行比較,從而對輸出進行預測。

同樣,我將保持與前文一致。

我要讓臨界值z等於0。如果點積f大於0,我們的預測是1。否則,它就是0。

記住,這個預測通常是用"carat"的頂部來表示的,也被稱為"hat"。我將預測賦給的變數是"yhat"。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


正如預期的那樣,預測為0。

你會注意到,在上面的註釋中,我稱之為"啟用函式"。這是對我們正在做的事情的更正式的描述。

檢視NAND輸出的第一行,我們可以看到實際值為1。既然我們的預測是錯誤的,我們就需要繼續更新權重。

4.更新權重

既然我們已經做出了預測,我們就可以更新權重了。

我們需要設定一個學習速率才能做到這一點。為了與前面的示例保持一致,我將為學習率"ETA"賦值0.1。

我將對每個權重的更新進行編碼,以便更容易閱讀。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


我們可以看到,我們的權重現在已經更新,所以我們準備繼續前進。

5.重複

現在我們已經完成了每一步,現在是時候把所有的東西都放在一起了。

我們還沒有討論的最後一個部分是損失函式。這是我們試圖最小化的函式,在我們的例子中,這將是平方和的錯誤。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


這就是我們用來計算錯誤的地方,看看模型是如何執行的。

將所有內容結合在一起,下面是整個函式的樣子:

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


現在我們已經編寫了完整的感知器,讓我們繼續執行它:

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


看一看錯誤,我們可以看到,在第6次迭代時,錯誤變為0。對於其餘的迭代,它保持在0。

當誤差達到0並停留在那裡時,我們知道我們的模型已經收斂了。這告訴我們,我們的模型已經正確地"學習"了適當的權重。

在下一節中,我們將在更大的資料上使用計算的權重做預測。

使用確信的案例進行驗證

到目前為止,我們已經找到了不同的學習資源,手工完成了演算法,並用一個簡單的例子在程式碼中測試了它。

現在是時候將我們的結果與可信的實現進行比較了。為了比較,我們將使用scikit-learn中的感知器(http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html)。

我們將使用以下步驟完成此比較:

1.匯入資料

2.將資料分割成訓練/測試組

3.訓練我們的感知器

4.測試感知器

5.與scikit-learn中的感知器進行比較

1.匯入資料

讓我們從匯入資料開始。你可以獲得資料集連結為:https://github.com/dataoptimal/posts/blob/master/algorithms%20from%20scratch/dataset.csv 。

這是一個線性可分離的資料集,我建立它是為了確保感知器能夠工作。為了進一步的工作,讓我們繼續繪製資料。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


看一下這幅圖,很容易看出我們可以用一條直線將這些資料分開。

在我們繼續之前,我將解釋我上面的程式碼。

我使用Pandas匯入CSV,CSV自動將資料放入dataframe中。

要繪製資料,我必須從dataframe中提取值,這就是為什麼我使用".values"方法。

特性在第1和第2列中,所以我在散點圖函式中使用了這些特性。第0列是我包含的1的虛擬特性,這樣就能計算出截距。這與我們在上文中對NAND gate所做的事情一樣。

最後,我使用C=df['3'],alpha=0.8在散射圖函式中。輸出是第3列(0或1)中的資料,因此我"告訴"函式使用'3'列對這兩個類進行著色。

如果你想找到更多關於Matplotlib的散點圖函式,請點選:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html 。

2.將資料分割成訓練/測試組

現在,我們已經確認資料可以線性分離,是時候將資料拆分了。

在一個獨立的資料集上訓練一個模型,而不是你測試的資料集,這是一個很好的實踐。這有助於避免過度擬合。

做這件事有不同的方法,但是為了保持簡單,我只使用一個訓練集和一個測試集。

我將從整理我的資料開始。如果你檢視原始檔案,你將看到資料按行分組,輸出為0(第三列),然後是所有的1。我想要改變事物,增加一些隨機性,所以我現在要打亂資料。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


我首先將資料從dataframe更改為numpy陣列。這使我將要使用的許多numpy函式更容易使用,例如.shuffle(即打亂或洗牌)。

為了使結果可重複,我設定了一個隨機數種子(5)。在我們完成之後,嘗試改變隨機數種子,看看結果是如何變化的。

接下來,我將70%的資料分成訓練集,30%的資料分成測試集。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


最後一步是分離訓練和測試集的特性和輸出。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


為了這個例子,我選擇了70%的訓練集和30%的測試集,但我鼓勵你研究其他方法,例如K折交叉驗證(https://en.wikipedia.org/wiki/Cross-validation_%28statistics%29)。

3.訓練我們的感知器

接下來,我們將訓練我們的感知器。

這很簡單,我們將重用我們在前文構建的程式碼。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


讓我們繼續看一看權重與平方誤差之和。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


現在這些權值對我們來說並不重要,但是我們將在後面使用這些數字來測試我們的感知器。我們還將使用它將我們的模型與scikit-learn模型進行比較。

看一下平方誤差之和,我們可以看到我們的感知器已經收斂了,這是我們所期望的,因為資料是線性可分的。

4.測試我們的感知器

現在是時候測試我們的感知器了。為了做到這一點,我們將建造一個小的感知器測試函式。

這和我們已經看到的很相似。這個函式取我們使用perceptron_train函式計算的權值的點積,以及特徵,以及啟用函式,來進行預測。

我們唯一沒有看到的是accuracy_score。這是一個來自scikit-learn的評價度量函式。你可以在這裡瞭解更多。

把所有這些放在一起,下面是程式碼:

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


得分為1.0表明我們的模型正確地預測了所有的測試資料。這個資料集顯然是可分離的,所以我們期望這個結果。

5.與scikit-learn感知器相比

最後一步是將我們的結果與scikit-learn的感知器進行比較。下面是這個模型的程式碼:

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


現在我們已經訓練了模型,讓我們比較權重和我們的模型計算的權重。

從零開始編寫任意機器學習演算法的6個步驟:關於感知器案例的研究


scikit-learn模型中的權重與我們的相同。這意味著我們的模型工作正常,這是個好訊息。

在我們結束之前,有幾個小問題需要複習一下。在scikit-learn模型中,我們必須將隨機狀態設定為"None"並關閉洗牌。因為我們已經設定了一個隨機數種子並打亂了資料,所以我們不需要再這樣做了。

我們還必須將學習速率"eta0"設定為0.1,以與我們的模型相同。

最後一點是截距。因為我們已經包含了一個虛擬的特性列1s,我們正在自動擬合截距,所以我們不需要在scikit-learn感知器中開啟它。

這些看起來都是次要的細節,但如果我們不設定這些,我們就無法複製與我們的模型相同的結果。

這一點很重要。在使用模型之前,閱讀文件並理解所有不同設定的作用是非常重要的。

寫下你的過程

這個過程中的最後一步可能是最重要的。

你已經完成了所有的工作,包括學習、記筆記、從頭開始編寫演算法,並將其與確信的案例進行比較。不要讓前期準備白白浪費掉!

寫下這個過程很重要,原因有二:

1.你會得到更深的理解,因為你正在教導別人你剛剛學到的東西。

2.你可以向潛在僱主展示它。

證明的天賦與能力,但如果你可以自己從頭實現它,那就更令人印象深刻了。

一個展示你作品的好方法是使用GitHub頁面組合(https://www.youtube.com/watch?v=qWrcgHwSG8M)。

結語

在這篇文章中,我們學習瞭如何實現從零開始編寫機器學習演算法(https://www.dataoptimal.com/machine-learning-from-scratch/)。

更重要的是,我們學會了如何找到有用的學習資源,以及如何將演算法分解成塊。

然後,我們學習瞭如何使用較小資料集在程式碼中訓練和測試演算法。

最後,我們將模型的結果與可信的案例進行了比較。

這是一個很好的方法,我們可以在更深層次上了解、學習演算法,這樣你就可以自己實現它。

大多數情況下,你使用的演算法都是準確無誤的,但是如果你真的想更深入地瞭解幕後的情況,從頭開始學習它是一個很好的練習!


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31545819/viewspace-2215637/,如需轉載,請註明出處,否則將追究法律責任。

相關文章