「All models are wrong, but some are useful.」程序員
— George Box算法
機器學習(Machine Learning)最大的魅力在於改變了開發者的思考方式,開發者不須要再費力地給程序編寫固定的邏輯指令,而是讓程序對大量的未知數據進行分析思考,而後學會如何去處理未知的輸入,如何對結果進行預測,如何採起動做服務器
y
值x
值,一個複雜的機器學習系統可能須要成千上萬個特徵labeled examples: {features, label}: (x, y)
,如這封被用戶主動標記爲垃圾郵件的郵件。無標籤樣本只有特徵沒有標籤 unlabeled examples: {features, ?}: (x, ?)
。咱們的目的就是經過大量的有標籤樣本去訓練模型,讓它可以對任何無標籤的樣本進行標籤的預測在統計學中,線性迴歸(Linear Regression)是對 標量響應(因變量) 和 一到多個解釋變量(自變量) 之間的關係進行建模的一種線性方法,只有一個解釋變量時被稱爲簡單線性迴歸,有多個解釋變量時被稱爲 multiple 線性迴歸,預測多個相關因變量時被稱爲 multivariate 線性迴歸
網絡
在統計學中,肯定函數中的參數時一般採用 「最小二乘法」,這是最多見最簡單的儘量減少偏差的擬合方法。在機器學習中,這個關係模型的表示也差很少:app
要想推理(預測)一個新的每分鐘蟲鳴數 對應的溫度 ,只須要把 帶入這個模型便可
這個預測模型只有每分鐘蟲鳴數一個特徵,而一個複雜的模型每每有多個特徵和對應的權重,如:
建立或訓練模型的過程就是尋找最好的權重和誤差值的過程(肯定最好的 和 的過程),而在監督式學習中,機器學習算法經過「考察大量樣本以便嘗試尋找一個最小化損失的模型」來構建模型,這個過程也被稱爲經驗式風險最小化(empirical risk minimization)
損失就是指對糟糕預測的懲罰,是表示模型在一個樣本上預測的糟糕程度,是個數值,若是模型的預測是完美的,那麼損失就是零,不然損失就很大,咱們能夠建立一個數學函數(損失函數)去有意義地彙總各個損失
機器學習
如何快速高效地肯定最好(如使 MSE 最小)的 和 的值呢?最簡單的辦法就是先胡亂猜一個 和 的值,計算一下損失,而後調整一下 和 的值,計算損失,比較一下這兩次損失再決定如何調整 和 的值(若是損失變小了說明調整的方向對了,繼續按照當前方向調整就好了,若是損失變大了就要考慮改變調整的方向了),理論上不斷地迭代試錯下去就能找到最好的 和 的值
函數
泛化(Generalization)指對新的前所未見的數據進行正確預測的能力。上面的模型過擬合(overfit)了訓練數據的特性,一個過擬合的模型雖然在訓練過程當中損失很低可是在預測新數據時卻表現糟糕,那怎麼判斷一個模型對新的數據能不能作出很好地預測呢?這就涉及到正則化的問題了。過擬合之因此會出現問題是由於它爲了追求訓練時的完美讓模型變得異常複雜,而機器學習應該在擬合數據的同時儘量地保證簡單,應該符合奧卡姆剃刀定律,爲了方便驗證模型的泛化能力,能夠將數據集分紅專門用來訓練的訓練集和專門用來測試的測試集,在測試集上表現良好每每能代表在新的數據集也能表現良好,前提是測試集足夠大且不會反覆用相同測試集做假
泛化過程通常須要知足三項基本假設:工具
實際上,有些狀況下可能會違反其中一些假設,如廣告推薦模型可能依賴於用戶以前看過的廣告,這違反了第一條假設,而一旦違反任意一項假設,就表示咱們已經失去了重要的理論支持,就必須得時刻注意各項指標了
既然測試集應該足夠大,那多大好呢?怎麼合理地把數據集分紅訓練集和測試集呢?訓練集和測試集應該相互獨立,但 訓練集的規模越大模型的學習效果就越好,測試集規模越大咱們咱們對評估指標的信心就越足,若是數據集的規模自己就很大就簡單多了,但若是數據集規模很是小,就要先進行像交叉驗證(cross-validation)之類的複雜操做了
測試集應該知足兩個條件:學習
永遠不要對測試集進行訓練,若是你發現模型在測試集上預測的準確度特別高,甚至比在訓練集上的還高,先不要興奮,你極可能把一些測試數據用於訓練了,得從新檢查一下訓練集是否是包含了一些訓練集的數據
在訓練集上訓練模型,在測試集上評估模型,再根據評估的結果調整模型,如此循環下去直到能選擇一個在測試集上表現最好的模型。這樣的流程有點問題,咱們可能無形中對測試數據的特性進行了過擬合,因此爲了不出現這種狀況,咱們從數據集中再單獨劃分出一些數據做爲驗證集,這樣迭代評估的時候只在驗證集上評估便可,測試集只用來確認結果,要確保在測試集上得出的結果基本符合在驗證集上得出的結果,若是不符合就說明對驗證集進行了過擬合
測試
咱們彷佛忘了一個最基本的問題,那就是如何從原始數據中抽象出供模型使用的特徵值,而從各類各樣的數據源中提取數據,而後再根據這些數據建立特徵向量的過程被稱爲特徵工程(feature engineering)。像房屋的臥室數量這樣的簡單數值信息直接複製到特徵向量就能夠了,可是像房屋的所屬街道這樣的字符串信息怎麼映射到特徵向量呢?最簡單的方式就是採用 one-hot 獨熱編碼,如一共有 N 個街道,那就建立一個 N 位的編碼,而後按照字典的方式將全部街道映射到這個這個編碼上(第 i 個街道那一位置 1,其它位置 0),若是 N 特別大,能夠採用稀疏表示法(sparse representation)壓縮。那究竟什麼樣的特徵纔算好的特徵呢?首先,它應該具備非零值且至少出現不少次,若是一個特徵出現次數極少或只出現一次,就能夠考慮在預處理時就把它過濾掉了。其次,它應該具備清晰明確的意義,以便咱們在檢查和調試時特徵被正確的處理。第三,特徵值不該隨時間而發生變化。最後,特徵值不該採用不理性的離羣值。要作這麼多工做的緣由是爲了把噪音降到最低,機器學習就像一個黑盒子,把數據都丟進去,卻不檢查數據,就盼着能得到好的結果,這從目前來看很不合適也不現實,因此在把數據交給機器學習模型以前,咱們只能憑藉本身的經驗對特徵進行抽象和過濾等處理,甚至還要監控特徵隨着時間變化的狀況。
不少時候浮點特徵值的範圍會很大(如 100 到 900),爲了讓梯度降低法更快地收斂,同時爲了不數據溢出致使的 NaN 問題,能夠把它縮放到標準範圍(如 0 到 1 或 -1 到 +1),最簡單的縮放策略就是線性的縮放,不過還有一種縮放策略是先計算每一個值的 Z score,縮放後的值爲 (原始值 - 平均值) / 標準差
,這樣的話大多數縮放後的值都會介於 -3 和 +3 之間了。
有時咱們須要處理一下極端離羣值(extreme outlier):
良好的機器學習依賴於良好的數據
到目前爲止,咱們研究的都是線性問題,線性學習器不但簡單並且能夠很容易擴展到大型數據集,可是若是要建模的問題很複雜怎麼辦?
在研究泛化問題時咱們重點關注了過擬合的問題,若是咱們過於追求在訓練集上的損失極低,就可能會出現過擬合訓練集而帶來的問題:
咱們要平衡這兩個因素,讓損失和複雜度都儘量地低,也就是說,要確保正確的訓練數據,又不過分信賴訓練數據。那如何定義模型複雜度呢?最簡單的就是選擇較小的權重,也就是說即便參數小到能夠忽略咱們依然能夠獲取正確的訓練樣本,從數學上來講通常使用 正則化,也稱爲嶺正則化,在這種正則化策略中,咱們對權重的平方和進行懲罰,若是熟悉貝葉斯先驗機率就知道這是一種先驗機率,在咱們知道訓練樣本以前就猜到權重應該是以 0 爲中心呈正態分佈的,並且數值不會太大。以數學的方式表示上面的公式爲
能夠看到第一項下降損失的過程取決於訓練數據,而第二項簡化模型則與數據無關,這兩項經過 實現了平衡, 的選取取決於你和實際狀況,若是有大量訓練數據且訓練數據與測試數據看起來一致,知足獨立同分布,你可能不須要多少正則化,不然可能須要大量正則化和交叉驗證,(lambda)也被稱爲正則化率(regularization rate),若是 lambda 值太高,模型會很是簡單,但會面臨數據欠擬合的風險,模型將沒法充分了解訓練數據以進行有用的預測,若是 lambda 值太低,模型會比較複雜,會面臨數據過擬合的風險,模型會過多解讀訓練數據的特殊性從而很難泛化到新的數據。將 lambda 值設爲 0 可完全取消正則化,此時訓練的惟一目的就是最小化損失,可是會使過擬合的風險達到最高。
正則化鼓勵 non-informative 特徵的權重趨向於 0,可是當這類特徵剛好與標籤相關時,會致使模型學到一箇中等的權重,此時,模型錯誤地給了 non-informative 特徵一些本應該給 informative 特徵的信任。 正則化對大權重的懲罰比小權重更嚴厲,所以,即便一個權重降低得比另外一個快, 正則化也會強制使較大權重的那個降低得比較小的更快。 正則化與學習速率息息相關,很容易讓人困惑
正則化雖然可使權重變小,但不能使他們正好爲 0, 正則化雖然可使權重爲 0,這樣能夠直接忽略某些特徵進而減小內存消耗,可是它會將咱們的凸優化問題變成非非凸優化問題(NP 困難),因此 正則化並不實用。而 正則化具備凸優化的優點,能夠進行有效計算。 會下降權重的平方, 會下降權重的絕對值, 的導數是 2 乘以權重, 的導數是與權重無關的常量 k,也就是說 每次移除權重的 x%,一般不會減到 0, 每次從權重中減去固定的常數,若是減法使權重從 +0.1 變成 -0.2,因爲懲罰的是絕對值,因此權重會變成 0
不少問題都須要把 機率估計 做爲輸出,好比圖片中的動物是貓的機率是多少、狗晚上吵醒人的機率是多少,既然是機率,那麼機率值確定是 0 到 1 之間,那咱們以前學到的線性模型的輸出能強制限制到 0 到 1 之間麼?很顯然不太現實,那咱們就要想出一種不一樣的損失函數和預測方法使機率值很天然的處於 0 到 1 之間,咱們將這種想法稱爲邏輯迴歸(Logistic Regression)。邏輯迴歸的機率就很是有用了,甚至能夠被看作實際機率去作有用的預測,用這個機率乘以想要預測的項就能夠獲得預期值。它在二元分類(binary classification)中也很是有用,如一封郵件是垃圾郵件的機率是多少,一枚硬幣朝上的機率是多少。那邏輯迴歸模型是怎樣保證輸出老是介於 0 到 1 之間呢?咱們來看一下 S 型函數(sigmoid function):
邏輯迴歸模型也相似: 表示邏輯迴歸模型的輸出, 表示線性模型的 , 也稱爲對數概率(log-odds),由於 ,若是是二元分類問題,那麼 和 就是相對的兩個機率其中 表示包含不少有標籤樣本的數據集, 表示有標籤樣本中的標籤, 表示預測的值
在邏輯迴歸模型中正則化變得更加劇要,若是沒有正則化,那麼邏輯迴歸的漸進性將在高維上讓損失趨向於 0 ,若是未指定正則化函數,模型將變得徹底過擬合,所以邏輯迴歸模型一般使用 正則化或早停法下降模型的複雜度
機器學習模型解決的最多見的問題就是分類問題,如郵件是正常郵件仍是垃圾郵件,圖片中的物體是什麼,咱們可使用邏輯迴歸做爲分類的基礎,給 機率輸出 應用 固定的閾值(threshold)就好了,如一封郵件爲垃圾郵件的機率超過了 0.8,咱們就認爲它是垃圾郵件,0.8 就是分類的閾值(分類閾值 classification threshold 也被稱爲斷定閾值 decision threshold),一旦選定了分類閾值,那咱們怎麼評估這個閾值下模型的質量呢?最傳統的方式就是用準確率(accuracy)這個指標,也就是預測正確數除以總數。可是準確率有時會成爲不好或者誤導性的指標,好比當不一樣錯誤的類型代價不同時,當分類不平衡(正例或負例極少)時(一個廣告的點擊率是千分之一萬分之一甚至更低,那麼一個模型預測一個廣告不被點擊的的準確率是 99.999% 沒有任何意義),此時區分不一樣錯誤的類型可能會有所幫助:
也就是說,TP 和 TN 都是正確的預測,而 FP 是指模型錯誤地將負類別預測成正類別,FN 更是嚴重錯誤地將正類別預測成負類別
如今假如出現了 100 次狼來了事件,有 1 次狼真的來了小男孩喊狼來了,有 1 次狼沒來卻喊狼來了,有 8 次狼來了卻沒喊,有 90 次 狼沒來也沒喊,那麼小男孩的準確率高達 ,從 91% 的準確率來看這個小男孩還挺好,可是事實是這樣的嗎?在 91 次狼沒來中小男孩有 90 次沒喊狼來了,可是,在 9 次狼真的來了的時候小男孩卻只有 1 次喊狼來了,這是多麼可怕啊!若是是腫瘤診斷模型,9 個惡性腫瘤中只有 1 個被發現是惡性腫瘤,那後果將更加的可怕
所以咱們須要一些新的指標來評估,如精確率(precision),也就是小男孩喊狼來了的狀況中有多少次是對的,。另外一方面,召回率(recall)是指在全部嘗試進入村子的狼中咱們發現了多少頭,即正確被識別爲正例的比例,。有趣的是這些指標每每是此消彼長的,如爲了把召回率作得好只要有風吹草動就喊狼來了,這會下降分類閾值,爲了精確率高只有在確認狼真的來了才喊狼來了,這會提升分類閾值,所以只有這兩方面都作得好才能評價模型的優劣。通常來講,提升分類閾值會減小假正例,從而提升精確率
你可能會說,那我把全部可能的分類閾值都試一下看那個閾值下模型的表現更好不就好了麼?事實上確實有這樣的,叫 ROC 曲線
真正例率 TPR(True Positive Rate)爲 ,和召回率同樣
假正例率 FPR(False Positive Rate)爲
將不一樣閾值下的 TPR 和 FPR 值的點連成一條曲線就是 ROC 曲線:
當問題複雜到沒法用線性迴歸解決怎麼辦?即便是利用特徵交叉也沒法解決非線性的問題呢?這個時候咱們但願經過某種方式,讓模型本身學習非線性的規律,而不用咱們手動爲它設置參數。這一願景能夠經過深度神經網絡(Deep Neural Networks)實現,它在複雜數據問題上作得特別好,例如圖片數據,視頻數據,音頻數據等。先來看一下線性模型的表示,如 :
訓練神經網絡最經常使用的訓練算法就是反向傳播算法(Backpropagation),它使梯度降低用於多層神經網絡成爲可能,反向傳播依賴梯度這個概念,事物必須是可微的,這樣咱們才能進行學習
須要注意的是,可能會出現梯度消失(Vanishing Gradients)的狀況,若是網絡太過深刻,信噪比隨着模型的深刻變差,學習可能變得特別慢,這個時候 ReLU 或其餘策略可能比較有用。若是網絡中的權重太大,那麼較低層的梯度會涉及許多大項的乘積,可能就會出現梯度爆炸(Exploding Gradients)的狀況,此時梯度太大根本沒法收斂,Batch 標準化或者下降學習速率會比較有用。若是加權和都低於 0,那麼 ReLU 單元會卡住,對網絡輸出沒有任何貢獻,梯度就沒法反向傳播,永遠沒法返回存在 ReLU 層的位置,就會出現死亡 ReLU 單元(Dead ReLU Units)的狀況,此時使用不一樣的初始化或下降學習速率會有所幫助
訓練神經網絡時還有一個頗有用的技巧,正則化的另外一種形式,叫作丟棄(Dropout),就是針對機率 P 取一個節點,而後從網絡的一個梯度步長中把它移除。在其餘梯度步長中重複此過程,並隨機取不一樣的節點進行丟棄,丟棄的越多,正則化的效果就越強
到目前爲止,咱們討論的分類問題都是二元分類問題,如郵件是否是垃圾郵件,腫瘤是惡性的仍是良性的,咱們也知道了,利用邏輯迴歸和能夠很好地解決二元分類問題,可是生活中不少分類問題是多類別(multi-class)的,如圖片中的東西是蘋果仍是梨仍是小狗仍是其餘的東西,這朵花是什麼花。那咱們怎麼把二元分類拓展到多類別分類呢?one-vs.-all 提供了利用二元分類的方式,若是有 N 個可能解,one-vs.-all 就包含 N 個單獨的二元分類器,也就是說每一個可能的結果都對應一個二元分類器,在訓練的時候,模型會運行一系列二元分類器,對每一個分類器進行訓練以回答單獨的分類問題,如給定一張狗狗的圖片,可能會訓練五種不一樣的識別器:
當類別不多時還能夠接受,但類別不少時,效率就會變得異常低下,所以咱們可使用深度神經網絡建立一個明顯更高效的 one-vs.-all 模型,其中每一個輸出節點表明不一樣的類型:
當類別不少時,Softmax 的代價會變得很大,因此除了 Full Softmax 還有一種策略叫 Candidate sampling,對全部正例標籤計算機率,但只對負例標籤的隨機樣本計算機率,如咱們想肯定圖片是小獵犬仍是尋血獵犬,咱們就沒必要爲每一個非狗樣本提供機率了
Softmax 假設每一個樣本只能有一個類別,若是一個樣本同時屬於多個類別,那麼你就不能用 Softmax,你只能依賴多個邏輯迴歸
如今咱們思考一個問題,咱們在讀一本書的時候,或者在思考的時候,腦海裏總有一個聲音跟你說話,這個聲音很像你本身的聲音,但又不是你的聲音,若是你看過西部世界,或者對心理學有過了解,你可能知道有一種理論叫作二分心智。二分心智通常被看作是人類意識的起源,而人們對於意識這種東西並非真正的瞭解,可是人類卻總想扮演上帝的角色,想要賦予一我的造的機器意識。上個世紀人們開動本身的想象力,想象着賦予機器意識的那一天,各類科幻電影更是把這種想象表達的淋漓盡致,然而到如今人們才冷靜下來,發現人工智能還有很長很長一段路要走,與其建立人工智能不如利用已有的知識水平爲人工智能鋪路,不如將已有的人工智能成果(機器學習)應用於現實生活中,Google 的 AI 向善就是很好地方式,利用 AI 技術能夠預測洪水,能夠用於醫療,能夠預測疾病,能夠幫助聾啞人跟正常人溝通等等等等
機器學習做爲實現 AI 的主要手段,涉及到的知識和領域很是多,而 Google 提供的 TensorFlow 平臺讓普通人建立或訓練機器學習模型成爲可能,做爲普通人,你沒法提出革命性的人工智能理論,甚至沒法理解不少數學知識,可是有了 TensorFlow 平臺,有了一些訓練好的模型,你就能夠建立本身想要的,能幫助你本身或者幫助他人解決問題的模型