僅需六步惠呼,從零實(shí)現(xiàn)機(jī)器學(xué)習(xí)算法导俘!

姓名:劉成龍 ?學(xué)號:16020199016

轉(zhuǎn)載自:https://www.jiqizhixin.com/articles/111104,有刪節(jié)罢杉。

【嵌牛導(dǎo)讀】:從零實(shí)現(xiàn)機(jī)器學(xué)習(xí)算法

【嵌牛鼻子】:機(jī)器學(xué)習(xí)

【嵌牛提問】:你想從小白實(shí)現(xiàn)機(jī)器學(xué)習(xí)算法嗎趟畏?

【嵌牛正文】:

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

從頭開始寫機(jī)器學(xué)習(xí)算法能夠獲得很多經(jīng)驗(yàn)赋秀。當(dāng)你最終完成時,你會驚喜萬分律想,而且你明白這背后究竟發(fā)生了什么猎莲。

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

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

對算法有基本的了解

找到不同的學(xué)習(xí)資源

將算法分解成塊

從簡單的例子開始

用可信的實(shí)現(xiàn)進(jìn)行驗(yàn)證

寫下你的過程

基本了解

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

它是什么液荸?

它一般用在什么地方?

什么時候不能用它脱篙?

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

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

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

當(dāng)決策邊界是非線性的時候不能使用感知器然遏,要用不同的方法。

借助不同的學(xué)習(xí)資源

在對模型有了基本了解之后吧彪,就可以開始研究了待侵。有人用教科書學(xué)得更好,而有人用視頻學(xué)得更好姨裸。就我而言秧倾,我喜歡到處轉(zhuǎn)轉(zhuǎn),用各種各樣的資源學(xué)習(xí)傀缩。

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

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

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

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

博客

Jason Brownlee 寫的《如何用 Python 從零開始實(shí)現(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)

視頻

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

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

將算法分解成塊

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

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

初始化權(quán)重

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

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

更新權(quán)重

重復(fù)

接下來我們詳細(xì)敘述每一個模塊的內(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)重相乘之后,對乘積求和撇眯。一般將其稱為點(diǎn)積报嵌。

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

3. 和閾值比較

計算出點(diǎn)積后锚国,我們要將它和閾值進(jìn)行比較腕巡。我將閾值定為 0,你可以用這個閾值血筑,也可以試一下其他值绘沉。

由于之前計算出的點(diǎn)積「f」為 0,不比閾值 0 大豺总,因此估計值也等于 0车伞。

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

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

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

4. 更新權(quán)重

我們要用到下面的等式:

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

為了調(diào)整權(quán)重,我們需要設(shè)定「學(xué)習(xí)率」赤套,用希臘字母「eta(η)」標(biāo)記飘痛。我將學(xué)習(xí)率設(shè)為 0.1,當(dāng)然就像閾值一樣容握,你也可以用不同的數(shù)值宣脉。

目前本教程主要介紹了:

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

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

5. 重復(fù)

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

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

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

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

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

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

從簡單的例子開始

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

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

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

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

#?Importing?libraries

#?NAND?Gate

#?Note:?x0?is?a?dummy?variable?for?the?bias?term

#?????x0??x1??x2

x?=?[[1.,?0.,?0.],

?????[1.,?0.,?1.],

?????[1.,?1.,?0.],

?????[1.,?1.,?1.]]

y?=[1.,

????1.,

????1.,

? ? 0.]

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

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

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

#?Initialize?the?weights

import?numpy?as?np

w?=?np.zeros(len(x[0]))

Out:

[?0.??0.??0.]

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

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

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

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

#?Dot?Product

f?=?np.dot(w,?x[0])

print?f

Out:

0.0

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

3. 與閾值相比較

為了與前文保持連貫,將閾值「z」設(shè)為 0抽米。若點(diǎn)積「f」大于 0特占,則預(yù)測值為 1,否則云茸,預(yù)測值為 0是目。將預(yù)測值設(shè)為變量 yhat。

#?Activation?Function

z?=?0.0

if?f?>?z:

????yhat?=?1.

else:

????yhat?=?0.

print?yhat

Out:

0.0

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

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

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

4. 更新權(quán)重

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

#?Update?the?weights

eta?=?0.1

w[0]?=?w[0]?+?eta*(y[0]?-?yhat)*x[0][0]

w[1]?=?w[1]?+?eta*(y[0]?-?yhat)*x[0][1]

w[2]?=?w[2]?+?eta*(y[0]?-?yhat)*x[0][2]

print?w

Out:

[?0.1??0.???0.?]

要像前文那樣設(shè)置學(xué)習(xí)率脚囊。為與前文保持一致,將學(xué)習(xí)率?η 的值設(shè)為 0.1桐磁。為了便于閱讀悔耘,我將對每次權(quán)重的更新進(jìn)行硬編碼。

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

5. 重復(fù)

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

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

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

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

import?numpy?as?np#?Perceptron?functiondefperceptron(x,?y,?z,?eta,?t):????'''????Input?Parameters:????????x:?data?set?of?input?features????????y:?actual?outputs????????z:?activation?function?threshold????????eta:?learning?rate????????t:?number?ofiterations????'''????#?initializing?the?weights????w?=?np.zeros(len(x[0]))??????????n?=?0????????????????????????????#?initializing?additionalparameters?to?compute?sum-of-squared?errors????yhat_vec?=?np.ones(len(y))?????#?vector?for?predictions????errors?=?np.ones(len(y))???????#?vector?for?errors?(actual?-?predictions)????J?=?[]?????????????????????????#?vector?for?the?SSE?cost?function????while?n?<?t:?for?i?in?xrange(0,?len(x)):?#?dot?product?f?=?np.dot(x[i],?w)?#?activation?function?if?f?>=?z:???????????????????????????????????????????????yhat?=?1.???????????????????????????????????????????else:???????????????????????????????????????????????????yhat?=?0.????????????yhat_vec[i]?=?yhat????????????#?updating?the?weights????????????for?j?in?xrange(0,?len(w)):?????????????????????????????w[j]?=?w[j]?+?eta*(y[i]-yhat)*x[i][j]????????n?+=?1????????#?computing?the?sum-of-squared?errors????????for?i?in?xrange(0,len(y)):????????????????errors[i]?=?(y[i]-yhat_vec[i])**2????????J.append(0.5*np.sum(errors))????return?w,?J

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

#?????x0??x1??x2x?=?[[1.,?0.,?0.],?????[1.,?0.,?1.],?????[1.,?1.,?0.],?????[1.,?1.,?1.]]y?=[1.,????1.,????1.,????0.]z?=?0.0eta?=?0.1t?=?50print?"The?weights?are:"printperceptron(x,?y,?z,?eta,?t)[0]print?"The?errors?are:"printperceptron(x,?y,?z,?eta,?t)[0]

Out:

The?weights?are:

[?0.2?-0.2?-0.1]

The?errors?are:

[0.5,?1.5,?1.5,?1.0,?0.5,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0]

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

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

用可信的實(shí)現(xiàn)進(jìn)行驗(yàn)證

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

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

我們將按照以下幾步進(jìn)行比較:

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

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

訓(xùn)練感知器

測試感知器

和 scikit-learn?感知器進(jìn)行比較

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)建的線性可分?jǐn)?shù)據(jù)集均践,確保感知器可以起作用。為了確認(rèn)摩幔,我們還將數(shù)據(jù)繪制成圖彤委。

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

import?pandas?as?pd

import?numpy?as?np

import?matplotlib.pyplot?as?plt

df?=?pd.read_csv("dataset.csv")

plt.scatter(df.values[:,1],?df.values[:,2],?c?=?df['3'],?alpha=0.8)

text

在繼續(xù)之前葫慎,我先解釋一下繪圖的代碼。我用 Pandas 導(dǎo)入 csv薇宠,它可以自動將數(shù)據(jù)放入 DataFrame 中偷办。為了繪制數(shù)據(jù),我要將值從 DataFrame 中取出來澄港,因此我用了 .values 方法椒涯。特征在第一列和第二列,因此我在散點(diǎn)圖函數(shù)中用了這些特征回梧。第 0 列是值為 1 的虛擬特征废岂,這樣就能計算截距。這與上一節(jié)中的 NAND 門操作相似狱意。最后湖苞,在散點(diǎn)圖函數(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 散點(diǎn)圖函數(shù)的信息。

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

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

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

df?=?df.values??

np.random.seed(5)

np.random.shuffle(df)

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

train?=?df[0:int(0.7*len(df))]

test?=?df[int(0.7*len(df)):int(len(df))]

最后一步是分離訓(xùn)練集和測試集的特征和輸出滚粟。

x_train?=?train[:,?0:3]

y_train?=?train[:,?3]

x_test?=?test[:,?0:3]

y_test?=?test[:,?3]

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

3. 訓(xùn)練感知器

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

defperceptron_train(x,?y,?z,?eta,?t):????'''????Input?Parameters:????????x:?data?set?of?input?features????????y:?actual?outputs????????z:?activation?function?threshold????????eta:?learning?rate????????t:?number?ofiterations????'''????#?initializing?the?weights????w?=?np.zeros(len(x[0]))??????????n?=?0????????????????????????????#?initializing?additionalparameters?to?compute?sum-of-squared?errors????yhat_vec?=?np.ones(len(y))?????#?vector?for?predictions????errors?=?np.ones(len(y))???????#?vector?for?errors?(actual?-?predictions)????J?=?[]?????????????????????????#?vector?for?the?SSE?cost?function????while?n?<?t:??????????for?i?in?xrange(0,?len(x)):???????????????????????????????????????????#?dot?product?????????????f?=?np.dot(x[i],?w)???????????????????????????????????#?activation?function?????????????if?f?>=?z:???????????????????????????????????????????????yhat?=?1.???????????????????????????????????????????else:???????????????????????????????????????????????????yhat?=?0.????????????yhat_vec[i]?=?yhat????????????#?updating?the?weights????????????for?j?in?xrange(0,?len(w)):?????????????????????????????w[j]?=?w[j]?+?eta*(y[i]-yhat)*x[i][j]????????n?+=?1????????#?computing?the?sum-of-squared?errors????????for?i?in?xrange(0,len(y)):????????????????errors[i]?=?(y[i]-yhat_vec[i])**2????????J.append(0.5*np.sum(errors))????return?w,?Jz?=?0.0eta?=?0.1t?=?50perceptron_train(x_train,?y_train,?z,?eta,?t)

接下來看權(quán)重和誤差項(xiàng)平方和耙替。

w?=perceptron_train(x_train,?y_train,?z,?eta,?t)[0]J?=perceptron_train(x_train,?y_train,?z,?eta,?t)[1]print?wprint?J

Out:

[-0.5????????-0.29850122??0.35054929]

[4.5,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0,?0.0]

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

根據(jù)誤差項(xiàng)平方和可以看出硝烂,感知器已經(jīng)收斂了,這是我們預(yù)料中的結(jié)果铜幽,因?yàn)閿?shù)據(jù)是線性可分的滞谢。

4. 測試感知器

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

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

from?sklearn.metrics?import?accuracy_scorew?=perceptron_train(x_train,?y_train,?z,?eta,?t)[0]defperceptron_test(x,?w,?z,?eta,?t):????y_pred?=?[]????for?i?in?xrange(0,?len(x-1)):????????f?=?np.dot(x[i],?w)???????????#?activation?function????????if?f?>?z:???????????????????????????????????????????yhat?=?1???????????????????????????????????????else:???????????????????????????????????????????????yhat?=?0????????y_pred.append(yhat)????return?y_predy_pred?=perceptron_test(x_test,?w,?z,?eta,?t)print?"The?accuracy?score?is:"print accuracy_score(y_test, y_pred)

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

5. 和 scikit-learn?感知器進(jìn)行比較

最后一步是將我們的感知器和 scikit-learn 的感知器進(jìn)行比較陷遮。下面的代碼是 scikit-learn?感知器的代碼:

from?sklearn.linear_model?import?Perceptron

#?training?the?sklearn?Perceptron

clf?=?Perceptron(random_state=None,?eta0=0.1,?shuffle=False,?fit_intercept=False)

clf.fit(x_train,?y_train)

y_predict?=?clf.predict(x_test)

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

Out:sklearn?weights:[-0.5????????-0.29850122??0.35054929]myperceptronweights:[-0.5????????-0.29850122??0.35054929]

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

在結(jié)束之前還有一些小問題。在 scikit-learn 模型中姨涡,我們將隨機(jī)狀態(tài)設(shè)置為「None」而且沒有打亂數(shù)據(jù)衩藤。這是因?yàn)槲覀円呀?jīng)設(shè)置了隨機(jī)種子,而且已經(jīng)打亂過數(shù)據(jù)涛漂,不用再做一次赏表。還需要將學(xué)習(xí)率?eta0 設(shè)置為 0.1,和我們的模型相同匈仗。最后一點(diǎn)是截距瓢剿。因?yàn)槲覀円呀?jīng)設(shè)置了值為 1 的虛擬特征列,因此模型可以自動擬合截距悠轩,所以不必在 scikit-learn?感知器中打開它间狂。

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

寫下你的過程

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

你剛剛經(jīng)歷了學(xué)習(xí)俭尖、做筆記、從頭開始寫算法以及用可信實(shí)現(xiàn)進(jìn)行比較的流程洞翩。不要浪費(fèi)這些努力稽犁!

寫下過程原因有二:

你要更深刻地理解這個過程,因?yàn)槟氵€要將你學(xué)到的東西教給別人骚亿。

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

從機(jī)器學(xué)習(xí)庫中實(shí)現(xiàn)算法是一回事,從頭開始實(shí)現(xiàn)算法是另一回事来屠,它會給人留下深刻印象虑椎。

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

總結(jié)

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末磕仅,一起剝皮案震驚了整個濱河市珊豹,隨后出現(xiàn)的幾起案子簸呈,更是在濱河造成了極大的恐慌,老刑警劉巖店茶,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜕便,死亡現(xiàn)場離奇詭異,居然都是意外死亡贩幻,警方通過查閱死者的電腦和手機(jī)轿腺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丛楚,“玉大人吃溅,你說我怎么就攤上這事⊙烀剩” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵螺垢,是天一觀的道長喧务。 經(jīng)常有香客問我,道長枉圃,這世上最難降的妖魔是什么功茴? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮孽亲,結(jié)果婚禮上坎穿,老公的妹妹穿的比我還像新娘。我一直安慰自己返劲,他們只是感情好玲昧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著篮绿,像睡著了一般孵延。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上亲配,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天尘应,我揣著相機(jī)與錄音,去河邊找鬼吼虎。 笑死犬钢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的思灰。 我是一名探鬼主播玷犹,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼官辈!你這毒婦竟也來了箱舞?” 一聲冷哼從身側(cè)響起遍坟,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晴股,沒想到半個月后愿伴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡电湘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年隔节,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寂呛。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡怎诫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贷痪,到底是詐尸還是另有隱情幻妓,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布劫拢,位于F島的核電站肉津,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏舱沧。R本人自食惡果不足惜妹沙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望熟吏。 院中可真熱鬧距糖,春花似錦、人聲如沸牵寺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缸剪。三九已至吗铐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杏节,已是汗流浹背唬渗。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奋渔,地道東北人镊逝。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像嫉鲸,于是被迫代替她去往敵國和親撑蒜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容