AI 之旅:啓程

「All models are wrong, but some are useful.」程序員

— George Box算法

機器學習(Machine Learning)最大的魅力在於改變了開發者的思考方式,開發者不須要再費力地給程序編寫固定的邏輯指令,而是讓程序對大量的未知數據進行分析思考,而後學會如何去處理未知的輸入,如何對結果進行預測,如何採起動做服務器

基本術語

  • 監督式機器學習(Supervised machine learning): 機器學習系統學習如何組合輸入以對 前所未見的數據 產生 有用的預測
  • 標籤(Label): 指咱們正在預測的東西或者說試圖預測的目標,如小麥未來的價格、照片中的動物種類、郵件是否是垃圾郵件等,是簡單線性迴歸的 y
  • 特徵(Feature): 指從輸入數據中提取的供機器學習系統使用的信息,是咱們表示數據的方式,如郵件的發件人地址、郵件內容,是線性迴歸的 x 值,一個複雜的機器學習系統可能須要成千上萬個特徵
  • 樣本(Example): 指一份數據,樣本分爲有標籤樣本和無標籤樣本。有標籤樣本包含特徵和標籤 labeled examples: {features, label}: (x, y),如這封被用戶主動標記爲垃圾郵件的郵件。無標籤樣本只有特徵沒有標籤 unlabeled examples: {features, ?}: (x, ?)。咱們的目的就是經過大量的有標籤樣本去訓練模型,讓它可以對任何無標籤的樣本進行標籤的預測
  • 模型(Model): 是執行預測的工具,定義了特徵和標籤之間的關係,如垃圾郵件監測模型會將某些特徵和垃圾郵件標籤緊密聯繫起來,模型有兩個階段: 訓練和推理
  • 訓練(Training): 建立模型或者讓模型學習,也就是說向模型提供有標籤樣本,從而讓模型逐漸學習到特徵和標籤之間的關係
  • 推理(Inference): 將訓練後的模型應用於無標籤樣本,也就是說用這個訓練後的模型去作有用的預測的過程
  • 迴歸模型(Regression model): 預測的是連續的值,如用戶點擊這條廣告的機率、小麥的價格
  • 分類模型(Classification mode): 預測的是離散的值,如這封郵件是否是垃圾郵件、這張圖片中的動物是什麼動物

線性迴歸

在統計學中,線性迴歸(Linear Regression)是對 標量響應(因變量) 和 一到多個解釋變量(自變量) 之間的關係進行建模的一種線性方法,只有一個解釋變量時被稱爲簡單線性迴歸,有多個解釋變量時被稱爲 multiple 線性迴歸,預測多個相關因變量時被稱爲 multivariate 線性迴歸
網絡

linear regression
能夠看出每分鐘蟋蟀的叫聲和溫度的關係是線性的關係,咱們就能夠隨便畫一條直線去擬合:

y = mx + b
  • y 指溫度(試圖預測的值)
  • m 指直線的斜率
  • x 指每分鐘蟲鳴數(輸入的特徵值)
  • b 指 y 軸截距

在統計學中,肯定函數中的參數時一般採用 「最小二乘法」,這是最多見最簡單的儘量減少偏差的擬合方法。在機器學習中,這個關係模型的表示也差很少:app

y' = b + w_1x_1
  • y' 指預測的標籤(理想輸出)
  • b 指誤差(y 軸截距),有時被稱爲 w_0
  • w_1 指特徵 1 的權重,和傳統直線方程中的斜率 m 是一個概念
  • x_1 指特徵(一個已知輸入)

要想推理(預測)一個新的每分鐘蟲鳴數 x_1 對應的溫度 y',只須要把 x_1 帶入這個模型便可
這個預測模型只有每分鐘蟲鳴數一個特徵,而一個複雜的模型每每有多個特徵和對應的權重,如: y' = b + w_1x_1 + w_2x_2 + w_3x_3
建立或訓練模型的過程就是尋找最好的權重和誤差值的過程(肯定最好的 bw_1 的過程),而在監督式學習中,機器學習算法經過「考察大量樣本以便嘗試尋找一個最小化損失的模型」來構建模型,這個過程也被稱爲經驗式風險最小化(empirical risk minimization)
損失就是指對糟糕預測的懲罰,是表示模型在一個樣本上預測的糟糕程度,是個數值,若是模型的預測是完美的,那麼損失就是零,不然損失就很大,咱們能夠建立一個數學函數(損失函數)去有意義地彙總各個損失
機器學習

loss
藍色線表示預測,紅色箭頭表示各個損失,很顯然右側的要比左側的平均損失更小。一個最多見的損失函數是平方損失函數(squared loss / L_2 loss),一個樣本的平方損失就是標籤和預測值差的平方,即 (y - y')^2。整個數據集每一個樣本的平均平方損失被稱爲 均方偏差 MSE(mean squared error),就是把每一個樣本的平方損失加起來除以樣本數:

MSE = \frac{1}{N} \sum_{(x,y)\in D} (y - prediction(x))^2

下降損失

如何快速高效地肯定最好(如使 MSE 最小)的 bw_1 的值呢?最簡單的辦法就是先胡亂猜一個 bw_1 的值,計算一下損失,而後調整一下 bw_1 的值,計算損失,比較一下這兩次損失再決定如何調整 bw_1 的值(若是損失變小了說明調整的方向對了,繼續按照當前方向調整就好了,若是損失變大了就要考慮改變調整的方向了),理論上不斷地迭代試錯下去就能找到最好的 bw_1 的值
函數

iterative approach
使用迭代法(iterative approach)不單是由於它簡單直接,更是由於它在面對大型數據集時仍然表現良好
對於線性迴歸來講,選擇哪一個點做爲起始點並非很重要,好比咱們徹底能夠選擇 b = 0, w_1 = 0 做爲迭代的起始點。圖中綠色的框是最關鍵的部分,正是它決定了迭代的方向,即新的 bw_1 的值,迭代到整體損失再也不變化或者變化極其緩慢爲止,這時表示模型已收斂(converged)
假設咱們有充足的時間和計算資源去計算全部 w_1 的可能值和對應的損失,對於咱們一直研究的迴歸問題,損失 和 w_1 的關係圖形始終是凸形(convex)的,或者說關係圖形是個碗形:
convex
咱們的目標就是不斷改變 w_1 的值直到找到惟一的損失最小的那個最低點(斜率爲 0),即損失函數收斂的位置,迭代的策略有不少種,最多見的就是梯度降低法(gradient descent)
gradient descent
先隨便選一個點做爲起始點,如圖中的一個比 0 大一點的點,而後梯度降低算法會計算起始點處損失曲線的梯度,而損失的梯度在這裏等於曲線在該點的導數(斜率)。若是有多個權重,那麼梯度就是對應權重的偏導數,更準確點說梯度是全部自變量對應偏導數的矢量,梯度降低算法會沿着負梯度的方向一直走以便儘快下降損失,下一步的步長不能過小否則計算量會很大很慢,不能太大否則可能會致使模型偏離,因此這就涉及到學習速率(Learning Rate)的問題了
階梯降低算法把梯度乘以學習速率做爲下一步的變化量,而如何肯定學習速率每每依賴於經驗技巧,因此說學習速率是一個超參數(Hyperparameters): 在機器學習算法中程序員要扭動的旋鈕。每一個迴歸問題都存在一個 Goldilocks 學習速率,一維空間的理想學習速率是 \frac{ 1 }{ f(x)'' }(f(x) 對 x 的二階導數的倒數),二位或多維空間的理想學習速率是海森矩陣的倒數
除了學習速率還有一個問題須要考慮,那就是樣本的個數,若是樣本個數特別大,大到幾十億甚至幾千億的數量級,那麼每次迭代計算梯度時都須要輸入所有的樣本嗎(須要的樣本數量稱爲 batch)?因此爲了減小計算量能夠從數據集中隨機的選擇一些樣本,這樣通過不多的計算就能夠很快地收斂。而隨機梯度降低 SGD(Stochastic gradient descent)更是極端地每次迭代只使用一個樣本,通過足夠的迭代 SGD 能夠發揮做用可是噪音更多。Mini-batch SGD 是介於 full-batch 迭代和 SGD 迭代之間的折衷方案,Mini-batch SGD 一般會隨機選 10 到 1000 個樣本,它比 SGD 噪音更少,比 full-batch 更有效率
已經大概知道了如何有效地下降損失,那損失能下降到 0 麼?能根據已知的樣本訓練一個完美的模型麼?事實上並不能,也沒有必要,就算費盡心機地把模型訓練地對已知樣本的預測準確率是完美的 100%,可是面對新的樣本時仍是沒法達到 100%,由於「凡事皆有例外」,並且這樣看似完美的模型在面對新的樣本時預測的準確率甚至還不如其餘簡單的模型:
generalization
能夠看到,藍色點表明生病的樹,黃色點表明健康的樹,背景色表明模型的預測,左邊的圖表明訓練好的特別複雜可是損失很低的模型,可是在新的樣本上測試時(右圖)能夠發現模型表現特別糟糕,對大部分新數據的分類都不許確,這就涉及到泛化的問題了

泛化

泛化(Generalization)指對新的前所未見的數據進行正確預測的能力。上面的模型過擬合(overfit)了訓練數據的特性,一個過擬合的模型雖然在訓練過程當中損失很低可是在預測新數據時卻表現糟糕,那怎麼判斷一個模型對新的數據能不能作出很好地預測呢?這就涉及到正則化的問題了。過擬合之因此會出現問題是由於它爲了追求訓練時的完美讓模型變得異常複雜,而機器學習應該在擬合數據的同時儘量地保證簡單,應該符合奧卡姆剃刀定律,爲了方便驗證模型的泛化能力,能夠將數據集分紅專門用來訓練的訓練集和專門用來測試的測試集,在測試集上表現良好每每能代表在新的數據集也能表現良好,前提是測試集足夠大且不會反覆用相同測試集做假
泛化過程通常須要知足三項基本假設:工具

  • 咱們從分佈中隨機抽取獨立同分布(i.i.d)的樣本,樣本以前不會互相影響
  • 分佈是固定的(stationary),分佈在數據集內不會變化
  • 咱們從同一分佈(same distribution)的數據劃分中抽取樣本

實際上,有些狀況下可能會違反其中一些假設,如廣告推薦模型可能依賴於用戶以前看過的廣告,這違反了第一條假設,而一旦違反任意一項假設,就表示咱們已經失去了重要的理論支持,就必須得時刻注意各項指標了
既然測試集應該足夠大,那多大好呢?怎麼合理地把數據集分紅訓練集和測試集呢?訓練集和測試集應該相互獨立,但 訓練集的規模越大模型的學習效果就越好,測試集規模越大咱們咱們對評估指標的信心就越足,若是數據集的規模自己就很大就簡單多了,但若是數據集規模很是小,就要先進行像交叉驗證(cross-validation)之類的複雜操做了
測試集應該知足兩個條件:學習

  • 規模足夠大以產生具備統計意義的結果
  • 可以表明整個數據集,不要選擇與訓練集不一樣特徵的測試集

永遠不要對測試集進行訓練,若是你發現模型在測試集上預測的準確度特別高,甚至比在訓練集上的還高,先不要興奮,你極可能把一些測試數據用於訓練了,得從新檢查一下訓練集是否是包含了一些訓練集的數據
在訓練集上訓練模型,在測試集上評估模型,再根據評估的結果調整模型,如此循環下去直到能選擇一個在測試集上表現最好的模型。這樣的流程有點問題,咱們可能無形中對測試數據的特性進行了過擬合,因此爲了不出現這種狀況,咱們從數據集中再單獨劃分出一些數據做爲驗證集,這樣迭代評估的時候只在驗證集上評估便可,測試集只用來確認結果,要確保在測試集上得出的結果基本符合在驗證集上得出的結果,若是不符合就說明對驗證集進行了過擬合
測試

validation set

特徵工程

咱們彷佛忘了一個最基本的問題,那就是如何從原始數據中抽象出供模型使用的特徵值,而從各類各樣的數據源中提取數據,而後再根據這些數據建立特徵向量的過程被稱爲特徵工程(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):

extreme outliers

有時咱們須要對浮點數進行分箱(Binning):
bin
緯度原本是連續的浮點類型的,可是小緯度內房價的差異並非連續的,差異通常也不大,因此能夠把緯度分箱,緯度 37.4 能夠表示爲 [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
到如今爲止,咱們能夠假設用於訓練和測試的數據是可靠的了,咱們像挑出壞蘋果同樣把很差的樣本挑出去了:

  • 遺漏值,如某個房屋的年齡忘寫了
  • 重複樣本,如服務器錯誤地把相同的日誌上傳了兩次
  • 不良標籤,如一我的錯誤地把一個橡樹圖片標記爲楓樹
  • 不良特徵值,如一我的把編號多輸了幾位

良好的機器學習依賴於良好的數據

特徵組合

到目前爲止,咱們研究的都是線性問題,線性學習器不但簡單並且能夠很容易擴展到大型數據集,可是若是要建模的問題很複雜怎麼辦?

linear problem
這時候就不能用 y = SIGN(b + w_1x_1 + w_2x_2) 去線性擬合了,可能你已經想到了,一種機智的作法是額外定義一種特徵 x_3 = x_1x_2,這樣咱們就能夠在線性模型中使用它了 y = SIGN(b + w_1x_1 + w_2x_2 + w_3x_3),若是 x_1x_2 的乘積爲正,那麼就是一三象限的藍色點,不然就是二四象限的橙色點,這樣咱們就能夠在線性模型中學習非線性的規律了,而像 x_3 這種把幾個特徵乘起來的合成特徵(synthetic feature)被稱爲特徵交叉(feature cross),一些有趣的研究代表將特徵交叉乘積得到的線性學習效果和深度網絡結合起來能夠實現極其強大的建模能力
特徵交叉也會帶來一些問題,好比幾個特別大特別稀疏的特徵交叉後將是一個更大的特徵表示,這會致使模型大小膨脹,佔據大量 RAM 內存,減緩運行時間,獲得的噪聲係數可能會致使過擬合,這就須要更復雜的如 L_0L_1 正則化去解決這個問題了

正則化

在研究泛化問題時咱們重點關注了過擬合的問題,若是咱們過於追求在訓練集上的損失極低,就可能會出現過擬合訓練集而帶來的問題:

regularization

能夠發現,在訓練損失愈來愈低時,驗證損失可能會愈來愈高,就像咱們只跟一我的練習外語交流同樣,剛開始進步很是快,可是隨着時間的發展你會慢慢習慣他的表達方式和發音習慣(就像過擬合了訓練數據同樣),致使再跟其餘人交流外語時變得很困難。那怎樣處理過擬合呢?最簡單的就是正則化(Regularization),正則化有不少策略,最簡單的就是儘早中止(Early stopping 早停法),也就是在收斂前(紅線上升以前)中止訓練,可是實際上很難實現,還有一種策略就是經過懲罰模型複雜度來儘量地下降模型的複雜度,有時也稱爲結構式風險最小化(structural risk minimization)

\text{minimize: } Loss(Data\;|\;Model) + complexity(Model)

咱們要平衡這兩個因素,讓損失和複雜度都儘量地低,也就是說,要確保正確的訓練數據,又不過分信賴訓練數據。那如何定義模型複雜度呢?最簡單的就是選擇較小的權重,也就是說即便參數小到能夠忽略咱們依然能夠獲取正確的訓練樣本,從數學上來講通常使用 L_2 正則化,也稱爲嶺正則化,在這種正則化策略中,咱們對權重的平方和進行懲罰,若是熟悉貝葉斯先驗機率就知道這是一種先驗機率,在咱們知道訓練樣本以前就猜到權重應該是以 0 爲中心呈正態分佈的,並且數值不會太大。以數學的方式表示上面的公式爲

Loss(Data|Model) + \lambda \left(w_1^2 + \ldots + w_n^2 \right)

能夠看到第一項下降損失的過程取決於訓練數據,而第二項簡化模型則與數據無關,這兩項經過 \lambda 實現了平衡,\lambda 的選取取決於你和實際狀況,若是有大量訓練數據且訓練數據與測試數據看起來一致,知足獨立同分布,你可能不須要多少正則化,不然可能須要大量正則化和交叉驗證,\lambda(lambda)也被稱爲正則化率(regularization rate),若是 lambda 值太高,模型會很是簡單,但會面臨數據欠擬合的風險,模型將沒法充分了解訓練數據以進行有用的預測,若是 lambda 值太低,模型會比較複雜,會面臨數據過擬合的風險,模型會過多解讀訓練數據的特殊性從而很難泛化到新的數據。將 lambda 值設爲 0 可完全取消正則化,此時訓練的惟一目的就是最小化損失,可是會使過擬合的風險達到最高。
L_2 正則化鼓勵 non-informative 特徵的權重趨向於 0,可是當這類特徵剛好與標籤相關時,會致使模型學到一箇中等的權重,此時,模型錯誤地給了 non-informative 特徵一些本應該給 informative 特徵的信任。L_2 正則化對大權重的懲罰比小權重更嚴厲,所以,即便一個權重降低得比另外一個快,L_2 正則化也會強制使較大權重的那個降低得比較小的更快。L_2 正則化與學習速率息息相關,很容易讓人困惑
L_2 正則化雖然可使權重變小,但不能使他們正好爲 0,L_0 正則化雖然可使權重爲 0,這樣能夠直接忽略某些特徵進而減小內存消耗,可是它會將咱們的凸優化問題變成非非凸優化問題(NP 困難),因此 L_0 正則化並不實用。而 L_1 正則化具備凸優化的優點,能夠進行有效計算。L_2 會下降權重的平方,L_1 會下降權重的絕對值,L_2 的導數是 2 乘以權重,L_1 的導數是與權重無關的常量 k,也就是說 L_2 每次移除權重的 x%,一般不會減到 0,L_1 每次從權重中減去固定的常數,若是減法使權重從 +0.1 變成 -0.2,因爲懲罰的是絕對值,因此權重會變成 0

邏輯迴歸

不少問題都須要把 機率估計 做爲輸出,好比圖片中的動物是貓的機率是多少、狗晚上吵醒人的機率是多少,既然是機率,那麼機率值確定是 0 到 1 之間,那咱們以前學到的線性模型的輸出能強制限制到 0 到 1 之間麼?很顯然不太現實,那咱們就要想出一種不一樣的損失函數和預測方法使機率值很天然的處於 0 到 1 之間,咱們將這種想法稱爲邏輯迴歸(Logistic Regression)。邏輯迴歸的機率就很是有用了,甚至能夠被看作實際機率去作有用的預測,用這個機率乘以想要預測的項就能夠獲得預期值。它在二元分類(binary classification)中也很是有用,如一封郵件是垃圾郵件的機率是多少,一枚硬幣朝上的機率是多少。那邏輯迴歸模型是怎樣保證輸出老是介於 0 到 1 之間呢?咱們來看一下 S 型函數(sigmoid function):

y = \frac{1}{1 + e^{-z}}

sigmoid function
邏輯迴歸模型也相似:

y' = \frac{1}{1 + e^{-(z)}}

l
y' 表示邏輯迴歸模型的輸出, z 表示線性模型的 b + w_1x_1 + w_2x_2 +  ... w_Nx_Nz 也稱爲對數概率(log-odds),由於 z = log(\frac{y}{1-y}),若是是二元分類問題,那麼 y1 - y 就是相對的兩個機率
咱們最開始討論的線性迴歸用的損失函數是平方損失(Squared Loss),而邏輯迴歸用的是對數損失(Log Loss):

\text{Log Loss} = \sum_{(x,y)\in D} -y\log(y') - (1 - y)\log(1 - y')

其中 (x,y)\in D 表示包含不少有標籤樣本的數據集,y 表示有標籤樣本中的標籤,y' 表示預測的值
在邏輯迴歸模型中正則化變得更加劇要,若是沒有正則化,那麼邏輯迴歸的漸進性將在高維上讓損失趨向於 0 ,若是未指定正則化函數,模型將變得徹底過擬合,所以邏輯迴歸模型一般使用 L_2 正則化或早停法下降模型的複雜度

分類

機器學習模型解決的最多見的問題就是分類問題,如郵件是正常郵件仍是垃圾郵件,圖片中的物體是什麼,咱們可使用邏輯迴歸做爲分類的基礎,給 機率輸出 應用 固定的閾值(threshold)就好了,如一封郵件爲垃圾郵件的機率超過了 0.8,咱們就認爲它是垃圾郵件,0.8 就是分類的閾值(分類閾值 classification threshold 也被稱爲斷定閾值 decision threshold),一旦選定了分類閾值,那咱們怎麼評估這個閾值下模型的質量呢?最傳統的方式就是用準確率(accuracy)這個指標,也就是預測正確數除以總數。可是準確率有時會成爲不好或者誤導性的指標,好比當不一樣錯誤的類型代價不同時,當分類不平衡(正例或負例極少)時(一個廣告的點擊率是千分之一萬分之一甚至更低,那麼一個模型預測一個廣告不被點擊的的準確率是 99.999% 沒有任何意義),此時區分不一樣錯誤的類型可能會有所幫助:

  • 真正例(True Positives):狼真的來了,正確喊出狼來了
  • 假正例(False Positives):狼沒有來,卻喊狼來了,全部人都很生氣
  • 假負例(False Negatives):狼真的來了,卻沒發現,後果更嚴重
  • 真負例(True Negatives):狼沒有來,也沒喊狼來了,一切安好

也就是說,TP 和 TN 都是正確的預測,而 FP 是指模型錯誤地將負類別預測成正類別,FN 更是嚴重錯誤地將正類別預測成負類別
如今假如出現了 100 次狼來了事件,有 1 次狼真的來了小男孩喊狼來了,有 1 次狼沒來卻喊狼來了,有 8 次狼來了卻沒喊,有 90 次 狼沒來也沒喊,那麼小男孩的準確率高達 \frac{TP+TN}{TP+TN+FP+FN} = \frac{1+90}{1+90+1+8} = 0.91,從 91% 的準確率來看這個小男孩還挺好,可是事實是這樣的嗎?在 91 次狼沒來中小男孩有 90 次沒喊狼來了,可是,在 9 次狼真的來了的時候小男孩卻只有 1 次喊狼來了,這是多麼可怕啊!若是是腫瘤診斷模型,9 個惡性腫瘤中只有 1 個被發現是惡性腫瘤,那後果將更加的可怕
所以咱們須要一些新的指標來評估,如精確率(precision),也就是小男孩喊狼來了的狀況中有多少次是對的,\frac{TP}{TP+FP} = \frac{1}{1+1} = 0.5。另外一方面,召回率(recall)是指在全部嘗試進入村子的狼中咱們發現了多少頭,即正確被識別爲正例的比例,\frac{TP}{TP+FN} = \frac{1}{1+8} = 0.11。有趣的是這些指標每每是此消彼長的,如爲了把召回率作得好只要有風吹草動就喊狼來了,這會下降分類閾值,爲了精確率高只有在確認狼真的來了才喊狼來了,這會提升分類閾值,所以只有這兩方面都作得好才能評價模型的優劣。通常來講,提升分類閾值會減小假正例,從而提升精確率
你可能會說,那我把全部可能的分類閾值都試一下看那個閾值下模型的表現更好不就好了麼?事實上確實有這樣的,叫 ROC 曲線
真正例率 TPR(True Positive Rate)爲 TPR = \frac{TP} {TP + FN},和召回率同樣
假正例率 FPR(False Positive Rate)爲 FPR = \frac{FP} {FP + TN}
將不一樣閾值下的 TPR 和 FPR 值的點連成一條曲線就是 ROC 曲線:

roc
觀察這個 ROC 曲線,咱們驚訝地發現曲線下的面積就能夠很好地表示分類模型的好壞,面積越大,那麼隨機選擇一個正樣本和一個負樣本時正樣本排在前面的機率就越大。而這個曲線下面積簡稱爲 AUC(Area under the ROC Curve)
還有一個指標,那就是誤差,迴歸模型應該是無誤差的,也就是說,預測的平均值和觀察到的平均值差很少是同樣的,預測誤差(Prediction bias)等於預測的平均值減去數據集中標籤的平均值,若是預測誤差不爲 0 那麼說明模型可能有問題,須要找一下是什麼緣由致使的非零誤差,固然,即便是預測誤差爲零也不能說明模型是完美的,還要看其餘指標。形成預測誤差的緣由可能有特徵集不完整,數據集中的噪音,有誤差的訓練樣本,太強的正則化等等,能夠經過添加校準層(calibration layer)來調整模型的輸出,從而減小誤差,可是這只是下策,由於這個治標不治本,並且你還得維護這個脆弱的系統

神經網絡

當問題複雜到沒法用線性迴歸解決怎麼辦?即便是利用特徵交叉也沒法解決非線性的問題呢?這個時候咱們但願經過某種方式,讓模型本身學習非線性的規律,而不用咱們手動爲它設置參數。這一願景能夠經過深度神經網絡(Deep Neural Networks)實現,它在複雜數據問題上作得特別好,例如圖片數據,視頻數據,音頻數據等。先來看一下線性模型的表示,如 y = b + w_1x_1 + w_2x_2 + w_3x_3:

linear
每一個特徵輸入都有一個權重,這些權重以線性方式結合到一塊兒產生惟一的輸出,也就是各個輸入特徵的加權和,那咱們怎麼把它擴展到非線性模型呢?
咱們發現,無論咱們以線性的方式往中間加多少層,線性函數的組合依然是線性函數,模型依然是線性的。所以咱們想辦法加一些非線性函數進去,這些非線性函數可能位於任何小的隱藏式節點的輸出中:
這種非線性函數也被稱爲激活函數(Activation Function),常見的激活函數有 S 型激活函數和 ReLU 激活函數,S 型函數以前提到過,能夠把加權和平滑地限制到 0 到 1 之間,而 ReLU(rectified linear unit) 激活函數更加的簡單,它接受線性函數,並在零值處截斷,即 F(x)=max(0,x)
事實上,任何數學函數均可以做爲激活函數,假設用 \sigma 表示激活函數,那麼網絡中節點的值就是 \sigma(\boldsymbol w \cdot \boldsymbol x+b)
如今,咱們有了人們常說的神經網絡的全部標準組件:

  • 一組節點,相似於神經元,位於層中
  • 一組權重,表示每一個神經網絡層與其下層的關係,下面的層能夠是另外一個神經網絡層也能夠是其它類型的層
  • 一組誤差,每一個節點一個誤差
  • 激活函數,用來轉換層中每一個節點的輸出,不一樣層可能有不一樣的激活函數

訓練神經網絡最經常使用的訓練算法就是反向傳播算法(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 模型,其中每一個輸出節點表明不一樣的類型:

on-vs.-all
咱們已經知道,邏輯迴歸在處理二元分類問題時頗有用,它能夠把輸出(機率)限制在 0 到 1 以內, 若是一封郵件是垃圾郵件的機率是 80%,那麼是正常郵件的機率就是 20%,加起來確定等於 1,那怎麼把這個擴展到多類別問題中呢?答案是 Softmax,它爲每一個類別分配一個機率,這些機率加起來必須等於 1,這會幫助訓練比其餘方式更快地收斂:
softmax
Softmax 層是輸出層以前的神經網絡層,必須和輸出層有同樣的節點數,它的公式本質上也是邏輯迴歸公式的延伸:

p(y = j|\textbf{x})  = \frac{e^{(\textbf{w}_j^{T}\textbf{x} + b_j)}}{\sum_{k\in K} {e^{(\textbf{w}_k^{T}\textbf{x} + b_k)}} }

當類別不少時,Softmax 的代價會變得很大,因此除了 Full Softmax 還有一種策略叫 Candidate sampling,對全部正例標籤計算機率,但只對負例標籤的隨機樣本計算機率,如咱們想肯定圖片是小獵犬仍是尋血獵犬,咱們就沒必要爲每一個非狗樣本提供機率了
Softmax 假設每一個樣本只能有一個類別,若是一個樣本同時屬於多個類別,那麼你就不能用 Softmax,你只能依賴多個邏輯迴歸

思考

如今咱們思考一個問題,咱們在讀一本書的時候,或者在思考的時候,腦海裏總有一個聲音跟你說話,這個聲音很像你本身的聲音,但又不是你的聲音,若是你看過西部世界,或者對心理學有過了解,你可能知道有一種理論叫作二分心智。二分心智通常被看作是人類意識的起源,而人們對於意識這種東西並非真正的瞭解,可是人類卻總想扮演上帝的角色,想要賦予一我的造的機器意識。上個世紀人們開動本身的想象力,想象着賦予機器意識的那一天,各類科幻電影更是把這種想象表達的淋漓盡致,然而到如今人們才冷靜下來,發現人工智能還有很長很長一段路要走,與其建立人工智能不如利用已有的知識水平爲人工智能鋪路,不如將已有的人工智能成果(機器學習)應用於現實生活中,Google 的 AI 向善就是很好地方式,利用 AI 技術能夠預測洪水,能夠用於醫療,能夠預測疾病,能夠幫助聾啞人跟正常人溝通等等等等
機器學習做爲實現 AI 的主要手段,涉及到的知識和領域很是多,而 Google 提供的 TensorFlow 平臺讓普通人建立或訓練機器學習模型成爲可能,做爲普通人,你沒法提出革命性的人工智能理論,甚至沒法理解不少數學知識,可是有了 TensorFlow 平臺,有了一些訓練好的模型,你就能夠建立本身想要的,能幫助你本身或者幫助他人解決問題的模型

參考

附錄

TensorFlow

  • 「Goldilocks and the Three Bears」 的故事講述了 Goldilocks 小女孩闖入了已經外出的三隻小熊的家,她以爲三把椅子中不硬不軟的椅子坐起來最舒服,三碗粥中不熱不冷的粥最好吃,三張牀中不硬不軟的牀睡着最舒服。因此 Goldilocks 一般用來形容剛恰好的東西
  • 奧卡姆剃刀是指簡約法則,簡單的解決方案相對於複雜的解決方案更多是正確的,也就是說,大道至簡
  • one-hot encoding 一般被翻譯爲獨熱編碼,全部編碼位中只有一個是熱的,也就是 1,多個 1 的編碼被叫作 multi-hot encoding
  • feature cross 中的 cross 源自 cross product,即叉積/向量積
  • 能夠下載 Jupyter Notebook 在本地作練習題:download.mlcc.google.cn/mledu-exerc…
  • steps 表示訓練迭代的總次數
  • batch size 表示每次迭代須要的樣本數
  • 訓練模型須要的總樣本數等於 batch\,size * steps
  • periods 表示報告的粒度,每一個 periods 內須要的訓練樣本數等於 \frac{batch\,size * steps} {periods}
相關文章
相關標籤/搜索