機器學習原來如此有趣!全世界最簡單的機器學習入門指南

大數據技術2019-06-12 06:33:23

作者:Adam Geitgey     

翻譯:巡洋艦科技——趙95

校對:離線Offline——林沁

鏈接:https://zhuanlan.zhihu.com/p/24339995


你是否曾經聽到過人們談論機器學習,而你卻對其含義只有一個模糊的概念呢?你是否已經厭倦了在和同事對話時只能點頭呢?現在,讓我們一起來改變這個現狀吧!


這篇文章是為那些對機器學習感興趣卻不知道如何開始的人而寫的。我估計有很多人嘗試過閲讀維基百科上面關於機器學習的文章,結果越讀越受挫,後面乾脆直接放棄,同時希望有人能夠給出一個高質量的解釋,那太棒了,這篇文章就是在幹這件事。


這篇文章的目標是讓所有人都能看懂,所以文章中將會有很多的概括,但是誰在意呢?如果這篇文章能引起一部分人對機器學習的興趣,那我的使命就達成了。


機器學習是什麼?


機器學習是一種概念:不需要寫任何與問題有關的特定代碼,泛型算法(Generic Algorithms)就能告訴你一些關於你數據的有趣結論。不用編碼,你將數據輸入泛型算法當中,它就會在數據的基礎上建立出它自己的邏輯。


例如,有一種算法叫做分類算法。它可以將數據放進不同的分組。用於識別手寫數字的分類算法也可以用於區分垃圾郵件和非垃圾郵件,且不需要改變任何代碼。算法是同一個,但是輸入了不同的訓練數據,所以得出不同的分類邏輯。


機器學習算法是個黑盒,它可以重複使用於很多不同的分類問題。


機器學習是覆蓋許多種泛型算法的涵蓋性術語。


兩種類型的機器算法


你可以將機器學習算法分成兩大類別:監督式學習(supervised Learning)和非監督式學習(unsupervised Learning)。要區分兩者很簡單,但也非常重要。


監督式學習


假設你是一名房地產經紀人,你的生意蒸蒸日上,因此你僱了一批新員工來幫忙。但是問題來了——雖然你可以一眼估算出房子的價格,但新員工卻不像你這樣經驗豐富,他們不知道如何給房子估價。


為了幫助你的新員工(也許就是為了給自己放個假嘻嘻),你決定寫一個可以根據房屋大小、地段以及同類房屋成交價等因素來評估一間房屋的價格的小軟件。


近三個月來,每當你的城市裏有人賣了房子,你都記錄了下面的細節——卧室數量、房屋大小、地段等等。但最重要的是,你寫下了最終的成交價:

這就是我們的「訓練數據」。


使用這些訓練數據,我們要來編寫一個能夠估算該地區其他房屋價值的程序:

我們希望使用這些訓練數據來預測其他房屋的價格。


這就是監督式學習。你已經知道了每一棟房屋的售價,換句話説,你已經知道了問題的答案,並且可以反向找出解題的邏輯。


為了編寫你的軟件,你將包含每一套房產的訓練數據輸入到你的機器學習算法當中去。算法會嘗試找出需要做哪些數學運算來得出價格。


這就好像是你已經知道了數學測試題的答案,但是算式中的運算符號都被擦去了:

天啊!一個陰險的學生擦去了參考答案上的算術符號!


你能從這張圖裏看出來測驗中的數學題是怎樣的嗎?你知道自己應該對左邊的數字「做些什麼」,才能得到右邊的答案。


在監督式學習中,你讓計算機為你算出這種關係。而一旦你知道了解決這類特定問題所需要的數學方法後,你就可以解答其它同類問題了!


非監督式學習


讓我們回到房地產經紀人的例子。如果你不知道每棟房子的售價怎麼辦?即使你所知道的僅僅是每棟房屋的大小、位置等信息,你也可以搞出一些很酷炫的花樣來。這就是我們所説的非監督式學習。

即使你並不是在嘗試預測未知的數據(如價格),你也可以運用機器學習做一些有意思的事。


這就有點像有人給你一張紙,上面寫了一列數字,然後説:「我不太清楚這些數字有什麼意義,但也許你能找出些規律或是把它們分類什麼的——祝你好運!」


所以該怎麼處理這些數據呢?首先,你可以用個算法自動從數據中劃分出不同的細分市場。也許你會發現,當地大學附近的購房者特喜歡户型小、卧室多的房子,而郊區的購房者偏好三卧室的大户型。瞭解這些不同消費者的喜好可以直接幫助你的營銷。


你還可以做件很酷炫的事,就是自動找出非同尋常的房屋。這些與眾不同的房產也許是奢華的豪宅,而你可以將最優秀的銷售人員集中在這些地區,因為他們的佣金更高。


在接下來的內容中我們主要討論監督式學習,但這並不是因為非監督式學習比較沒用或是無趣。實際上,隨着算法的改良,非監督式學習正變得越來越重要,因為即使不將數據和正確答案聯繫在一起,它也可以被使用。[2]


太酷炫了,但是估算房價真能被看作「學習」嗎?


作為人類的一員,你的大腦可以應付絕大多數情況,並且在沒有任何明確指令時也能夠學習如何處理這些情況。如果你做房地產經紀人時間足夠長,你對於房產的合適定價、房屋的最佳營銷方式以及客户會感興趣類型等等都會有一種本能般的「感覺」。強人工智能研究的目標就是要計算機複製這種能力。


但是目前的機器學習算法還沒有那麼強大——它們只能在非常特定的、有限的問題上有效。也許在這種情況下,「學習」更貼切的定義是「在少量樣本數據的基礎上找出一個公式來解決特定的問題」。


但是「機器在少量樣本數據的基礎上找出一個公式來解決特定的問題」不是個好名字。所以最後我們用「機器學習」取而代之。


當然了,如果你是在 50 年後的未來讀的這篇文章,而我們人類也已經得出了強人工智能的算法的話,那這篇文章看起來就像個老古董了。那樣的話,就別讀了,去讓你的機器傭人給你做份三明治吧,未來的人類。


讓我們愉快地寫代碼吧!


所以,你打算怎麼寫上面例子中評估房價的程序呢?在往下看之前先思考一下吧。


如果對機器學習一無所知,你很有可能會嘗試寫出一些基本規則來評估房價,如下:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price = 0
# 在我這地方,每平方英尺房屋均價是 200 美元
price_per_sqft = 200
if neighborhood == "hipsterton":
# 但是有些地段房價會貴一點
price_per_sqft = 400
elif neighborhood == "skid row":
# 有些地段房價便宜點
price_per_sqft = 100
# 我們先按面積大小估計房屋價格基準
price = price_per_sqft * sqft
# 現在根據卧室數量微調價格
if num_of_bedrooms == 0:
# 工作室類型的公寓比較便宜
price = price — 20000
else:
# 卧室數量越多,通常房價越貴
price = price + (num_of_bedrooms * 1000)
return price

假如你像這樣瞎忙幾個小時,最後也許會得到一些像模像樣的東西。但是你的程序永不會完美,而且當價格變化時很難維護。

如果能讓計算機找出實現上述函數功能的辦法,豈不更好?只要返回的房價數字正確,誰會在乎函數具體幹了些什麼呢?

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price =
return price

考慮這個問題的一種角度是將價格看作一碗美味的湯,而湯的原材料就是卧室數量、面積和地段。如果你能算出每種原材料對最終的價格有多大影響,也許就能得到各種原材料混合形成最終價格的具體比例。


這樣可以將你最初的程序(全是令人抓狂的 if else 語句)簡化成類似如下的樣子:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price = 0
# 一小撮這個
price += num_of_bedrooms * .841231951398213
# 一大撮那個
price += sqft * 1231.1231231
# 或許再加一把這個
price += neighborhood * 2.3242341421
# 最後,再多加一點點鹽
price += 201.23432095
return price


注意那些用粗體標註的神奇數字——.841231951398213, 1231.1231231, 2.3242341421, 和201.23432095。它們稱為權重(weight)。如果我們能找出對每棟房子都適用的完美權重,我們的函數就能預測所有的房價!


一種找出最佳權重的笨辦法如下所示:


第一步:


首先,將每個權重都設為 1.0:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price = 0
# 一小撮這個
price += num_of_bedrooms * 1.0
# 一大撮那個
price += sqft * 1.0
# 或許再加一把這個
price += neighborhood * 1.0
# 最後,再多加一點點鹽
price += 1.0
return price


第二步:


將你知道的每棟房產的數據代入函數進行運算,檢驗估算值與正確價格的偏離程度:

用你的程序來預測每棟房屋的價格。


比如説,如果第一套房產實際成交價為 25 萬美元,你的函數估價為 17.8 萬美元,這一套房產你就差了 7.2 萬。


現在,將你的數據集中的每套房產估價偏離值平方後求和。假設你的數據集中交易了 500 套房產,估價偏離值平方求和總計為 86,123,373 美元。這個數字就是你的函數現在的「錯誤」程度。


現在,將總和除以 500,得到每套房產的估價偏差的平均值。將這個平均誤差值稱為你函數的代價(cost)。


如果你能通過調整權重,使得這個代價變為 0,你的函數就完美了。它意味着,根據輸入的數據,你的程序對每一筆房產交易的估價都是分毫不差。所以這就是我們的目標——通過嘗試不同的權重值,使代價儘可能的低。


第三步:


通過嘗試所有可能的權重值組合,不斷重複第二步。哪一個權重組合的代價最接近於 0,你就使用哪個。當你找到了合適的權重值,你就解決了問題!


興奮的時刻到了!


挺簡單的,對吧?想一想剛才你做了些什麼。你拿到了一些數據,將它們輸入至三個泛型的、簡單的步驟中,最後你得到了一個可以對你所在區域任何房屋進行估價的函數。房價網站們,你們要小心了!


但是下面的一些事實可能會讓你更興奮:


1. 過去 40 年來,很多領域(如語言學、翻譯學)的研究表明,這種「攪拌數字湯」(我編的詞)的泛型學習算法已經超過了那些真人嘗試明確規則的方法。機器學習的「笨」辦法終於打敗了人類專家。


2. 你最後寫出的程序是很笨的,它甚至不知道什麼是「面積」和「卧室數量」。它知道的只是攪拌,改變數字來得到正確的答案。


3. 你可能會對「為何一組特殊的權重值會有效」一無所知。你只是寫出了一個你實際上並不理解卻能證明有效的函數。


4. 試想,如果你的預測函數輸入的參數不是「面積」和「卧室數量」,而是一列數字,每個數字代表了你車頂安裝的攝像頭捕捉的畫面中的一個像素。然後,假設預測的輸出不是「價格」而是「方向盤轉動角度」,這樣你就得到了一個程序可以自動操縱你的汽車了!


太瘋狂了,對吧?


第三步裏「嘗試每個數字」是怎麼一回事?


好吧,當然你不可能試遍所有權重組合來找到效果最好的組合。直到世界毀滅你也算不完,因為這數字和組合無窮無盡。


為了避免這種情況,數學家們找到了很多種聰明的辦法來快速找到優秀的權重值。下面是一種:


首先,寫出一個簡單的等式表示上面的第二步:

這就是你的代價函數(Cost Function)。


現在讓我們,使用機器學習數學術語(現在暫時你可以忽略它們),重新改寫同樣的這一等式:

θ 表示當前的權重值。 J(θ) 表示「當前權重的代價」。


這個等式表示,在當前權重值下,我們估價程序的偏離程度。


如果我們為這個等式中所有卧室數和麪積的可能權重值作圖的話,我們會得到類似下圖的圖表:

我們代價函數的圖形就像一個碗。縱軸表示代價。

圖中,藍色的最低點就是代價最低的地方——在這裏我們的程序偏離最小。最高點們意味着偏離最大。所以,如果我們能找到一組權重值讓我們到達圖中的最低點,我們就得到了答案!



因此,我們需要做的只是調整我們的權重,使得我們在圖上朝着最低點「走下坡路」。如果我們不斷微調權重,一直向最低點移動,那麼我們最終不用嘗試太多權重就可以到達那裏。


如果你還記得一點微積分的話,你也許記得如果你對一個函數求導,它會告訴你函數任意一點切線的斜率。換句話説,對於圖上任意給定的一點,求導能告訴我們哪條是下坡路。我們可以利用這個知識不斷走向最低點。


所以,如果我們對代價函數關於每一個權重求偏導,那麼我們就可以從每一個權重中減去該值。這樣可以讓我們更加接近山底。一直這樣做,最終我們將到達底部,得到權重的最優值。(讀不懂?不用擔心,繼續往下讀)。


這種為函數找出最佳權重的方法叫做批量梯度下降(Batch Gradient Descent)。如果你對細節感興趣,不要害怕,可以看看這個詳細説明。


當你使用一個機器學習算法庫來解決實際問題時,這些都已經為你準備好了。但清楚背後的原理依然是有用的。


還有什麼是本篇文章略過的內容?


上面我描述的三步算法被稱為多元線性迴歸(multivariate linear regression)。你在估算一個能夠擬合所有房價數據點的直線表達式。然後,你再根據房子可能在你的直線上出現的位置,利用這個等式來估算你從未見過的房屋的價格。這是一個十分強大的想法,你可以用它來解決「實際」問題。


但是,儘管我展示給你的這種方法可能在簡單的情況下有效,它卻不能應用於所有情況。原因之一,就是因為房價不會是簡簡單單一條連續的直線。


不過幸運的是,有很多辦法來處理這種情況。有許多機器學習算法可以處理非線性數據(如神經網絡或帶核函數的支持向量機)。除此之外,靈活使用線性迴歸也能擬合更復雜的線條。在所有的情況下,尋找最優權重這一基本思路依然適用。


另外,我忽略了過擬合(overfitting)的概念。得到一組能完美預測原始數據集中房價的權重組很簡單,但用這組權重組來預測原始數據集之外的任何新房屋其實都不怎麼準確。這也是有許多解決辦法的(如正則化以及使用交叉驗證的數據集)。學習如何應對這一問題,是學習如何成功應用機器學習技術的重點之一。


換言之,儘管基本概念非常簡單,要通過機器學習得到有用的結果還是需要一些技巧和經驗的。但是,這是每個開發者都能學會的技巧。


機器學習是魔法嗎?


一旦你開始明白,用機器學習技術解決那些看似困難問題(如字跡識別)有多便利時,你就會有一種,只要有足夠的數據,你就能夠用機器學習解決任何問題的感覺。只需要輸入數據,計算機就能神奇地找出擬合數據的等式!


但是有一點很重要,你要記住,只有在你擁有的數據對於解決實際問題有效的時候,機器學習才能適用。


例如,如果你建立了一個根據每套房屋內盆栽種類的數量來預測房價的模型,那它永遠都不會有效果。因為盆栽種類的數量和房價之間沒有任何的關係。所以,無論你多賣力地嘗試,計算機永遠也推導不出兩者之間的關係。

你只能模擬實際存在的關係。


所以請記住,如果一個問題人類專家不能手動用數據解決,計算機可能也不能解決。然而,對於那些人類能夠解決的問題,如果計算機能夠更快地解決,那豈不美哉?


怎樣學到更多機器學習的知識


我認為,目前機器學習的最大問題是它主要活躍於學術界和商業研究組織中。對於只想大體瞭解一下,而不打算成為專家的人們來説,簡單易懂的資料不多。但是這種情況每天正在改善。


吳恩達教授(Andrew Ng)在 Coursera 上的免費機器學習課程非常棒。我強烈建議從此入手。對於任何擁有計算機或科學學位的人,或是還能記住一點點數學的人來説,都應該非常容易入門。


另外,你還可以通過下載安裝 SciKit-Learn,用它來試驗無數個機器學習算法。它是一個 Python 框架,包含了所有常見機器學習算法的「黑盒」版本。

注:

1. 譯者注:泛型,即沒有特定類型,泛型算法是一種對很多不同問題都適用的算法,也叫作通用算法。如果你現在還對這個概念一知半解沒關係,相信你讀過這篇文章之後會對「泛型算法」有一個更深入的理解。

2. 作者注:還有很多其它種類的機器學習算法。但從這裏開始講起是一個不錯的選擇。

3. 譯者注:權重可能有很多種不同的組合,每一種權重最後給出的房價預測也不同,我們的目標就是要找出一組最終價格最接近真實值的權重。

4. 譯者注:到這裏,你應該對泛型算法有一個更深刻的理解了。

5. 譯者注:如果你還記得微積分當中,一個點求出的導數是 0的話,那麼這個點就是最低點。所以返回到剛剛的代價函數裏面,代價函數就等於 0,也就意味着,你的預估和真實值沒有任何差別。


(完)



●編號832,輸入編號直達本文

●輸入m獲取到文章目錄

推薦↓↓↓

程序員數學之美

https://hk.wxwenku.com/d/200843084