中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

僅需六步,從零實現(xiàn)機器學習算法!

2018-11-16    來源:raincent

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

本文以感知器為例,介紹了從零實現(xiàn)機器學習方法的具體步驟以及重要性。

 

 

從頭開始寫機器學習算法能夠獲得很多經(jīng)驗。當你最終完成時,你會驚喜萬分,而且你明白這背后究竟發(fā)生了什么。

有些算法比較復(fù)雜,我們不從簡單的算法開始,而是要從非常簡單的算法開始,比如單層感知器。

本文以感知器為例,通過以下 6 個步驟引導(dǎo)你從頭開始寫算法:

♦ 對算法有基本的了解

♦ 找到不同的學習資源

♦ 將算法分解成塊

♦ 從簡單的例子開始

♦ 用可信的實現(xiàn)進行驗證

♦ 寫下你的過程

基本了解

不了解基礎(chǔ)知識,就無法從頭開始處理算法。至少,你要能回答下列問題:

♦ 它是什么?

♦ 它一般用在什么地方?

♦ 什么時候不能用它?

就感知器而言,這些問題的答案如下:

♦ 單層感知器是最基礎(chǔ)的神經(jīng)網(wǎng)絡(luò),一般用于二分類問題(1 或 0,「是」或「否」)。

♦ 它可以應(yīng)用在一些簡單的地方,比如情感分析(積極反應(yīng)或消極反應(yīng))、貸款違約預(yù)測(「會違約」,「不會違約」)。在這兩種情況中,決策邊界都是線性的。

♦ 當決策邊界是非線性的時候不能使用感知器,要用不同的方法。

 

 

借助不同的學習資源

在對模型有了基本了解之后,就可以開始研究了。有人用教科書學得更好,而有人用視頻學得更好。就我而言,我喜歡到處轉(zhuǎn)轉(zhuǎn),用各種各樣的資源學習。

如果是學數(shù)學細節(jié)的話,書的效果很好(參見:https://www.dataoptimal.com/data-science-books-2018/),但對于更實際的例子,我更推薦博客和 YouTube 視頻。

以下列舉了一些關(guān)于感知器不錯的資源:

《統(tǒng)計學習基礎(chǔ)》(The Elements of Statistical Learning),第 4.5.1 節(jié)(https://web.stanford.edu/~hastie/Papers/ESLII.pdf)

《深入理解機器學習:從原理到算法》,第 21.4 節(jié)(https://www.cs.huji.ac.il/~shais/UnderstandingMachineLearning/understanding-machine-learning-theory-algorithms.pdf)

博客

Jason Brownlee 寫的《如何用 Python 從零開始實現(xiàn)感知器算法》(https://machinelearningmastery.com/implement-perceptron-algorithm-scratch-python/)

Sebastian Raschka 寫的《單層神經(jīng)網(wǎng)絡(luò)和梯度下降》(https://sebastianraschka.com/Articles/2015_singlelayer_neurons.html)

視頻

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

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

將算法分解成塊

現(xiàn)在我們已經(jīng)收集好了資料,是時候開始學習了。與其從頭讀一個章節(jié)或者一篇博客,不如先瀏覽章節(jié)標題和其他重要信息。寫下要點,并試著概述算法。

在看過這些資料之后,我將感知器分成下列 5 個模塊:

♦ 初始化權(quán)重

♦ 將輸入和權(quán)重相乘之后再求和

♦ 比較上述結(jié)果和閾值,計算輸出(1 或 0)

♦ 更新權(quán)重

♦ 重復(fù)

接下來我們詳細敘述每一個模塊的內(nèi)容。

1. 初始化權(quán)重

首先,我們要初始化權(quán)重向量。

權(quán)重數(shù)量要和特征數(shù)量相同。假設(shè)我們有三個特征,權(quán)重向量如下圖所示。權(quán)重向量一般會初始化為 0,此例中將一直采用該初始化值。

 

 

2. 輸入和權(quán)重相乘再求和

接下來,我們就要將輸入和權(quán)重相乘,再對其求和。為了更易于理解,我給第一行中的權(quán)重及其對應(yīng)特征涂上了顏色。

 

 

在我們將特征和權(quán)重相乘之后,對乘積求和。一般將其稱為點積。

 

 

最終結(jié)果是 0,此時用「f」表示這個暫時的結(jié)果。

3. 和閾值比較

計算出點積后,我們要將它和閾值進行比較。我將閾值定為 0,你可以用這個閾值,也可以試一下其他值。

 

 

由于之前計算出的點積「f」為 0,不比閾值 0 大,因此估計值也等于 0。

將估計值標記為「y hat」,y hat 的下標 0 對應(yīng)的是第一行。當然你也可以用 1 表示第一行,這無關(guān)緊要,我選擇從 0 開始。

如果將這個結(jié)果和真值比較的話,可以看出我們當前的權(quán)重沒有正確地預(yù)測出真實的輸出。

 

由于我們的預(yù)測錯了,因此要更新權(quán)重,這就要進行下一步了。

 

4. 更新權(quán)重

我們要用到下面的等式:

 

 

基本思想是在迭代「n」時調(diào)整當前權(quán)重,這樣我們將在下一次迭代「n+1」時得到新權(quán)重。

為了調(diào)整權(quán)重,我們需要設(shè)定「學習率」,用希臘字母「eta(η)」標記。我將學習率設(shè)為 0.1,當然就像閾值一樣,你也可以用不同的數(shù)值。

目前本教程主要介紹了:

 

 

現(xiàn)在我們要繼續(xù)計算迭代 n=2 時的新權(quán)重了。

 

 

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

5. 重復(fù)

由于我們的算法沒能計算出正確的輸出,因此還要繼續(xù)。

一般需要進行大量的迭代。遍歷數(shù)據(jù)集中的每一行,每一次迭代都要更新權(quán)重。一般將完整遍歷一次數(shù)據(jù)集稱為一個「epoch」。

我們的數(shù)據(jù)集有 3 行,因此如果要完成 1 個 epoch 需要經(jīng)歷 3 次迭代。我們也可以設(shè)置迭代總數(shù)或 epoch 數(shù)來執(zhí)行算法,比如指定 30 次迭代(或 10 個 epoch)。與閾值和學習率一樣,epoch 也是可以隨意使用的參數(shù)。

在下一次迭代中,我們將使用第二行特征。

 

 

此處不再重復(fù)計算過程,下圖給出了下一個點積的計算:

 

 

接著就可以比較該點積和閾值來計算新的估計值、更新權(quán)重,然后再繼續(xù)。如果我們的數(shù)據(jù)是線性可分的,那么感知器最終將會收斂。

從簡單的例子開始

我們已經(jīng)將算法分解成塊了,接下來就可以開始用代碼實現(xiàn)它了。

簡單起見,我一般會以非常小的「玩具數(shù)據(jù)集」開始。對這類問題而言,有一個很好的小型線性可分數(shù)據(jù)集,它就是與非門(NAND gate)。這是數(shù)字電路中一種常見的邏輯門。

 

 

由于這個數(shù)據(jù)集很小,我們可以手動將其輸入到 Python 中。我添加了一列值為 1 的虛擬特征(dummy feature)「x0」,這樣模型就可以計算偏置項了。你可以將偏置項視為可以促使模型正確分類的截距項。

以下是輸入數(shù)據(jù)的代碼:

與前面的章節(jié)一樣,我將逐步完成算法、編寫代碼并對其進行測試。

1. 初始化權(quán)重

第一步是初始化權(quán)重。

注意權(quán)重向量的長度要和特征長度相匹配。以 NAND 門為例,它的長度是 3。

2. 將權(quán)重和輸入相乘并對其求和

我們可以用 Numpy 輕松執(zhí)行該運算,要用的方法是 .dot()。

從權(quán)重向量和第一行特征的點積開始。

如我們所料,結(jié)果是 0。為了與前面的筆記保持連貫性,設(shè)點積為變量「f」。

3. 與閾值相比較

為了與前文保持連貫,將閾值「z」設(shè)為 0。若點積「f」大于 0,則預(yù)測值為 1,否則,預(yù)測值為 0。將預(yù)測值設(shè)為變量 yhat。

正如我們所料,預(yù)測值是 0。

你可能注意到了在上文代碼的注釋中,這一步被稱為「激活函數(shù)」。這是對這部分內(nèi)容的更正式的描述。

從 NAND 輸出的第一行可以看到實際值是 1。由于預(yù)測值是錯的,因此需要繼續(xù)更新權(quán)重。

4. 更新權(quán)重

現(xiàn)在已經(jīng)做出了預(yù)測,我們準備更新權(quán)重。

要像前文那樣設(shè)置學習率。為與前文保持一致,將學習率 η 的值設(shè)為 0.1。為了便于閱讀,我將對每次權(quán)重的更新進行硬編碼。

權(quán)重更新完成。

5. 重復(fù)

現(xiàn)在我們完成了每一個步驟,接下來就可以把它們組合在一起了。

我們尚未討論的最后一步是損失函數(shù),我們需要將其最小化,它在本例中是誤差項平方和。

 

 

我們要用它來計算誤差,然后看模型的性能。

把它們都放在一起,就是完整的函數(shù):

 

 

現(xiàn)在已經(jīng)編寫了完整的感知器代碼,接著是運行代碼:

 

 

我們可以看到,第 6 次迭代時誤差趨近于 0,且在剩余迭代中誤差一直是 0。當誤差趨近于 0 并保持為 0 時,模型就收斂了。這告訴我們模型已經(jīng)正確「學習」了適當?shù)臋?quán)重。

下一部分,我們將用計算好的權(quán)重在更大的數(shù)據(jù)集上進行預(yù)測。

用可信的實現(xiàn)進行驗證

到目前為止,我們已經(jīng)找到了不同的學習資源、手動完成了算法,并用簡單的例子測試了算法。

現(xiàn)在要用可信的實現(xiàn)和我們的模型進行比較了。我們使用的是 scikit-learn 中的感知器(http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html)。

我們將按照以下幾步進行比較:

♦ 導(dǎo)入數(shù)據(jù)

♦ 將數(shù)據(jù)分割為訓練集和測試集

♦ 訓練感知器

♦ 測試感知器

♦ 和 scikit-learn 感知器進行比較

1. 導(dǎo)入數(shù)據(jù)

首先導(dǎo)入數(shù)據(jù)。你可以在這里(https://github.com/dataoptimal/posts/blob/master/algorithms from scratch/dataset.csv)得到數(shù)據(jù)集的副本。這是我創(chuàng)建的線性可分數(shù)據(jù)集,確保感知器可以起作用。為了確認,我們還將數(shù)據(jù)繪制成圖。

從圖中很容易看出來,我們可以用一條直線將數(shù)據(jù)分開。

 

 

在繼續(xù)之前,我先解釋一下繪圖的代碼。我用 Pandas 導(dǎo)入 csv,它可以自動將數(shù)據(jù)放入 DataFrame 中。為了繪制數(shù)據(jù),我要將值從 DataFrame 中取出來,因此我用了 .values 方法。特征在第一列和第二列,因此我在散點圖函數(shù)中用了這些特征。第 0 列是值為 1 的虛擬特征,這樣就能計算截距。這與上一節(jié)中的 NAND 門操作相似。最后,在散點圖函數(shù)中令 c = df['3'], alpha = 0.8 為兩個類著色。輸出是第三列數(shù)據(jù)(0 或 1),所以我告訴函數(shù)用列「3」給這兩個類著色。

你可以在此處(https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html)找到更多關(guān)于 Matplotlib 散點圖函數(shù)的信息。

2. 將數(shù)據(jù)分割成訓練集 / 測試集

現(xiàn)在我們已經(jīng)確定數(shù)據(jù)可線性分割,那么是時候分割數(shù)據(jù)了。

在與測試集不同的數(shù)據(jù)集上訓練模型是很好的做法,這有助于避免過擬合。還有不同的方法,但是簡單起見,我要用一個訓練集和一個測試集。首先打亂數(shù)據(jù)。

先將數(shù)據(jù)從 DataFrame 變?yōu)?numpy 數(shù)組。這樣就可以更容易地使用 numpy 函數(shù)了,比如 .shuffle。為了結(jié)果的可重復(fù)性,我設(shè)置了隨機種子 (5)。完成后,我試著改變隨機種子,并觀察結(jié)果會產(chǎn)生怎樣的變化。接下來,我將 70% 的數(shù)據(jù)分為訓練集,將 30% 的數(shù)據(jù)作為測試集。

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

我在這個例子中將 70% 的數(shù)據(jù)作為訓練集,將 30% 的數(shù)據(jù)作為測試集,你們可以研究 k 折交叉驗證等其他方法。

3. 訓練感知器

我們可以重復(fù)使用之前的章節(jié)中構(gòu)建的代碼。

 

 

接下來看權(quán)重和誤差項平方和。

 

 

現(xiàn)在權(quán)重對我們來說意義不大了,但是我們在測試感知器時還要再使用這些數(shù)值,以及用這些權(quán)重比較我們的模型和 scikit-learn 的模型。

根據(jù)誤差項平方和可以看出,感知器已經(jīng)收斂了,這是我們預(yù)料中的結(jié)果,因為數(shù)據(jù)是線性可分的。

4. 測試感知器

現(xiàn)在是時候測試感知器了。我們要建立一個小的 perceptron_test 函數(shù)來測試模型。與前文類似,這個函數(shù)取我們之前用 perceptron_train 函數(shù)和特征計算出的權(quán)重的點積以及激活函數(shù)進行預(yù)測。之前唯一沒見過的只有 accuracy_score,這是 scikit-learn 中的評估指標函數(shù)。

將所有的這些放在一起,代碼如下:

 

 

得分為 1.0 表示我們的模型在所有的測試數(shù)據(jù)上都做出了正確的預(yù)測。因為數(shù)據(jù)集明顯是可分的,所以結(jié)果正如我們所料。

5. 和 scikit-learn 感知器進行比較

最后一步是將我們的感知器和 scikit-learn 的感知器進行比較。下面的代碼是 scikit-learn 感知器的代碼:

現(xiàn)在我們已經(jīng)訓練了模型,接下來要比較這個模型的權(quán)重和我們的模型計算出來的權(quán)重。

scikit-learn 模型中的權(quán)重和我們模型的權(quán)重完全相同。這意味著我們的模型可以正確地工作,這是個好消息。

在結(jié)束之前還有一些小問題。在 scikit-learn 模型中,我們將隨機狀態(tài)設(shè)置為「None」而且沒有打亂數(shù)據(jù)。這是因為我們已經(jīng)設(shè)置了隨機種子,而且已經(jīng)打亂過數(shù)據(jù),不用再做一次。還需要將學習率 eta0 設(shè)置為 0.1,和我們的模型相同。最后一點是截距。因為我們已經(jīng)設(shè)置了值為 1 的虛擬特征列,因此模型可以自動擬合截距,所以不必在 scikit-learn 感知器中打開它。

這些看似都是小細節(jié),但是如果不設(shè)置它們的話,我們的模型就無法重復(fù)得到相同的結(jié)果。這是重點。在使用模型之前,閱讀文檔并了解不同的設(shè)置有什么作用非常重要。

寫下你的過程

這是該過程的最后一步,可能也是最重要的一步。

你剛剛經(jīng)歷了學習、做筆記、從頭開始寫算法以及用可信實現(xiàn)進行比較的流程。不要浪費這些努力!

寫下過程原因有二:

你要更深刻地理解這個過程,因為你還要將你學到的東西教給別人。

你要向潛在雇主展示這個過程。

從機器學習庫中實現(xiàn)算法是一回事,從頭開始實現(xiàn)算法是另一回事,它會給人留下深刻印象。

GitHub 個人資料是展示你所做工作的一種很好的方法。

總結(jié)

本文介紹了如何從零開始實現(xiàn)感知器。這是一種在更深層次上學習算法的好方法,而你還可以自己實現(xiàn)它。你在大多數(shù)情況下用的都是可信的實現(xiàn),但是如果你真的想要更深入地了解背后發(fā)生了什么,從頭實現(xiàn)算法是很好的練習。

原文鏈接:https://www.dataoptimal.com/machine-learning-from-scratch/

標簽: b2c 代碼 網(wǎng)絡(luò)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:最新任務(wù)型對話數(shù)據(jù)集大全

下一篇:2018年雙11天貓成交2135億元,比去年多了453億