Sweetkang 的機器學習實驗室 (1)

前言

近年來,Machine Learning 在許多領域上已然取得了可喜的成就,很是火熱。就我我的來說,有意將業餘 Sport Programming 的範圍擴展一下,譬如 Topcoder Marathon。在解決實際問題中,方法太 Naive 每每效果不怎麼樣,依舊須要學習一下相關的基礎知識。
本系列文章主要基於 Coursera 的 Machine Learning,我社內部 Machine Learning 課裏能說的一部分,wikipedia,以及一些其餘的讀物。算法

一些概念

機器學習的定義

對於某類任務T和性能度量P,若是一個計算機程序在T上以P衡量的性能隨着經驗E而自我完善,那麼咱們稱這個計算機程序從經驗E中學習。
這是一個比較嚴謹的界定機器學習問題的 Guideline。若是有什麼問題搞不清楚是否是這個範疇,能夠嘗試套用定義來檢查:任務是什麼,性能度量是什麼,經驗是什麼,性能是否因爲經驗而提高。機器學習

一些機器學習應用

  • 手寫識別,Optical character recognition
  • 文本分類,識別垃圾郵件,工口反動內容等
  • 語音識別,機器翻譯等
  • 圖像識別,人臉識別
  • 識別釣魚網站
  • 機器人,無人機等

一些機器學習問題

  • 分類(Classification):給每組輸入打一個 tag,譬如手寫識別,實際上至關於對一個圖像進行分類
  • 迴歸(Regression):對每組輸入,預測一個實數值,譬如預測股市行情
  • Ranking:將輸入排序,譬如對搜索引擎的搜索結果,推薦系統等
  • 聚類(Clustering):將輸入數據分紅若干類
  • 降維(Dimensionality reduction):尋找輸入數據的低維表示

一些定義

  • 樣例(Example):某個實體
  • Features:實體的屬性集合,一般用向量來表示
  • Label:對於分類問題,就是樣例屬於哪一類;對於迴歸問題,就是實數值
  • 訓練集(Training Data):用來訓練模型
  • Validation set:每每用來調整學習的參數
  • 測試集(Test Data):用來評估模型的表現
  • 監督學習:從給定的訓練數據集中學習出一個函數,當新的數據到來時,能夠根據這個函數預測結果
  • 非監督學習:訓練集沒有人爲標註的結果
  • 區別:訓練數據有沒有標註

機器學習三要素:模型,策略,算法

  • 模型:就是所要學習條件機率分佈或決策函數
  • 策略:按照什麼樣的準則來學習或者挑選模型
  • 算法:學習模型的具體計算方法,即用什麼樣的方法來求得最優解

我的理解,模型表明着你如何看待這個問題。譬如識別一個東西是否是汽車,若是你認爲識別的依據是:金屬殼 + 車燈 + 反光鏡 + 車輪子 … = 汽車,這個思路就比較接近基於規則,決策樹,貝葉斯;若是你考慮這個東西和見過的什麼東西比較類似,就是 KNN 的思路。以後咱們要不斷學習的實際上都是模型。ide

常見的兩個策略是經驗風險最小化和結構風險最小化。經驗風險最小化意味着咱們傾向於對訓練數據取得精準的預測。這個想法很直接,且有必定道理:模型在訓練數據上表現不佳,更沒法期望在測試數據上取得好結果。可是,在訓練集上表現好的模型,未必在測試集上表現好。一般來說,簡單的模型會更有通用性,而複雜的模型,每每會有一些 hardcode 了訓練數據的感受,效果反而不必定好。結構風險最小化在經驗風險最小化的狀況下,加入一些因子來限制模型的複雜度。函數

根據策略,能夠列出一個須要最優化的式子。算法就是求這個式子最優或者較優解的方法。最多見的方法是梯度降低,其餘技能尚未 get,就暫不討論了。性能

梯度降低法(Gradient Descent)

暫時忘記機器學習,如今須要優化一個形如 \( y = f(\theta) \) 的式子,求 \( x = argmax f(\theta) \) 或 \( x = argmin f(\theta) \),有什麼好的辦法麼?
梯度降低法,基於這樣的觀察:若是實值函數\( F(x) \)在點 a 處可微且有定義,那麼函數 \( F(x) \)在 a 點沿着梯度相反的方向 \( -F\nabla(a) \) 降低最快。所以,若是 \( b = a - \gamma\nabla F(a) \) 對於 \( \gamma > 0 \) 且爲一個夠小數時成立,那麼 \( F(a) \geq F(b) \)。換句話說,咱們給出一個對極值的估計 a,不斷迭代求 \( a = a - \gamma\nabla F(a) \) ,就能取得一個極值。學習

用一個實際例子來演示一下:對二次函數 \( f(y) = x^{2} + 2x + 10 \) ,使用梯度降低法求 \( min f(x) \) 和 \( argmin f(x) \),函數圖像以下:測試

結論不管是從圖像仍是初中數學的角度來看都很簡單。咱們看看梯度降低算法是如何進行的:優化

f <- function(x) {
    x^2 + 2 * x + 10
}
df <- function(x) {
    2 * x + 2
}

x <- 5
y <- f(x)
learning.rate <- 0.3
plot(f, -5, 5)

while (TRUE) {
    nx = x - df(x) * learning.rate
    ny = f(nx)
    if (abs(x - nx) < 0.01) 
        break
    arrows(x, y, nx, ny, col = "red")
    x = nx
    y = ny
    print(c(x, ny))
}

plot of chunk unnamed-chunk-1

## [1]  1.40 14.76
## [1] -0.040  9.922
## [1] -0.616  9.147
## [1] -0.8464  9.0236
## [1] -0.9386  9.0038
## [1] -0.9754  9.0006
## [1] -0.9902  9.0001

不管是簡單問題仍是複雜問題,參數 learning.rate,也就是前文中提到的\( \gamma \)的選擇很是重要。Learning rate 太小則須要更多的迭代。Learning rate 過大則會出現之字降低,甚至之字上升。網站

看一個非凸,多元函數的例子:Rosenbrock函數:\( f(x, y) = (1-x)^2 + 100(y-x^2)^2 \) 很顯然 x = y = 1 的時候能夠取得最優解,可是求解過程倒是很坑的。我們把 x = y = 1 附近的圖像畫出來:ui

plot of chunk unnamed-chunk-2

再研究一下 x = 1 時的切面:

plot of chunk unnamed-chunk-3

大概能看出來,這個函數在解附近有個很大的很平的底。。。貼一段代碼,你們能夠 play 一下:

f <- function(x, y) { (1 - x) ** 2 + 100 * (y - x ** 2) ** 2}
df.dx <- function(x, y) { x * 2 - 2 - 400 * y + 400 * x ** 3}
df.dy <- function(x, y) { 200 * y - 200 }

x <- runif(1, 0, 2)
y <- runif(1, 0, 2)
z = f(x, y)
learning.rate = 1E-6
eps <- 1E-10

while (TRUE) {
  new.x = x - df.dx(x, y) * learning.rate
  new.y = y - df.dy(x, y) * learning.rate
  new.z = f(new.x, new.y)
  if (abs(new.z - z) < eps) break
  x = new.x
  y = new.y
  z = new.z
  print(c(x, y, z))
}

能夠調整一些參數,譬如 learning.rate,eps 去看看某些現象。咱們能夠看到他最後幾步的收斂極爲緩慢,若是 learning.rate 過大,還會之字上升等等。總的來說,選擇一個合適的 learning rate 是很是重要的,除去經驗性的技巧,每每也只好枚舉了,看看 cost function 的變化狀況,若是降低過慢,則須要增大 learning rate,若是反而增加了,則須要減小 learning rate。這也就是爲何某些時候咱們須要一個比較小的 validate set,咱們能夠按期的在訓練中的模型上跑一下 validate set,看一下 cost function 的變化,從而決定 learning rate 的調整。

一元線性迴歸

以 Stanford Machine Learning 爲例:根據房子的面積預測房價。我們來把一些概念對上號:

  • Training Set:m 個二元對 \( (x_{i},y_{i}) \)
  • feature:房屋面積,即 \( x_{i} \)
  • label:房價,即 \( y_{i} \)
  • 這是監督學習,由於測試數據是標註過的
  • 這是迴歸問題,由於 label 是連續值
  • 模型:一元線性迴歸,這個想法很顯然
  • 策略:\[ minimize J(\theta_{0}, \theta_{1}) = \sum_{i=1}^{m}(\theta_{0}x_{i} + \theta_{1} - y_{i})^2 \]

  • 算法:注意此時咱們要求解的是 \( \theta_{0},\theta_{1} \),而 \( x_{i},y_{i} \) 都是已知量,能夠考慮求偏導,而後用梯度降低求解,這就是技能範圍之內的東西了,由於每次迭代用了全部的 Training Data,因此這個作法叫 Batch Gradient Descent。

實際應用中,比較好用的算法是 Stochastic Gradient Descent,Batch Gradient Descent 每次迭代,對 \( \sum_{i=1}^{m}(\theta_{0}x_{i} + \theta_{1} - y_{i})^2 \) 求導,至關於 \[ \theta_{0} = \theta_{0} - 2\alpha\sum_{i=1}^{m}(\theta_{0}x_{i} + \theta_{1} - y_{i})x_{i} \] \[ \theta_{1} = \theta_{1} - 2\alpha\sum_{i=1}^{m}(\theta_{0}x_{i} + \theta_{1} - y_{i}) \] 而 Stochastic Gradient Descent 至關與把 Batch Gradient Descent 的 1 次迭代拆成了 m 次,每次對 \( (\theta_{0}x_{i} + \theta_{1} - y_{i})^2 \) 求導,而後 \[ \theta_{0} = \theta_{0} - 2\alpha(\theta_{0}x_{i} + \theta_{1} - y_{i})x_{i} \] \[ \theta_{1} = \theta_{1} - 2\alpha(\theta_{0}x_{i} + \theta_{1} - y_{i}) \]

Batch Gradient Descent 能夠求得更精確的解,可是若是模型複雜,或者數據量大,就很難直接 Batch Gradient Descent 了。

相關文章
相關標籤/搜索