最近完成公司的 AI 培訓後,開始思考我們說的模型(Model)跟軟體開發中的領域模型(Domain Model)是否有關聯,如果仔細思考,似乎在抽象層面上是類似的。
模型
領域模型通常指的是封裝商業邏輯(Business Logic)的部分,而且跟特定領域有很深入的關聯。軟體開發中我們去設計一個領域模型,也是為了讓我們可以處理特定類型的邏輯。
舉例來說,假設有一個以關鍵字判斷惡意網址的系統,我們可能會預期輸入(Input)是網址,輸出(Output)則是一個評分,中間的判斷可能是一些正規表達式(Regexp)和預先設計好的關鍵字名單。
1type URL string
2type Score float
3
4type AntiScam interface {
5 Execute(input URL) Score
6}
如果改成用機器學習來處理這件事情,我們從人工篩選關鍵字,轉換到讓機器自己學習哪些關鍵字是有惡意的,進而判斷某個網址是否帶有惡意,那麼輸入跟輸出的介面(Interface),跟原本我們設計的領域模型實際上是相同的。
從抽象的角度去看,模型的建構差異只在於是否人工還是自動(或半自動)的建立。
訓練
在機器學習中,要對模型進行訓練才能夠處理特定的任務。以監督式學習(Supervised Learning)的方式進行時,會需要提供 Ground Truth 來對資料標注,讓機器可以理解到怎樣是正確,或者預期看到的結果。
例如,我們可以提供一些訓練資料
url | score |
---|---|
https://i-am-scam.com | 10 |
https://i-am-safe.com | 100 |
https://hi-scame.com | 5 |
訓練時,根據我們對網址的編碼(Encode)和分數的關聯(如:scam
~= 10
)得到一個模型,並且透過訓練資料的一部分當作測試,後續反覆調整參數(Hyper Parameter)後得到一個最佳的參數用於模型。
關於模型的訓練,網路上有許多文章能更詳細的說明,這邊只簡單介紹概念。
對應到驗收測試驅動開發(ATDD,Acceptance test-driven development)的情境,我們也是在做相同的事情,有測試資料以及訓練過程(反覆修正程式)的情境,概念上可能是非常接近的。
首先,由團隊先撰寫測試(訓練資料)
1Feature: Anti Scam Checker
2 Scenario: give a scam url and return lower score
3 Given a url as input "https://i-am-scam.com"
4 When I run the anti-scam checker
5 Then the score is 10
接下來進行實作,跟模型訓練相同的情境,我們會從失敗(成果不理想)開始出發,嘗試改進這個模型
1type KeywordBasedAntiScam struct {
2}
3
4func (m *KeywordBasedAntiScam) Execute(input URL) Score {
5 return Score(100)
6}
隨著實作更加完善,我們的模型就能得到更好的分數
1func (m *KeywordBasedAntiScam) Execute(input URL) Score {
2 score := Score(100)
3 // ...
4 for _, keyword := range m.Keywords {
5 hasScamKeyword := strings.Contains(input, keyword)
6 if hasScamKeyword {
7 score -= m.Weights[keyword]
8 }
9 }
10
11 return score
12}
最後就能夠得到一個通過測試的領域模型,雖然跟機器學習相比測試資料的規模、複雜度都不同,但是在改善正確性這件事情上本質還是一樣的,也許可以認為是當下提升對特定領域理解的最佳實踐。
雜訊
最近在讀的雜訊:人類判斷的缺陷一書中,提到許多依靠經驗、直覺、偏見(Bais)判斷的情況,讓許多法律判斷、行情預測等結果有許多差異。
而透過機器學習產生的模型進行判斷,通常雜訊(Noise)的情況會減少許多,在各種參數的權重(Weights)配比上也能找到更適合的分配方式,讓每一次的評估結果都接近一致。
之所以能做到這點,從監督式學習的訓練過程中可以發現,我們會以訓練資料的一部分來驗證輸出,同時不斷的調整到大多數情境都符合這個輸出結果,中間對於不同資訊的參考、排除就是一種消除雜訊的方式。
如果應用在軟體開發上,我們撰寫驗收測試也是為了避免開發團隊跟產品負責人(Product Owner)的認知有差異,假設單純依靠開發團隊想像,這些假想就變成一種雜訊存在於開發過程中,那麼最終的成果就會變得不可預測,或者偏離目標。
如果想要明確的對結果做評估,使用舉例的方式效果會更好,如同訓練資料中提供輸入、輸出是什麼,訓練過程則要想辦法讓輸入跟輸出接近測試的內容。
從這點來看,機器學習跟軟體開發剛好在不同的情境對不同需求的模型建構,是能夠相輔相成的。