1. 程式人生 > 實用技巧 >【機器學習與R語言】9- 支援向量機

【機器學習與R語言】9- 支援向量機

目錄

1.理解支援向量機(SVM)

1)SVM特點

  • 支援向量機和神經網路都是“黑箱模型”的代表:潛在的模型基於複雜的數學系統,而且結果難以解釋。
  • SVM的目標是建立一個平面邊界(“超平面”),使得任何一邊的資料劃分都是均勻的。結合了kNN和線性迴歸。
  • 幾乎適用於所有的學習任務,包括分類和數值預測。

2)用超平面分類

  • 線性可分:可以由一條直線或一個平面進行劃分

  • 最大間隔超平面(MMH):很多線都能對資料點進行分類,但要尋找能使類形成最大間隔的那條線(因為在邊界附近點位置的微小變化可能導致某些點落線上之外),支援向量就是每個類中最接近最大間隔超平面的點。所以單獨使用支援向量,就能定義最大間隔超平面。

  • 線性可分條件下,最大間隔超平面要儘可能遠離兩組資料點的外邊界(“凸包”),最大間隔超平面就是兩個凸包之間的最短距離直線的垂直平分線,可通過“二次優化”演算法實現。

  • 非線性可分:資料不是線性可分的條件下,使用一個“鬆弛變數”來建立一個軟間隔,允許一些點落線上不正確的一邊。

  • 非線性可分中的成本引數C:即所有違反約束的點,試圖使總成本最小,而非尋找最大間隔。修改C將調整對於落在超平面錯誤一邊的案例的懲罰。C越大,實現100%分離的優化就越困難。較小的C將把重點放在更寬的整體邊緣。

3)對非線性空間使用核函式

  • 另一種處理非線性問題的方法,就是使用“核技巧”的處理將問題對映到一個更高維的空間,這樣非線性關係可能會變為完全線性。

  • 從本質上講,核技巧涉及一個新增能夠表述度量特徵之間數學關係新特徵的過程。
  • 非線性核SVM的特點:

  • 核函式:線性核函式(特徵的點積),多項式核函式(加一個非線性資料變換),S形核函式(類似神經網路的S形啟用函式),高斯RBF核函式(類似RBF神經網路)。多數情況下,核函式的選擇是任意的,因為效能可能只有輕微的變化。

2. 支援向量機應用示例

使用SVM進行光學字元識別(OCR影象處理):通過將印刷或手寫文字轉換為電子形式,儲存在資料庫種來處理紙質檔案。

難點:

  • 影象的規則模式很難嚴格定義
  • 影象資料往往是噪聲資料

1)收集資料

資料集包含26個大寫英文字母的2000個案例,使用20種不同的隨機重塑和扭曲的黑斯和白色字型印刷。
假設當影象字元被掃描到計算機,轉換為畫素,有16個統計屬性(如水平垂直尺寸,黑色畫素比例等)。

資料下載:

連結: https://pan.baidu.com/s/1q8zHWkMZcapwnX90PA4hOg 提取碼: eaqt

2)探索和準備資料

SVM需要所有特徵都是數值型的,而且每一個特徵需要縮小到一個相當小的區間內。所以不要有因子,而且要做標準化。這裡略過沒做。

## Example: Optical Character Recognition ----

## Step 2: Exploring and preparing the data ----
# read in data and examine structure
letters <- read.csv("letterdata.csv")
str(letters)

# divide into training and test data
letters_train <- letters[1:16000, ] #80%
letters_test  <- letters[16001:20000, ] #20%

3)訓練資料

SVM的R包有e1071,klaR和kernlab等,這裡用kernlab(與caret連用,允許SVM使用各種自動化方法進行訓練和評估)。

kernlab::ksvm(target~predictors, 
                 data=mydata, 
                 kernel="rbfdot", #隱非線性對映,rbfdot/polydot/tanhdot/vanilladot
                 c=1) #違法約束條件的懲罰,較大的c值導致較窄的邊界

訓練:

## Step 3: Training a model on the data ----
# begin by training a simple linear SVM
library(kernlab)
letter_classifier <- ksvm(letter ~ ., data = letters_train,
                          kernel = "vanilladot")  #預設使用高斯RBF核函式,這裡用線性函式

# look at basic information about the model
letter_classifier

4)評估模型

letter_predictions <- predict(letter_classifier, letters_test)

head(letter_predictions)

table(letter_predictions, letters_test$letter)

# look only at agreement vs. non-agreement
# construct a vector of TRUE/FALSE indicating correct/incorrect predictions
agreement <- letter_predictions == letters_test$letter
table(agreement)
prop.table(table(agreement))


識別的準確度大概為84%。

5)提高效能

可以使用一個更復雜的核函式,將資料對映到更高維的空間,獲得一個較好的模型擬合度。如試試高斯RF核函式,或者修改成本約束引數C值來修正決策邊界的寬度。

## Step 5: Improving model performance ----
set.seed(12345)
letter_classifier_rbf <- ksvm(letter ~ ., data = letters_train, kernel = "rbfdot") #高斯RBF核函式
letter_predictions_rbf <- predict(letter_classifier_rbf, letters_test)

agreement_rbf <- letter_predictions_rbf == letters_test$letter
table(agreement_rbf)
prop.table(table(agreement_rbf))

訓練時間更長,將準確度提高到了93%。