MaDi's Blog

一個紀錄自己在轉職軟體工程師路上的學習小空間

0%

機器學習(Machine learning)-數學整理

談到AI,不外乎是機器學習(Machine Learning)和深度學習(Deep Learning),機器學習主要是以演算法來達到人工智慧的目的,過程牽涉到許多數學,為了讓自己不要只是會呼叫套件,還得懂一點背後的數學,特別紀錄這篇網路上的教學,提供給未來的自己參考。

感知器(Perceptron)

介紹:

  1. 感知器又被稱為 PLA(Perceptron Learning Algorithm)
  2. 是機器學習中最早的演算法
  3. 限制: 唯有在資料是線性可分的情況下能夠被正確地分類。也就是說在二維平面上可以被一條線切開,三維空間內可以被一個面所切開…
  4. 是以生物的”神經元模型”為基礎所開發出來的演算法

數學:

把不等式右邊的threshold移到左邊,並以”某個值”來表示他,為了配合整個式子的符號,這邊就用w0*x0來表示,但是 x0永遠等於1。

因此,整個不等式最後長這樣:

也就是說改成用>0或是<0來區分分類的結果。而式子裡面的 權重wi正是模型要不斷訓練才能得到的資訊,也就是為什麼我們要訓練模型的原因。

而這個不等式判斷大於零還是小於零來做為分類結果的規則,就是激勵函式(activation function)

激勵函式在做的事情就是

回頭看這個不等式,其實就是一個平面,wi是權重,也是這個平面的法向量,所以我們在訓練模型的過程中就是去決定一個最佳的法向量,也就是決定一個最佳的平面,達到分類的成果。

接著,我們要定義預測錯誤的時候,該怎麼更新權重,Perceptron更新權重的規則是這樣:

當第一次分類的結果中有分錯的,在迭代第二次之前先更新權重,而這裡的y指的是理論上要分對的output是什麼,也就是所謂的正解。

實例:

舉例來說,今天有個二分類問題,在二維平面上各自有一群data,我們希望找到一條線可以將它完美的切分開來:

首先,第一步初始化權重,假設 w=[0, 0] (也可以隨意假設),而 x = [1,2],透過 wi*xi 計算完會得到0,因為<=0,所以會把所有分類都分成-1,導致理論上要分成1的全部分錯。

現在假設分錯的某一筆資料是 x = [3,10],在迭代第二次之前要更新權重,所以

更新完權重之後,就開始進行第二次迭代,重複數次之後…

最終就會找到最佳的平面,將數據完美的切分開來。

限制:

  1. perceptron停止的criteria是當所有error=0,也就是要全部分對才會停止迭代。如果資料無法線性可分割,就會無法停止,這也就是為何資料要線性才能使用perceptron的原因。
  2. 只能完成分類,但無法知道分完之後各類別的機率是多少。(Logistic regression可解決)

羅吉斯回歸(Logistic Regression)

介紹:

  1. 名稱雖然有回歸,但其實是分類
  2. 概念與perceptron類同,僅差在有機率的概念引進
  3. 解決perceptron只能知道分類結果卻不知道機率是多少的問題

數學:

logistic regression採用的激勵函式跟perceptron不同,採用比較平滑的函數,如sigmoid就是一個例子。


y值介於0~1
當z>0,判斷成A的機率>0.5
當z<0,判斷成A的機率<0.5

程式碼:

1
2
3
4
5
6
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(X_train, Y_train)

lr.predict(X_test) #分類結果
lr.predict_proba(X_test) #分類後的機率

優點:

  1. 資料不需要線性可分
  2. 可以獲得A類跟B類的機率
  3. 實務上Logistic Regression執行速度非常快

缺點:

線的切法不夠漂亮(SVM可以解決)

SVM

介紹:

  1. SVM(Support Vector Machine),支援向量機
  2. 不再受限於線性可分,可以做非線性的分類

數學:

黑色虛線分別距離紅線左右距離k,虛線上的藍紅兩顆球X1,X2就是支援向量(Support vector),目標是最大化中間的margin,margin的計算方式是計算X1-X2向量在W上的投影。

透過條件 Y * (W * X) <= k 來計算來最大化margin。

程式碼:

1
2
3
4
5
6
from sklearn.svm import SVC
svm = SVC(kernel='linear', probability=True)
svm.fit(X_train, Y_train)

svm.predict(X_test) #分類結果
svm.predict_proba(X_test) #分類後的機率

優點:

  1. kernel可以選擇線性或非線性
  2. 可以得到分類後的機率大小

缺點:

效能不好,因為時間複雜度為 O(n^2),當資料量過多的時候會執行較慢。

決策樹(Decision Tree)、隨機森林(Random Forest)

介紹:

  1. 決策樹是透過一層一層的問題來分類答案,具有更強的解釋性
  2. 執行效率高的監督式機器學習模型
  3. 可以做分類與回歸
  4. 隨機森林是多個決策樹組合而成的,應用ensemble的概念將許多弱的機器學習模型結合起來建構成一個較強的模型,比較不會有overfitting的問題


圖片來源

數學:

計算資訊量的公式有兩種:

  1. 熵(Entropy)
  2. Gini(Gini Impurity)

它們的原理都是計算所謂的Information Gain,將較高同質性的資料放置於相同的類別,以產生各個節點。Entropy代表某個資料集的乾淨程度,當資料愈乾淨,則Entropy=0,反之,當資料很混亂,則Entropy=1。

1. Entropy:

p:成功的機率(或true的機率)
q:失敗的機率(或false的機率)

2. Gini:

p:成功的機率(或true的機率)
q:失敗的機率(或false的機率)

程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 決策樹
from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier(criterion = 'entropy', random_state=0) #entropy or gini
tree.fit(X_train, Y_train)
tree.predict(X_test)
tree.score(X_test, Y_test)

# 隨機森林
from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier(criterion='entropy', n_estimators=10,random_state=3,n_jobs=2)
forest.fit(X_train, Y_train)

# 將樹的實際長相視覺化
from sklearn.tree import export_graphviz
export_graphviz(tree, out_file='檔名.dot', feature_names=['name1','name2'...])

max_depth: 主要是可以防止樹長得過高造成overfit

n_estimators: 樹木的多寡(你要創造幾個決策樹來投票),通常越多越好,但運算時間也會拉長。

n_jobs: 主要是隨機森林支援平行運算,你可以決定要用你電腦的幾個核心去算,來加速運算速度

XGBoost

介紹:

  1. XGBoost, eXtreme Gradient Boosting (極限梯度提升)
  2. 基於Gradient Boosted Decision Tree (GBDT)的改良與延伸

程式碼:

1
2
3
4
from xgboost import XGBClassifier
xgb = XGBClassifier()
xgb.fit(X_train, Y_train)
xgb.score(X_test, Y_test)

參考: