0%

上一篇提到一些基本的Feature Engineering概念與方法,這一篇則是會說明當要使用類別型的特徵來訓練機器學習模型時的技巧。

Categorical

如果遇到類別型的特徵又需要拿進來訓練模型,則可以用one-hot encoding來處理。例如當今天要對商品銷售預測建立模型時,想要把員工拿進來考量,也許不同員工對顧客的服務上會影響到商品銷售。雖然員工的編號是數值,但其並不存在實際上數值的意義,這時候就可以透過one-hot來處理,並以多個欄位變數表示來將每個值轉成0/1表示的稀疏向量。

有時候在某些資料則可以當作連續型處理,也可以使用one-hot來處理。例如顧客的評分,如果你認為4分和2分是差距很大的,這時也可以依個人考量當作類別型處理。要特別注意的是,如果今天顧客沒有提供評分資料,在處理missing value上,第一種數值型的處理方法是使用另一個欄位來紀錄是否有收到評分(1/0),並維持評分值為0;第二種類別型處理方法則將所有one-hot變數設為0,並一樣透過另一欄位紀錄是否有評分,注意不要使用自己的特別編碼(magic number)來處理。

Feature Cross

假設今天要建立模型來判斷車輛是否為計程車,而使用的特徵只有兩個,分別為車倆的顏色和車輛所屬城市。假設透過簡單的線性模型來作訓練,在調整權重的過程中,都沒辦法有好的辨識效果。因為模型在調整黃色和白色的權重時,當它看到黃色在紐約是計程車,提高了黃色的權重,但這反而造成所有黃色車倆比較容易判斷成計程車,這是不對的;相同的如果模型提高了紐約的權重,這也會造成所有紐約的車倆都容易判斷成計程車,這一樣是不對的。

這時候則可以嘗試將兩個變數結合變成第三個變數,並透過one-hot encoding來處理,而在訓練過程中就會將黃色X紐約的組合單獨調整權重,可以避開原本的問題。例如在預測計程車車資問題中,雖然知道在上下班時間的旅程時間會比較長,車資也可能比較高,但是這時可以不特別作新增rule的處理(例如標注某天的某時段為上下班時間),而是直接將Day of Week和24小時作feature cross建立組合。

Bucketize

以加州的房價預測來說,如果觀察緯度這個特徵會發現有兩個高峰,一個是舊金山灣區,另一個則是洛杉磯大都市,這時就可以透過資料分群(bin)來拆成100個bucket,轉成類別型資料來訓練模型。注意在預測時也要透過資料前處理來將資料作bucketize。

Wide and Deep

到這邊就會遇到一個問題,在銷售遇到時會有價格和員工兩種不同特性的變數,價格是密集的(Dense)的連續型變數,而員工編號是透過one-hot產生稀疏(Sparse)的類別型變數。而在使用類神經網路訓練模型時,因為在0在乘上權重還是為0,所以稀疏的矩陣可能造成訓練過程中收斂在區域最佳解跳不出來。但是以上面說的計程車例子,其實線性模型是比較容處理的。

因此在訓練模型時,可以嘗試合併兩種方法,透過類神經網路來使用連續型變數訓練深度(Deep)結果,再和類別型變數透過線性方式串聯(Wide),這即是一個wid-and-deep架構的神經網路模型。

參考資料:
Data Engineering on Google Cloud Platform 4 - Serverless Data Analysis with Google BigQuery and Cloud Dataflow

前陣子在上Coursera的Data Engineering on Google Cloud Platform這個系列課程,其中在Serverless Machine Learning with Tensorflow on Google Cloud Platform這週內有一個Feature Engineering單元,裡面展示了如何透過Feature Engineering來提升模型的表現。上完後覺得裡面提到一些關於Feature Engineering的技巧,決定還是找時間把筆記寫下來。

好的特徵必須要和預測目標值是有相關的,對於特徵和預測值之間,需要有合理的假設,而不是隨意丟任意的資料進來,就希望特徵和預測值間具有關聯性,否則會落入Data Dredge的問題。Data Dredge意指可能會從大量資料中找到另人意外的相關性,這並不是我們想要的結果。(例如荷蘭的研究中指出一個地方送子鳥被看到的數量,和9個月後嬰兒出生的數量相關)

Causality

好的特徵特性是要使用預測當下能夠掌握的資料當作特徵,例如當你要使用每日的銷售資料當作特徵值,但是這些資料可能需要一個月的資料才會產生,而不是及時會被收集到資料倉儲。像這種可能因為資料延遲造成在預測時無法取得完整的資料將可能造成模型失效。所以在訓練模型時,請確保這些特徵在預測時是可以完整取得的,否則不要使用在模型中。

Numeric & Magnitude

因為在機器學習的過程中,會對輸入的資料作許多的運算,因此使用的特徵必須要為數值形態,且其數值是有大小意義的(例如coupon提供的打折數20%和10%存在折數大小關係)。

Enough examples

好的特徵需要有足夠的資料,以講者的個人經驗來說,如果一個特徵中每個值出現至少5筆,才會將這個特徵用來訓練模型。舉例來說,有一個類別為自動交易,需要有足夠的詐欺/非詐欺資料才有辦法訓練出有效的機器學習模型。如果今天只有3筆自動交易資料,且3筆都是非詐欺,這樣數量的資料可能就無法訓練出可用的機器學習模型。我想這裡的用意是指一個特徵如果相似度太高,可能造成沒有鑑別度;例如在分類問題中,特徵在每個類別的值都一樣或相似,那麼這樣的特徵可能對分類問題沒辦法貢獻太多資訊,使用決策樹來切分也會找不到好的切點。

參考資料:
Data Engineering on Google Cloud Platform 4 - Serverless Data Analysis with Google BigQuery and Cloud Dataflow

Python的collection模組裡面其實包含了許多非常實用的資料結構,比如之前介紹過的
namedtuple。今天要談的是Counter,Counter是一個dict的子類別,用來對hashable的物件作計算。

比如說我們今天要來幫公司裡面每個不同的team訂飲料好了,以下簡易一點不接受客製化調味,在建立Counter可以有以下幾種方法

1
2
3
4
5
6
7
8
9
10
# 使用mapping建立Counter,輸入一個dict
>>> team1 = Counter({'BlackTea': 3, 'GreenTea': 2, 'MilkTea': 1})
# 使用iterable建立Counter,輸入一個list
>>> team2 = Counter(['BlackTea', 'BlackTea', 'BlackTea', 'MilkTea', 'MilkTea', 'MilkTea'])
# 使用keyword參數建立Counter,輸入key-value組合
>>> team3 = Counter(GreenTea=3, MilkTea=3)
>>> team1['BlackTea'] # 可以直接當作dict存取
3
>>> team2['GreanTea'] # 取出不存在的item即為0
0

可以看到透過Couter能透過三種不同的方法來建立,就看使用的情境比較適合哪一種。而Counter也可以直接就當作dict取出值,特別是如果取出不存有的item,其計數會為0,並不會出現dict的KeyError。

1
2
3
4
5
6
7
8
>>> team1 + team2  # 使用加法運算符
Counter({'BlackTea': 6, 'MilkTea': 4, 'GreenTea': 2})
>>> team2 - team3 # 使用減法運算符
Counter({'BlackTea': 3})
>>> team2 & team3 # 運算兩者的交集
Counter({'MilkTea': 3})
>>> team2 - team3 # 運算兩者的聯集
Counter({'MilkTea': 3, 'GreenTea': 3, 'BlackTea': 3})

Counter也可以支援不同的運算符來對Counter物件進行操作,來達成對不同集合元件的運算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> drink_order = team1 + team2 + team3
Counter({'MilkTea': 7, 'BlackTea': 6, 'GreenTea': 5})

>>> list(drink_order) # 將Counter的items轉成list
['BlackTea', 'GreenTea', 'MilkTea']
>>> set(drink_order) # 將Counter的items轉成set
['BlackTea', 'GreenTea', 'MilkTea']
>>> dict(drink_order) # 將Counter的items轉成一般dict
{'BlackTea': 6, 'GreenTea': 5, 'MilkTea': 7}

>>> drink_order.items() # 取出item pairs
dict_items([('MilkTea', 7), ('BlackTea', 6), ('GreenTea', 5)])
>>> drink_order.keys() # 取出key值
dict_keys(['MilkTea', 'BlackTea', 'GreenTea'])
>>> drink_order.values() # 取出value值
dict_values([7, 6, 5])

>>> sum(drink_order.values()) # 取出value值並加總得到全部數量
18

因為Counter是dict的一個字類別,所以基本上他可以辦到原本dict可以作到的資料轉型,包含透過items()來逐一取出每個pair,或是直接可以使用values()並加總來計算出Counter裡面總計有多少數量的東西。

1
2
3
4
5
6
list(drink_order.elements())
>>> ['BlackTea', 'BlackTea', 'BlackTea', 'BlackTea', 'BlackTea', 'BlackTea', 'GreenTea', 'GreenTea', 'GreenTea', 'GreenTea', 'GreenTea', 'MilkTea', 'MilkTea', 'MilkTea', 'MilkTea', 'MilkTea', 'MilkTea', 'MilkTea']
>>> drink_order.most_common(3)
[('MilkTea', 7), ('BlackTea', 6), ('GreenTea', 5)]
>>> drink_order.most_common(2)
[('MilkTea', 7), ('BlackTea', 6)]

Counter還支援兩個函式,elements可以幫你展開所有的items。而most_common則會使用數量作排序,並且可以指定要排出前幾名。

Counter其實使用上非常方便,讓我們看一下Counter在實戰上可以拿來解什麼樣的問題,以下選兩個LeetCode的題目來看看Counter可以怎麼樣被使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'''389. Find the Difference
Given two strings s and t which consist of only lowercase letters.
String t is generated by random shuffling string s and then add one more letter
at a random position. Find the letter that was added in t.
Input:
s = "abcd"
t = "abcde"
Output: e ('e' is the letter that was added.)
'''
def findTheDifference(self, s, t):
from collections import Counter
s_counter = Counter(s)
t_counter = Counter(t)
return list(t_counter - s_counter)[0]

LeetCode-389是給定兩個字串s和t,其中要判斷t比s多了哪個字元。這時候就可以直接將s和t分別以iterable的方式建立兩個Counter,而我們知道t會比s多一個字元,於是再透過減法來找到t和s的差集後,輸出是哪個item即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'''819. Most Common Word
Given a paragraph and a list of banned words, return the most frequent word
that is not in the list of banned words. It is guaranteed there is at least
one word that isn't banned, and that the answer is unique.
Words in the list of banned words are given in lowercase, and free of punctuation.
Words in the paragraph are not case sensitive. The answer is in lowercase.
Example:
Input:
paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."
banned = ["hit"]
Output: "ball"
'''
def mostCommonWord(self, paragraph, banned):
import re
from collections import Counter
words = re.sub("[!|?|'|,|;|.]", '', paragraph).lower().split(' ')
return (Counter(word for word in words if word not in banned).most_common(1)[0][0])

LeetCode-819是給定一個段落,還有被禁掉的詞清單,接著輸出出現字詞次數最多次,而且沒有被禁掉的詞。這邊先將所有詞轉成小寫,接著再透過空白切分後,將特殊符號取代掉只留下字詞。再來就可以將不存在於禁用清單的詞拿來建立Counter,然後使用most_common取出次數最高的第一名,接著再輸出是哪個詞即可。

Counter其實在計算次數的時候非常實用,特別是在項目很多的情況下,而且還需要作加減運算時,可以嘗試使用Counter來解問題,絕對可以幫助你省下很多的時間的!

參考資料:
Python docs - Counter dict subclass for counting hashable objects

在RNN的應用中,有一種是sequence to sequence模型,像是在語言翻譯問題上,要把長度為5的法文翻譯成長度為6的英文。首先先透過一個encoder將每個法文字詞輸入進RNN模型,再透過decoder逐一輸出英文字詞直到結尾,這樣的模型被證實只要使用足夠大量的法文和英文句子就可以完成。

另一個類似的應用是給一張照片,然後自動給予這張照片適當的標題,這時可以透過CNN來建立一個encoder,接著再透過RNN建立一個decoder來產生適當的標題。

第一週有學到language model,會計算產生句子的機率。而在翻譯問題中的encoder部分和language model非常相似,只是在輸入不是向量0,而是一個encoder的網絡。翻譯問題其實很像是一個conditional language model,即給定輸入翻譯前的句子X之下,輸出不同翻譯結果的機率。

我們並不希望直接對這個分布輸出作隨機的取樣,因為取樣的結果容易很不穩定,有時取到好的翻譯結果,有時取到不好的翻譯結果。所以在使用這個模型的時候,需要使用一個演算法來計算出給定X輸出譯翻結果Y的最大條件機率。

一個方法是使用貪婪搜尋法(Greedy Search),即先根據conditional language model來產生第一個詞,接著在後面的翻譯部份每一次再依據前個詞選取最大機率來產生下個詞。但我們實際上希望的是找到輸出翻譯結果中每個詞Yi最大的聯合機率(Joint Probability),而不是每次都產生一個機率最大的詞,比如說法文翻譯到英文的問題中,如果前兩個字的翻譯結果開頭都是Jane is…,但是going這個字在英文上比起visiting還常見,所以用這個方法會造成第3個詞比較容易接going,但是這並不是一個最佳化的翻譯結果。但在英文可選的詞非常多,所以會使用approximate搜尋法來嘗試找到最大的條件機率。

Beam Search演算法的特性在於不會像之前一樣只找一個最大的機率,而是會存下前B個最大的機率值在記憶體裡面。比如說第1個詞已經找出是in, jane和september,再來會繼續再找出第1個詞是in的情況下,第2個是哪個詞。這時會計算出在給定輸入X且第一個詞是in之下,哪個詞的機率最大,即P(Y2|X,Y1)。再將機率乘上P(Y1|X)就可以得到給定X之下,前兩個詞的機率P(Y1,Y2|X)。然後存下前三個最大的可能性,這時可能會存下in september, jane is和jane visiting,再繼續往下找第3個詞。這時也就代表演算法認為september不會是第一個詞。

接著beam search再從前兩個詞的三組詞往下展開來,並找出前三個詞最大機率的三組保留,透過這個方法持續到接到結尾EOS並停止。要注意的是如果把B設定成1的話,就等同於前面介紹的Greedy Search。

有些不同的方法可以讓beam search可以得到更好的結果,其中一個是length normalization。beam search會持續連乘使得機率值變很小,這可以透過取log相加取代,因為logP(y|x)和P(y|x)兩者取最大值將會有一樣的結果。當句子很長時,可以透過改變目標函式的方法來解決這個問題。因為取log後為<=1,所以當詞越多值也就會越小,一個方法是除上詞的數量來作正規化,這可以大幅的降低因為句子太長所造成的懲罰(Penalty)效果。另外為了要讓這個正規化效果更加的平滑,可以將Ty取α次方,比如說設定成0.7(1為完整的正規化,0為不作正規化)

但B值到底該如何選擇呢?B值越大會可以留下更多的組合來找到更好的結果,但卻訓練的時間會更久,而且也會使用更多的記憶體。Andrew這邊建立在production系統B為10就可以了,但是在研究的系統上,可以取更大的B來計算不同的組合,多次作嘗試。

因為翻譯問題不是像是圖像辨識一樣有正確的答案可以用accuracy來衡量,翻譯結果可能可以有多個一樣好的結果,這個時候可以使用Bleu(Biligual Evaluation Understudy) score來作訓練結果的衡量。
Precision會比對機器翻譯出來的結果和人翻譯的結果,看機器翻譯的每個詞,是否都有出現在不同的答案reference中。比如果機器翻譯出來有7個詞,其中the這個詞都出現在reference中,所以precision為7/7。但這樣的計算顯然不夠精確。Modified Precision則會給予每個詞不同權重,像是the在reference 1出現2次,在reference 2出現1次,因此會給它權重為2,那邊Modified Precision將會修正2/7。

但是衡量並不會只看單一詞的結果,比如說使用兩個詞為一組(Bigram)來作計算的話,會先透過bigram來取出所有組合,並計算每個組合在機器翻譯結果出現次數,再來計算每個組合在所有的reference中有沒有出現(1或0),再來則將reference的數量除上機器翻譯bigram出現次數來計算 bigram的precision。

所以在使用N-gram取組合時,即可以歸納出一個公式,如果機器翻譯出來的結果和其中一組reference相同時,modified precision就會等於1。

把多個n-grams分數綜合起來,可以計算出一個綜合的分數再乘上BP。因為當機器的翻譯結果過短時,會造成大多的字存在reference中,使得modified precision會偏高,此時會引入BP(Brevity Penalty)的概念,當機器翻譯的長度比起reference還長時,BP為1即不給予懲罰分數;反之給予一個懲罰分數。

實際上人在進行翻譯時,並不會把整段都看完再翻譯,而是先看一小段翻完再往後看另一小段。而且當句子越長時,Bleu score會逐漸降低,這時如果使用Attention Model來幫助每一小段作翻譯的話,則可以解決這個問題。

雖然attention model是用在比較長的句子,但這邊使用短句來作說明。這裡encoder使用bidirectional RNN,在decoder時透過另一個RNN來完成翻譯。在產生第1個詞時會透過α來表示要產生這個詞應該要注意的資訊量有多少。接著再產生第2個詞時,會產生一組新的attention weight來表示產生第兩個詞時該注意的資訊量,並加上前一個產生的詞。

在建立attention model時,encoder使用的bidirectional RNN會貢獻兩個activation值,此值即為α權重。接著在decoder產生每個Y值時會輸入C,這個C即為α值的加總,用來表示要產生的Y值需要注意多少的資料量,而這個α會取softmax確保其加總為1。

所以在產生Y時主要有兩個輸入,一個是上個hidden狀態S< t-1 >,一個是要注意的資訊量a < t’ >,透過建立這個小的神經網路來使用梯度下降作訓練。但attention model的缺點就是他的計算成本較高,複雜度為Tx * Ty。

seqence to sequence可以被使用在文字的正規化,把不同型態的文字表達轉成一個相同的表示方法。

語音辨識(Speech Recognition)也是一種sequence to sequence的問題,輸入一段語音後期望可以輸出一段正確的辨識結果。傳統的語音辨識方法會使用音位(Phoneme)當作基本的單位來表示語音結果,但在end to end的深度學習方法,已經不再需要使用這種方法。

一個有效的方法是使用CTC cost,語音辨識因為每秒可能有多次的取樣,所以輸入的資料會很大,光是10秒的語音就可以變成上1000的輸入,但是輸出的辨識結果並不會有上千的輸出。CTC可以協助幫輸出的結果作適當的collapse,其會對重複的字作collapse像是重複的t, e和q來產生較短的結果。

這裡以trigger word偵測系為例來說明語音辨識問題,trigger word常被使用在一些智慧管家的產品當中,像是Google Home或是Amazon Echo。在訓練過程中會輸入語音,並在出現trigger word時的目標label設定為1,其它部份為0。

參考資料:
Deep Learning Course 5 - Sequece Models

在上一週的課程中,我們使用了one-hot結合詞庫來將句子作量化處理。但是使用one-hot的缺點是每個詞被視為獨立的,也就是無法衡量出兩個詞之間的相似或與重要性(兩個one-hot vector內積都會為0)。所以當你想知道apple和orange之間的關係比起apple和king還接近,就無法單純的使用one-hot來作文字的量化。其中一個方法是可以用不同的特性來作量化,比如說使用性別、是否為食物等等的特性,這個時候便可以辯識出具有相同性質的詞。

這種量化文字的方法又可以被稱為Word Embedding,像是每個詞會嵌在高維度的特徵向量中,即每個詞都可以在高維度的特徵找到一個能表示它的位置,而如果要將多個維度的特徵壓縮到兩維來表示,可以使用t-SNE演算法來找到相同的詞會彼此較相近。

使用Word Embedding的好處除了可以判斷出兩個詞之間的相關係,也對Transfer learning有很大的幫助,即使用已經訓練好的word embeddig來用在新的任務。在使用word embedding於transfer learning有幾種方法。1. 從大量的詞庫(1-3B)中進行訓練(或是下載已被訓練過的) 2. 使用原本已建立的embedding並transfer到新的而且訓練資料集較小(1-3k)的任務 3. 持續的使用新的資料來對embeddings進行finetune。

Word Embeddings也可以作到比擬(analogy),比如說Man之於Woman等同於King之於Queen,這可以透過向量相減來找到相似的結果。

實際上要基於Man與Woman的關係來找到King和某個詞,可以透過向量相似度的計算來找到,只要找到King和哪一個詞的相似度與Man和Woman的相似度最接近即可。這裡的相似度計算是從原始的高維度(~300D)來的,雖然可以透過t-SNE來將高維度使用非線性的轉換到2維空間作視覺化,但如果使用了轉換的2維來計算反而會失真,所以在實際上的相似度計算會使用原始的高維度向量空間。

一個常用的相似度計算是Cosine similarity,即計算兩個向量的角度來判斷兩個相向之間的相似度。Cosine similarity也經常被用在文本分析中,透過計算代表兩筆資料的高維度向量,來評估兩筆資料的相似度。

Word Embedding的學習最終會得到一個Embedding Matrix,凡是把這個矩陣乘上某一個詞的one-hot向量,所得到的即是代表這個詞的embedding。因為one-hot是高維度而且幾乎都是0的稀疏矩陣,所以在實務上並不會真的相乘,而且透過特別的方法來找到詞的embeddings。

在word embeddings的學習演算法中,過去往往會使用很多很複雜的演算法來學習,但後來卻發現很多簡單的方法就可以達到很好的效果。在複雜的方法中,比如說要預測一句話的下一個詞,可以把每個詞的word embeddings輸入到一個類神經網路學習,最後訓練出我們要的embedding matrix(E)。如果有300維度,那麼要輸入到網路裡面的維度就會多達300乘6共1800維,也可以選擇只看前4個詞來學習,那麼維度就會降到300乘4共1200維。

不過事實上用簡單一點的模型也可以訓練出好的效果,比如說只用預測詞的前一個字,或是最接近預測詞前一個詞的詞(又稱為skip gram)來訓練word embeddings matrix。

這裡介紹Word2Vec的Skip-grams模型,Skip-grams在選擇Context與Target組合時,針對Target可透過隨機挑選的方式選出不同的組合,比如說Context詞的+-5~10個詞來選出Target詞。

再來將這些對應的組合透過matrix E轉成word embeddings後丟入神經路網學習,接著經過softmax後計算loss function來訓練出matrix E。

但這個方法的主要缺點在於需要大量的計算,因為在計算softmax時,分別需要加總所有詞,如果詞的數量越多,那麼速度就會越慢,因此很難擴充到大型的訓練詞集。一個解法是使用hierarchical softmax,先拆出詞位於哪個部份(前或是後五千詞),接著再接續往下作二元拆解。在tree的結構可以把常出現的通用詞放在上半部,這樣就可以較快的被找到。

因為skip-grams在計算softmax需要花費大量運算,使用Negative Sampling則可以避免這個問題。Negative Sampling首先會先建立postive pair和negaive pair,比如說orange和juice會一起出現,就給予label 1,然後再隨機選出其他K個詞和orange組成negative pair給予label 0(即便某些時候negative pair組合真的有一起出現也沒關係)。最後將這些組合透過監督式學習訓練模型。

接著可以使用logistic regression來計算在給定label為1時,postive pair組合的機率,並使用K+1組資料進行訓練,然後再將這個分類器應用在10000個詞作二元分類。因此比起原本作skip-grams要一次訓練10000組資料,使用negatiev sampling的方法只需要用少量的資料訓練,再一次用在多組詞的分類。

但是該如何去選擇negative sampling呢?一個方法可以從詞出現的頻率選起,但是很容易選到停用詞(stop word);或是假定他是均勻分配,使用1/|V|來選擇,而在這篇論文裡面是用了每個詞在訓練詞庫中出現的3/4次方來計算機率作選擇。

另一個學習方法為GloVe,首先會計算context和target一起出現在訓練資料的次數,Xij會等於Xji如果是用target的正負距離來選擇context,但是如果只看target出現在context後面,就會不相等。

GloVe的模型中為了避免Xij為0,因此會乘上一個權重f(Xij),如果Xij為0則f(Xij)為0,當然這個函式也可以用來給予不同詞頻的詞有不同的權重處理。

情感分析(Sentiment Analysis/Classification)是NLP其中一種應用,主要用在判斷文本中是表達喜歡或是不喜歡(正或負)。比如說,輸入的X為評論的內容,輸出Y為評論的情感等級,像是從網路評論中判斷對於餐廳或是旅館的正負評論。其最大的困難在於情感分析缺乏大量的標記資料來學習,如果使用word embedding可以幫助在少量訓練資料的情況下學習。

在建立情感分析模型時,一樣使將每個詞透過embedding matrix選出該詞的embeddings向量,接著透過加總或是取平均值後,再使用softmax函式得到輸出Yhat。不過因為這樣的方法是沒有前後順序的,所以如果遇到明明有否定詞在前面,但是後面出現很多的正向詞good,這可能就會造成誤判斷把明明是一星的評論判成五星,因為出現很多次的good會把結果導到正向,這個時候就需要使用RNN來建立模型。

使用RNN一開始也是將每個詞透過embeddings matrix找到該詞的embeddings向量,接著將每個詞輸入進RNN,最後再接softmax判斷結果,這個就一開始提到的Many to One的RNN類型。因為RNN是會有順序性的,所以對於出現否定詞的句子能夠處理的比較好。因為word embedding可以從較大的訓練資料訓練出來,所以即使在情感分析的訓練集裡面缺少了某些詞,但這些詞有被word embedding訓練過,這樣在作情感分析時也可以得到較好的結果。

在word embeddings的訓練過程中,可能會造成帶有偏見的學習結果,比如說本來是希望學出Man之於Woman等於King之於Queen,但可能會學習出Man之於Programer對於Woman之於Home_keeper這種帶偏見,或是Father之於Doctor對於Mother之於Nurse這種錯誤的結果。因為機器學習現在已經越來越普及的被應用在許多不同的領域上,所以這種帶偏見的錯誤結果應該要被避免的。

解決這種錯誤的學習有不同的方法,以解決性別偏見為例來說明,第一先將girl-boy和mother-father來找到屬於性別的分界向量,這時把任一個詞和這個分界向量作內積,就可以找到這個詞會偏向哪個性別,並找出bias direction,要讓不能帶有性別偏差的詞向量去除bias。透過Neutralize將一些對於性別來說屬於中性的詞,將其投影到non bias的方向軸,最後為確保像是doctor這種應該屬於中性的詞,與帶不同性別的詞(像Girl或是Boy)距離要是相同的,會使用Equalize pairs的手法將帶性別的詞移動到以軸為中性對稱的位置,這樣就會讓兩者與doctor的距離或是相似度是相同的。在選擇哪些詞需要進行Neutralize,可以透過練一個分類器來分辨;在選擇要equalize的部份因為較少量,所以可以簡單透過人工挑選的方式完成。

參考資料:
Deep Learning Course 5 - Sequece Models

有序列性質的資料(sequence data)可以泛指輸入資料(X)是有序列的,或是輸出資料(Y)是有序列的。比如說在翻譯問題上,輸入和輸出都是有序列性的句子;但在情感分析問題上,輸入會是一個有序列性質的評論句子,但是輸出為情感的等級或是分數。

量化句子的方法可以使用詞庫加上one-hot encoding,可以透過自己建立或是使用已存在的詞庫,並將詞庫使用one-hot encoding作編碼來將文字資料作量化產生可以用來學習的輸入資料X。

如果使用一般標準的類神經網路會有什麼問題呢?1. 每一個訓練資料的輸入和輸出的長度不同,不好處理。2. 在不同文字中的不同位置無法學習出共同的特徵。如果要像CNN一樣能夠在不同的訓練資料的不同位置中學習到共同的特徵,就必須要透過RNN來達成。

Recurrent Neural Network(RNN)在每個訓練樣本會共同相同的weight和activation function。RNN會將每一個字詞X< i >經過激活函式後的結果,再傳給下一個字詞X< i+1 >,所以每個字詞會拿到由前面傳遞過來的資訊。但是只拿到前面字詞的資訊是不夠的,例如在判斷Teddy時,就需要使用字詞後面的句子內容,才能夠有效的區分Teddy究竟是指總統還是玩具。這時會使用到雙向的RNN(BRNN)才能夠解決這個問題。

前面有提到RNN的輸入和輸出長度可能會不一樣長,針對不同輸入輸出長度可分為不同類型的RNN。在翻釋問題上,不同的語言可能翻譯後的長度都不同,這是一個Many to Many問題;如果是情感分析會將一則評論輸出成正反或是1到5星等級,屬於Many to One問題;One to Many會適用在像是音樂生成,給定一種音樂類型來產生一首音樂;One to One這種類型就是一般的神經網路了。

RNN可以被應用在建立語言模型(Language Model),例如在語音辨識中,透過語言模型可以透過計算不同輸出句子的機率,來辨識出哪一個句子是最符合的輸出。

把每個句字斷詞並量化後,就可以丟進RNN來建立模型。舉例來說,在訓練時,將第一層RNN輸入空向量,再將本來的實際詞Y< i >從第兩次RNN依序丟進去訓練,就可以建立模型來預測某段句子後會接什麼樣的詞。即輸入Cats average,判斷下個接每個詞的機率。所以可以透過將每個詞依序輸入來計算出在給定某個句子下,輸出某個詞的機率。在這裡可以透過外部詞典,並使用softmax來算出每個詞的機率

進一步我們就可以使用這個模型來隨機的產生句子,首先先隨機選出一個詞,接著將每個詞依序丟進下個結點來產生新的詞,直到取出字尾EOS或是設定一個固定的句子長度終止。

除了使用詞(Word-level)來組成句子,也可以使用字元(Character-level)來建且模型組成句子。如果使用字元來組成句子,那麼每一個輸出就是一個字元而非一個詞,好處在於不用怕取到辭典裡面沒有的詞,壞處則會產生更長的句子,也會降低訓練速度,所以目前經常是使用詞來建立模型。

梯度消失(Gradient Vanishing)

如果句子太長的話,使得神經網路過於深,會讓梯度在作back propagation時很難影響到前面的layer,產生梯度消失現象。對於RNN來說,實際上的影響在於如果太前面的神經元,將會無法去記住前面的詞(例如區分單數詞或是複數詞)。因此,傳統的RNN的輸出結果主要會受到接近神經元的影響,較遠的神經元不容易影響到最終的輸出。比起梯度爆炸容易被發現與處理,梯度消失反而不容易被處理,而且更容易影響到RNN的訓練結果。

Gate Recurrent Unit(GRU)是一個改善RNN長期記憶問題的方法,他引入了memory cell(C)的概念,在這裡的C就等同於activation function的輸出a,這個memory cell會將長期的記憶儲存下來,並用一個帶使用sigmoid轉換後的Γu值來判斷要不要選擇忘記之前的記憶並更新,還是要保留之前的記憶,直到不需時再忘記。實際上為什麼應用GRU會改善梯度消失的現象,主是要在Γu值透過sigmoid轉換後如數數值很小那麼就可能會非常的接近0,在這個情況下,C< t >就會非常接近C< t-1 >並很容易的保存較遠的記憶來大幅改善梯度消失的現象。

另一個常用的方法為Long Short Term Memory(LSTM),在LSTM裡面C不再等同於a,LSTM會用到3種gate,分別為update gate, forget gate和output gate。

透過update gate和forget gate來決定是否保存較長遠的記憶,並透過output gate來輸出a到下一個神經元。

如果要同時合併前後神經元的資訊,就得使用Bidrectional RNN(BRNN)。BRNN除了從左到右作forward propagation外,也會從右到左作forward propagation。在輸出資料時,會同時輸入兩個方向進入activation function。而其中每個神經元也可以是GRU或是LSTM,所以實務上也會使用LSTM結合BRNN來建立模型。

RNN可以疊多層起來變成深度的RNN模型,本來RNN每一個順序都只有連接一個神經元,但也可以在每一個序順接處多個神經元來建立深度的RNN模型,甚至結合GRU和LSTM與BRNN來建立複雜的RNN模型。不過因為深度的RNN在訓練是非常耗資源的,所以不太常見到超過3層的RNN模型。

參考資料:
Deep Learning Course 5 - Sequece Models

最近正在學習Andrea在Coursera上開的Deep Learning課程,之前工作關係有接觸到keras,而且使用起來還滿容易上手的,所以就嘗試拿了MNIST資料集來試玩看看

首先載入手寫辨識資料集mnist,這個資料集還滿廣泛被拿來使用的,而且在keras也可以直接載入,另外也會用到最基本的keras Sequential model。

1
2
3
4
from keras.datasets 
import mnistfrom keras.models
import Sequentialfrom keras.layers
import Denseimport numpy as np
1
2
model = Sequential()
(x_train, y_train), (x_test, y_test) = mnist.load_data()

再來直接宣告一個sequential模型,並載入訓練和測試資料集

1
2
3
4
5
x_train = np.reshape(x_train, (x_train.shape[0], -1))/255
x_test = np.reshape(x_test, (x_test.shape[0], -1))/255

y_train = np.eye(10)[y_train.reshape(-1)]
y_test = np.eye(10)[y_test.reshape(-1)]

接著要先處理一下載入的資料,在x資料的部份要先將原本28×28的維度轉成1×784輸入,這裡可以使用numpy的reshape來處理,再來再將資料除上255作正規化。另外在label y資料集的部份則要作one-hot encoding,將每個標籤轉成長度為10的向量,並用0和1來表示屬於哪一個類別。

1
2
3
4
5
6
7
8
>>> x_train.shape
(60000, 784)
>>> x_test.shape
(60000, 10)
>>> y_train.shape
(10000, 784)
>>> y_test.shape
(10000, 10)

可以看到處理完後的資料維度

1
2
model.add(Dense(units=256, activation='relu', input_dim=28*28))
model.add(Dense(units=10, activation='softmax'))

再來加入兩個layer,即只使用一個hidden layer和一個output layer,其中hidden layer有256顆神經元,output layer有10顆,並透過softmax輸出結果

1
2
3
model.compile(loss='categorical_crossentropy',
optimizer='Adam',
metrics=['accuracy'])

接著開始設定使用什麼loss function與最佳化的方法,還有要評估模型的指標

1
model.fit(x_train, y_train, epochs=10, batch_size=32)

接著就開始訓練,其中會設定訓練的週期與每一次的批數

1
2
3
4
5
6
>>> loss_and_metrics = model.evaluate(x_train, y_train, batch_size=128)
>>> print(loss_and_metrics)
loss=0.007, acc=0.998
>>> loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
>>> print(loss_and_metrics)
loss=0.08, acc=0.979

中間可以看到訓練的過程,在訓練完畢說可以透過evaluate來評估model在訓練資料集,還有測試資料集的正確率。

keras在建立模型非常方便使用,可以很容易的加入需要的hidden layer數,而且針對常使用的activation function, loss function和最佳化的方法都有支援,如果需要快速的建出模型來作應用非常的推薦。另外keras也有支援CNN還有RNN,下次會用別的資料來試試看囉!

參考資料:
Keras Getting Start

上一堂提到validation的手法,透過留下用來驗證的資料模擬測試過程,並透過validation結果來選擇該使用什麼樣的模型。這一堂會提到三個在作機器學習時的小技巧。

Occam’s Razor在機器學習裡面意議是指不要對資料有過多的解釋,就是越簡單的解釋越好。以上面兩張圖的資料來看,左邊的模型符合直覺判斷,是一種比較容易而且 簡單的解釋,那到底什麼樣的模型才叫簡單的模型,而為什麼簡單的模型就比較好呢?

簡單的hypothesis是指沒有過多的參數就是個簡單的hypothesis,而簡單的模型則是指模型包含了較少的hypothesis就是個簡單的模型,所以簡單在這裡就是指比較小的hypothesis和模型複雜度。而要得到簡單的解釋,除了一開始就使用簡單的模型之外,也可以在之前透過regularization來達成。

那為什麼簡單的模型就比較好呢?如果今天使用簡單的模型就可以將資料分類正確,那某種程度上也就代表著資料背後的關聯性或是規律性是簡單的;相反的如果使用很複雜的模型,可能就無法知道資料背後的關聯性,因為不管是有關聯性的資料,或是雜訊很多的資料,都可以被複雜的模型分的開。所以如果使用簡單的模型來解釋資料,可以很直覺的看到資料間的顯著性,但是如果使用複雜的模型就辨別不出來,所以建議一開始推薦先使用線性模型。

第二個技巧會談到樣本的抽樣誤差,這裡用一個美國總統選舉的例子,來說明如果抽樣和要學習的結果不一致,並帶出抽樣誤差問題。如果在抽樣時就發生抽樣誤差,那麼在學習時就會產生偏差的結果,這就是為什麼前面課堂有說到訓練和測試的樣本資料要抽樣自相同的分配,訓練和測試的資料抽自相同的分配,才會得到預期中的學習效果,這就是我們VC中的重要假設。

這裡舉了一個實際上發生過的問題,如果訓練資料和驗證資料有有時間前後依序性(即一個人看過的電影順序),而非隨機取樣的話,如果透過隨機取樣來建立訓練資料和驗證資料,那麼在學習和驗證中就會有問題。這時候為了讓測試和驗證可以盡可能的接近,例如訓練時可以把時間依序性較後面的權重調高,或是抽比較多時間依序較後面的資料來作驗證。

再來第三個技巧則是談到之前說到偷看資料的問題,前面有說到如果偷看了資料,可能會把人腦學習到的,或是自己的偏差帶進機器學習裡面。

偷看資料其實比想像中更容易發生,不是只有用眼睛視覺化的偷看才叫偷看,而是你在處理資料的整個過程中,都算是間接的偷看了資料。如果使用這樣偷看過的資料,都會受到自己的主觀影響。假設今天有一組八年的交易資料,使用前六年當訓練,後兩年當測試。其中在將資料作放縮(Data Scaling)的資料處理過程中,如果不是將前六年作縮放,預測完再還原,而是直接將八年的資料都作放縮的話,就會得到紅色這條上升趨線。這樣將會得到一個太過於樂觀的學習結果,如果將這個結果用來實際投資可能會大大的失準。

除了直接的視覺化偷看,或是使用統計分析間接的偷看,其實作在研究上也會發生。例如針對相同問題,不同的論文會都使用更好的模型來作的比以前好,這樣的過程就有點像你的論文間接的偷看了前面論文的結果,這樣就有點像某種程度的overfit了。正是所謂的如果你拷問資料過久了,他就會招拱一個好的hypothesis,但是這個hypothesis應該用測試資料可能效果不保證會好。

但是完全不偷看其實很不容易,只能盡量的降低這中間的干擾,比如說小心的使用validation,或是把測試資料好好的先收好。所以要時時注意的是,記得要用專業知識來建立模型,而不是先偷看了資料來作決策。另外要時時存著懷疑每次作出來的結果,並懷疑這樣的分析結果是不是有受過汙染。

這堂課教到很多和三有關的東西,第一個是三個和機器學習相關的領域,Data Mining是希望在大量資料中找到找到有用或是重要的關聯,人工智慧是要讓機器作出有智慧的事情(像是自動駕駛),機器學習可以說是實現人工智慧的方法,統計則是為了去對母體作出推論,所以統計方法也被大量的使用在機器學習上。

在機器學習背後理論的保證,如果只有一個hypothesis的情況下,Hoeffding可以情供測試驗證的保證,當有多個hypothesis的情況下,Multi-Bin Hoeffding可以提供在有限多個選擇下的保證,如果是無限多個選擇下,VC則是可以提供在無限多個hypothesis是供理論上的保證。

在機器學習模型部份,PLA/pocket可以提供在線性可分下處理二元分類問題,在衡量上為讓0/1 err最小化,linear regression則是可以處理數值預測問題,在衡量上使用squared err最小化,logistic regression則可以處理軟性二元分類問題,在衡量上使用cross entropy最小化。

另外還有學到三個重要的技巧,Feature Transform可以將簡單的線性模型轉成高維度的複雜模型,會得到較好的Ein但是也會付出較高的VC代價,Regularization則是相反,透過加上regularizer來讓VC代價變小,但是也會讓Ein變大,Validation則是在沒辦法拿到測試資料的情況下,留下一部份的資料當作驗證資料。

最後則是這堂課學到的三個注意的地方,要注意簡單模型是好的,而且要注意抽樣的偏差,最後要記得不能提看資料。

再來後面的課程還會上到如何使用不同的轉換方法,以即不同的規則化方法,或是在缺少label的情況下該如何進行訓練。

總結這堂課程學到了很多機器學習背後的論理依據,而許多不同的機器學習方法將在另一堂機器學習技法課程教授!

參考資料:
Machine Learning Foundation 16

上一堂課講到為了避免overfitting,可以使用regularization的技巧,把一個regularizer加在Ein上面,轉而求Augmented Error反而可以有效的解決模型複雜度太高的問題。這一堂課會講到該如何使用Validation的手法幫助選擇機器學習裡面不同的參數。

在訓練一個機器學習模型,其中會遇到很多的選擇,包含使用哪些演算法、使用多少資料、要使用什麼非線性轉換方法,甚至是要使用哪一種regularizer。

Machine Learning裡面最實務的問題,就是如何作出好的選擇讓最後Eout可以作到最好,如果用視覺化的方法來作選擇,反而會受到自己的主觀影響,那到底該怎麼作選擇呢?

如果使用Ein來作模型選擇的話,就會受到overfitting的影響,越複雜的模型就越容易作好更好的Ein,但是會付出模型複雜度的代價,因為overfitting造成泛化能力變差,Eout反而也作不好。

那如果我們可以拿到實際的測試資料,就拿實際的測試資料衡量模型表現就好了,但是實務上可能不會有這樣的實際測試資料。

如果使用Ein來選模型不可行,而實務上又拿不到實際的資料該怎麼取平衡呢?我們可以使用手上的樣本資料,把一部份切出來當作看不到的測試資料,再拿剩下的資料作學習,並使用切出來的資料衡量模型的效果。

原本的樣本資料D要負擔兩種角色,一個是透過D來求出最好的Ein,然後再把D丟進演算法得到一個Hypothesis G,前面有講到如果這樣的話很可能會造成overfitting問題,所以我們把資料分成train和validation,先使用train總共N-K筆資料練習出好的Ein,並得到Hypothesis G,最後再透過K筆validation資料來驗證G到底好還不好。

從前面講到的learning curve可以知道,如果使用較多的資料來訓練會得到比較好的結果,所以實務上雖然會使用D(train)來訓練出不同的Hypothesis,然後使用D(val)作評估並選出最好的模型,但是最後在選好模型之後,會再把全部的資料D丟進模型裡作訓練,因為使用全部的資料會比較用部份訓練資料所訓練出來的模型還要好。

從驗證資料量和Eout來分析可以看到黑線的Eout會很大,因為在使用複雜的模型之下可能因為overfitting的關係造成Eout作不好;而虛線是用Etest資料,但是這個最佳的測試資料常常是不存在的;紅色是只使用訓練資料建立模型得到的Eout,他會比藍色使用全部資料來訓練所得到的Eout還要來的高。至於為什麼使用訓練資料會比使用Ein還要來的差的原因,是因為當驗證資料量K越大,代表訓練資料就越小,可能產生underfitting使得模型怎麼樣都練習不好。

所以我們會遇到不知道該怎麼選擇驗證資料量K的情況,因為如果用了比較大的K,雖然可以確保validation和Eout可以比較接近,但卻會造成訓練資料的Eout和全部資料的Eout差很多;但如果使用小的K雖然可以確保訓練資料的Eout和全部資料的Eout很接近,但是就無法確保validation和Eout到底接不接近。實務上的K常使用N/5。

假設今天設定K=1,並且重複抽出一筆當驗證算出error,再來把error作平均,就可以透過計算這個平均的error來推估Eout。而這種只抽一筆當驗證的方法就稱為leave-one-out的cross validation,因為每次都用N-K筆計算一個g,所以稱為交叉驗證。

在使用leave-one-out cross validation可以有兩種方法,第一種是拿掉一個點,用剩下的點作迴歸,再計算驗證的點到迴歸的距離當作error;第二種是拿掉一個貫,用剩下的點中間取一個常數,再計算驗證的點到常數的距離當作error,透過比較這兩種方法得到的較小的error,就可以選出比較好的模型,也許使用計算迴歸不一定會得到比較小的error,反而使用常數來計算還得到較好的結果。

而且leave-one-out cross validation的期望值,確實也可以證明和Eout是相近的,這個部份證明這裡就不多作說明了。

在實務上,如果使用Ein來選擇模型,使用越多的特徵雖然可以得到較小的Ein,但卻也可以造成overfitting,反而和Eout相差很大。但是如果使用leave-one-out cross validation的方法來選模型,確實可以找到一個比較接近Eout的結果,而且絕對對比Ein要來的好很多。

使用leave-one-out的最大問題,就是他會花很多的時間在作訓練,如果樣本資料有1000筆,每次都要拿999筆來訓練並重複作一千次才能取到平均的Error,所以在實務上leave-one-out要用來選擇模型可能比較不可行。第二個問題是leave-one-out因為每次只取一個點,所以他的變動程度很高,雖然有取平均,但是他本質上還是一個變動程度比較高的評估方法。

所以實務上,第一個希望可以降低訓練的次數,比起之前的1000次訓練,可以切成10份的方式,每次取9份作訓練1份作驗證後作平均,這樣就只需要作10次而不需要作到1000次。而且這個方法也可以作到交叉驗證的效果,leave-one-out其實也就是這種方法的極端例子。實務上比較常用的方法是切成十份,又可以稱為10-fold cross validation

使用cross validation在實務上會比只作一次validation當果會比較好也比較穩定,但是前提是在計算上是充許的,因為作k次的交叉驗證作平均需要額外的運算資源;而validation切5份或是10份就可以得到比較好的結果,不需要真的使用到leave-one-out。我們透過validation是可以讓我們選到一個比較好的模型,但是要注意的是,這個validation還是比最終使用測試資料的結果應該還是要樂觀的,只要真正應用在測試資料,你才會知道真的的效果如何。

總結來說,這堂課學到使用Ein來選擇模型是很危險的,並談到leave-one-out cross validaion與實務上會使用到的k-fold corss validation可以用來作模型選擇。

參考資料:
Machine Learning Foundation 15

上一堂課講到overfitting現象,他會在使用過高的模型複雜度、雜訊過多或是資料太少時發生。上次有提到可以使用Data Clean/Purning和Data Hinting從資料面下手解決,這堂課會提到regularized手法來避免overfitting。

Overfit現象就是Target和Fit兩者相差太多,雖然可以將樣本學習的很好使Ein很小,但是卻造成泛化能力很差Eout過高,就如同右邊這張圖。regularized目標則是希望可以把Fit曲線能夠更接近Target,所以regularized可以視成一個從高次方項走向底次方項的手法,有很多的解都可以通過樣本點,但是究竟哪一組是最好的,就是regularized要作的。那該怎麼從高次多項走回低次多項式呢?

要從高次多項式走回低次多項式,其實就可以視成低次多項式是高次多項式加上constrain,即如果把十次多項式中超過三次的項權重都設成0,那麼就可以降回二次多項式了。在求最佳化的過程也是,如果今天要求二次多項式的最小值Ein,就可以使用加上constrain的十次多項式來求最小值。

進一步的可以再延伸出,如果我並不是把超過三次項的權重設成0,而是只要其中有8項設權重設成0,就可以放寬這個constrain,讓regression可以更加的有彈性。這個放寬限制條件的二項式會比本來的二項式可以變化的項次更多,但也不像十次多項式這麼複雜。所以成求Ein時,只要確保權重為0的項次小於3個就可以了,但是這種離散的限制就像PLA一樣不容易求解,是NP-hard問題。

原本的條件是算權重不是0的項次要小於3,我們可以把他轉換成將每個項次權重平均相加要小於上限制C,這樣就可以轉成比較好解的問題,而且權重越接近0的取平均會越小。C如果設定的越大,就會越接近十次多項式結果,且所有比較小的C的項次組合都會被比較大的C的項次組合包含。這個H(C)又可以被稱為regularized hypothesis,即加上限制條件的hypothesis,而透過規則化的hypothesis set裡所找到的最佳hypothesis又稱為W(REG)

再來可以和之前一樣把式子轉換成矩陣的表示方法來解最佳化問題。原本我們可以透過走梯度反方向到W(lin)這個最佳解,但是現在加上了限制式,這個限制在幾何上是一個圓圈,找到前面所提到的規則化hpothesis最佳解W(REG)的話,就得同時往梯度反方向走而且不離開圓邊。又因為往圓的法向量(紅色向量)走就會離開圓邊,所以只能往垂直於法向量的分量走(綠色向量),當持續走到梯度反方向要是和圓的法向量平行的話,就代表不能走了,即為找到最佳解。我們可以把兩個平行向量的比值設成2λ/N。

再來可以把求梯度等於0轉換回求最小值的式子,即為Ein加上一組regularizer又可稱為augmented error Eaug(w),如果預先先指定λ值就可以很容易的解這個式子。

所以只要加上一點regularizer就可以對模型結果作出適當調整,今天如果λ設成0的話就等同沒有regularized即為overfitting,λ設的太大則會造成underfitting,加上regularizer就會有類似懲罰的效果。這種的規則化方法又稱為weight-decay regularization,即把權重最小的規則化方法。而且這個規則化方法可以應用到linear regresion、logistic regression甚至是其他不同的transform。

但究竟這個augmented error和之前學到的VC有什麼相關性呢?用求augmented error的方法來解本來不好解的constrain Ein,這裡對應到的VC保證為Eout會小於En加上一個constrain H(C),所以作好Eaug就能把Eout間接的也作好。

Augmented error和VC bound其實相同的地方在於都是在求複雜度,augmented error求的是單一個hypothesis的複雜度,而VC則是在求整個hypothesis集合的複雜度。這個augmented error如果可以表現更好,那麼Eaug可能是一個比Ein更好的代理人可以幫我們作到好的Eout。

其實使用regulization付出的VC dimension會比原本還要小,因為在實際上有N個特徵維度下,最終透過regulization將不會使用到那麼多的維度。這裡相比原本的d(VC),可以稱為d(EFF),其付出的維度會比本來的d(VC)還小。

那到底該使用什麼樣的regularizer呢?今天如果在知道target特性的情況下,可以針對target特性來設計regularizer,比如說如果想要一個比較接近偶函數的函數話,就針對奇數次方讓他變小。又或者在選出一個比較能夠說服我們的regularizer,像是比較平滑或是簡單的regularizer,因為overfitting是noise造成的,noise就會造成不平滑,像是使用L1 regularizer。或者也可以找一個好使用好最佳化的regularizer,像是前面說到的weight-decay regularizer,又被稱為L2 regularizer。如果找到不好的regularizer,那就把λ設定成0就等同於拿掉regularizer的效果。

L2 Regularizer最大的好處就是他很好微分求最佳值,而L1在微分求最佳值的部份比較困難,且L1在求最佳值時很常發生在頂點上,意義就是某一些的權重w會是0,所以L1 Regularizer又被稱為sparse regularizer。透過L1就可以在高維度空間下(例如1000維),找到一些w非0的項次(可能只有5維),所以在最後的預測只要算非0項速度會比較快。

那λ該怎麼選擇呢?很明顯的可以看到不管是stochastic noise或是deterministic noise,只要noise越大λ就要越大。下一講將會開始說明在使用規則化手法時,該如何有效的使用最佳的λ。

總結來看,這堂課說明規則化就是在原本的hypothesis加上一個條件,並轉成一個Augmented Error,因為作了規則化所以有些維度就不會被使用到,因此VC維度就會下降成d(EFF),而使用regularizer的使用方法可以針對target特性,或是使用容易說服自己的regularizer,還有也可以使用好最佳化的regularizer。

參考資料:
Machine Learning Foundation 14