蒼時弦也
蒼時弦也
資深軟體工程師
發表於

驗收測試驅動開發與 AI 訓練相似之處

最近完成公司的 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 來對資料標注,讓機器可以理解到怎樣是正確,或者預期看到的結果。

例如,我們可以提供一些訓練資料

urlscore
https://i-am-scam.com10
https://i-am-safe.com100
https://hi-scame.com5

訓練時,根據我們對網址的編碼(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)的認知有差異,假設單純依靠開發團隊想像,這些假想就變成一種雜訊存在於開發過程中,那麼最終的成果就會變得不可預測,或者偏離目標。

如果想要明確的對結果做評估,使用舉例的方式效果會更好,如同訓練資料中提供輸入、輸出是什麼,訓練過程則要想辦法讓輸入跟輸出接近測試的內容。

從這點來看,機器學習跟軟體開發剛好在不同的情境對不同需求的模型建構,是能夠相輔相成的。