返回文章列表

機器學習驗證模式與基線方案設計

本文探討機器學習模型驗證與基線方案設計,涵蓋滾動交叉驗證、常數基線、預訓練模型等方法,並以 Supermegaretail 需求預測和 PhotoStock 搜尋引擎為例,說明如何根據專案需求選擇合適的驗證策略和基線方案,確保模型評估的準確性和效率。

機器學習 系統設計

在機器學習系統開發中,選擇合適的驗證模式和基線方案至關重要。驗證模式確保模型評估的可靠性,而基線方案則提供效能比較基準。對於時間序列資料,滾動交叉驗證是一種有效的方法,可以模擬真實資料的到來方式。基線方案則從最簡單的常數基線開始,逐步增加複雜度,例如根據規則的模型、線性模型,最後才考慮深度學習模型。特徵工程同樣重要,應從最小特徵集開始,逐步新增互動特徵、計數特徵和嵌入特徵。此外,預訓練模型和簡單模型的微調也是常用的基線方法。選擇基線方案時需權衡模型的準確度、開發成本、可解釋性和計算時間。

驗證模式的選擇:設計檔案解析

在設計檔案中,選擇適當的驗證模式對於機器學習模型的評估至關重要。本文將探討 Supermegaretail 和 PhotoStock Inc. 的驗證模式選擇。

Supermegaretail 的驗證模式

需求分析

在評估 Supermegaretail 的驗證過程時,需要關注以下假設:

  • 新資料每天到達。
  • 資料可能延遲最多 48 小時到達。
  • 新標籤(銷售單位數量)隨新資料到達。
  • 最近的資料對於預測任務最相關。
  • 分類別矩陣每月變化 15%。
  • 資料中存在季節性(每週/每年迴圈)。

推理過程

在固定模型(在超引數最佳化過程中)後,我們在過去 2 年的資料上訓練它,並預測未來 4 周的需求。這個過程在內部和外部驗證中完全重現。需要注意的是,訓練和驗證集之間應該有 3 天的間隔,以準備資料可能延遲到達的事實。這將影響我們在構建模型時可以和不能計算的特徵。

內部和外部迴圈

我們使用兩層驗證。外部迴圈用於最終評估模型的效能,而內部迴圈用於超引數最佳化。

首先,對於外部迴圈,由於我們正在處理時間序列資料,滾動交叉驗證是一個明顯的選擇。我們設定 K = 5,以訓練五個具有最佳引數的模型。由於我們正在預測 4 周後的資料,驗證視窗大小在所有拆分中也由 28 天組成。集合之間有 3 天的間隔,步長為 7 天。

以下是外部迴圈的示例:

  • 第一個外部折疊:
    • 測試資料從 2022-10-10 到 2022-11-06(4 周)。
    • 訓練資料從 2020-10-07 到 2022-10-06(2 年)。
  • 第二個外部折疊:
    • 測試資料從 2022-10-03 到 2022-10-30。
    • 訓練資料從 2020-09-29 到 2022-09-28。

對於內部迴圈,在外部驗證的每個“訓練集”中,我們執行額外的滾動交叉驗證,具有三個折疊。每個內部迴圈訓練樣本也由 2 年的歷史資料組成,以捕捉年度和每週的季節性。我們使用內部迴圈來調整超引數或進行特徵選擇。

更新頻率

我們每週更新拆分,以及新的資料和標籤(以便每個驗證集始終包含整個星期)。這將幫助我們捕捉模型效能的區域性變化和趨勢。

此外,我們還有一個單獨的保留集作為基準(“黃金集”)。我們每 3 個月更新一次。它幫助我們跟蹤系統的長期改進。

程式碼實作

import pandas as pd
from sklearn.model_selection import TimeSeriesSplit

# 定義時間序列交叉驗證
tscv = TimeSeriesSplit(n_splits=5)

# 定義資料
data = pd.read_csv('data.csv')

# 定義特徵和目標變數
X = data.drop('target', axis=1)
y = data['target']

# 進行滾動交叉驗證
for train_index, val_index in tscv.split(X):
    X_train, X_val = X.iloc[train_index], X.iloc[val_index]
    y_train, y_val = y.iloc[train_index], y.iloc[val_index]
    # 在訓練資料上訓練模型
    model.fit(X_train, y_train)
    # 在驗證資料上評估模型
    model.evaluate(X_val, y_val)

程式碼解密:

上述程式碼使用 TimeSeriesSplit 對時間序列資料進行滾動交叉驗證。首先,我們定義了 TimeSeriesSplit 物件,指定了折疊數量 n_splits=5。然後,我們讀取資料並定義特徵和目標變數。接著,我們使用 tscv.split(X) 對資料進行滾動交叉驗證,得到訓練和驗證索引。最後,我們在訓練資料上訓練模型,並在驗證資料上評估模型。

這個程式碼片段展示瞭如何使用滾動交叉驗證來評估時間序列模型的效能。透過這種方法,我們可以更好地瞭解模型的泛化能力,並避免過擬合。

驗證框架與基準解決方案

在機器學習(ML)系統設計中,驗證框架和基準解決方案是確保模型預測能力和系統整體效能的關鍵組成部分。本章節將探討驗證框架的設計原則和基準解決方案的重要性,以及如何將這些概念應用於PhotoStock Inc.的搜尋引擎專案中。

驗證框架的設計原則

驗證框架的主要目的是準確評估模型的預測能力。為此,需要考慮以下四個主要問題:

  1. 代表性:驗證集和測試集應該能夠代表實際生產資料,即真實使用者查詢。
  2. 多樣性:驗證集和測試集應該涵蓋盡可能廣泛的主題和情境。
  3. 避免資料洩漏:同一個使用者的查詢應該只出現在訓練集、驗證集或測試集中的一個,以避免資料洩漏。
  4. 移除重複查詢:應該從資料集中移除重複的查詢,以避免資料洩漏。

實作驗證框架的步驟

  1. 按使用者分組查詢:將查詢按照使用者進行分組,每個查詢只分配給一個使用者。如果另一個使用者有相同的查詢,則忽略。

  2. 隨機分配使用者到訓練集、驗證集和測試集:使用固定的比例(例如90/5/5)將使用者隨機分配到訓練集、驗證集和測試集。

  3. 確定性分桶方法:使用使用者ID的雜湊值將使用者分配到不同的桶中,然後根據桶的數量和比例分配到不同的資料集。

def assign_bucket(user_id):
    _hash = sha1(user_id.encode()).hexdigest()
    return int(_hash, 16) % n_buckets

def assign_split(user_id):
    bucket = assign_bucket(user_id)
    if bucket < n_buckets * train_ratio:
        return 'train'
    elif bucket < n_buckets * (train_ratio + val_ratio):
        return 'val'
    else:
        return 'test'

內容解密:

  • assign_bucket函式:使用SHA1雜湊演算法對使用者ID進行雜湊,然後將雜湊值轉換為整數,並對桶的數量取模,實作使用者到桶的對映。
  • assign_split函式:根據桶的數量和設定的比例,將使用者分配到訓練集、驗證集或測試集。

基準解決方案的重要性

基準解決方案是機器學習系統中的最小可行產品(MVP),它能夠在不涉及複雜性的情況下提供價值。基準解決方案的主要目標包括:

  • 降低風險:透過最小化時間、成本和努力投入來測試產品假設。
  • 取得早期反饋:快速失敗並重新規劃。
  • 盡早提供使用者價值:透過階段性的更新產生可預測的收入。

基準解決方案的型別

  1. 常數基準:最簡單的基準,不涉及任何機器學習模型。
  2. 模型基準和特徵基準:比較不同的模型和特徵對系統效能的影響。
  3. 深度學習基準:針對特定問題設計的深度學習模型作為基準。

基線解的價值與實踐

在開發機器學習(ML)系統時,建立一個基線解(Baseline Solution)是至關重要的第一步。基線解提供了一個簡單、可行的初始方案,用於比較和評估後續更複雜模型的效能。本文將探討基線解的重要性、優勢、以及在不同情境下的應用。

為什麼需要基線解?

基線解的主要目的是提供一個比較的基準,以評估更複雜模型的價值。它不僅是一個簡單的模型,還具有多項優勢,包括:

  1. 簡單性:基線解通常易於構建和維護,不需要複雜的模型或大量的計算資源。
  2. 穩健性:由於簡單,基線解不容易出現過擬合或意外的行為。
  3. 可解釋性:非機器學習的同事更容易理解簡單模型的運作原理,從而增加對ML產品的信任。
  4. 可擴充套件性:基線解通常易於擴充套件,以適應不同的應用場景。

基線解的優勢

選擇一個合適的基線解有多項好處。首先,它允許團隊快速組裝一個可執行的ML系統,從而能夠及早進行測試和迭代。其次,基線解可以在主模型出現問題時作為備用方案,確保系統的穩定運作。

然而,儘管基線解具有多項優勢,但在實踐中卻常常被忽視。複雜性往往被視為是一種優勢,因為它能夠展示努力、專業知識和創新。然而,這種對複雜性的偏好往往導致不必要的複雜化,從而浪費時間和資源。

常數基線解

常數基線解是一種最簡單的基線解形式。它通常涉及預測一個固定的值或類別,無論輸入如何。這種方法在某些情況下可能足夠,例如當資料集中的某個類別佔主導地位時。

何時不需要基線解?

雖然基線解在大多數情況下是有用的,但在某些特定情況下,它們可能不是必要的或甚至是不相關的。例如:

  1. 準確性至關重要:在某些應用中,例如癌症檢測或自動駕駛,錯誤的成本太高,無法接受任何形式的簡化。
  2. 高度確定性:當我們對使用者的需求有明確的瞭解,或已經有成熟的經驗時,直接採用成熟的方案可能更為合理。
  3. 重建現有系統:如果已經有一個運作良好的系統,直接最佳化和改進現有系統可能比建立基線解更為有效。

基線解的建立:從簡單開始

在建立複雜模型之前,首先應該考慮一個簡單的基線模型。這種做法類別似於在建造橋樑之前,先思考最原始、最簡單的橋樑結構。一個好的基線模型可以為未來的機器學習(ML)系統奠定堅實的基礎。

從最簡單的解決方案開始

當我們開始尋找合適的基線時,通常會問自己:「什麼是最簡單的ML模型可以解決這個問題?」或者「我們應該從哪個ML模型開始?」但這些問題往往不是正確的。我們認為,正確的問題應該是:「我們是否需要ML來解決這個問題?」

有時,我們根本不需要ML,或者至少不應該重新發明輪子,而是可以使用第三方供應商的解決方案。正如第三章(第3.2節)所討論的那樣,這是一種可行的替代方案。

常數基線

如果我們決定建立自己的模型,好的建模應該從沒有模型開始:嘗試透過選擇解空間中最平凡和最懶惰的解決方案來破解定義的指標。這將是我們問題的第一個近似值。可以說,常數基線本身就代表了一個模型。透過常數基線,我們將所有依賴關係和互動作用近似為一個常數。

常數基線的例子

  • 迴歸任務:常數基線可以是平均值或中位數預測(在時間序列預測中,可以根據最後一天/周/月/年進行預測),或者根據最後可用的值(例如,對於相應的使用者或專案)進行預測。此外,這也可以是一些使用者定義的常數,以最大化指標。

  • 分類別任務:常數基線將是根據主要類別進行預測(例如,在反欺詐問題中,我們可以假設根本沒有欺詐行為),或者對正類別的機率進行常數預測。

  • 排名:常數基線可以是檔案的隨機順序,或者根據無關的數字屬性(如檔案ID)進行排序,或者使用簡單的啟發式方法,如「查詢關鍵字在專案描述中的數量」。

為什麼需要常數基線?

建立常數基線有兩個目標:

  1. 基準測試:獲得隨機預測的選定指標的基線值是有幫助的。一個簡單的健全性檢查是將您的模型與簡單的經驗法則進行比較。確實,如果花了2周時間進行硬核ML建模,最後在5分鐘內實作的最簡單的基線卻擊敗了您的模型,那將是令人遺憾的。這種情況在現實生活中相當常見。

  2. 提供備用方案:如果您的真實ML模型由於某些錯誤、執行時間限制或冷啟動問題(對於新使用者和新專案)而無法進行預測,或者它根本就出了故障,您的ML服務至少應該傳回一些東西。在這種情況下,常數基線就是您所需要的。

模型基線與特徵基線

如果我們沿著複雜度尺度進一步移動,我們的下一站是根據規則的模型。雖然在大多數情況下,我們很難在常數基線和根據規則的基線之間劃清界限,但後者通常可以定義為在某些分組基礎上的常數。

根據規則的基線例子

  • 以正規表示式開始解決自然語言處理問題是一個眾所周知且具有說服力的例子。

  • Arseny曾在一家計程車聚合公司工作,參與開發了一個服務,用於預測最近的汽車到達客戶的時間。他的同事,一位高階工程師,將其視為一個標準的迴歸任務,並從「始終預測5分鐘」或「如果行政區 == ‘曼哈頓’:傳回4」等模型開始。事實證明,這些型別的基線很難被硬核ML演算法擊敗。

基線模型的演進

典型的ML問題中的基線序列通常從以下開始:常數基線、根據規則的基線和線性模型。只有當這些基線不足以解決我們的任務時,我們才需要更複雜和專業的模型。

圖表說明

此圖示展示了在設計模型早期階段中典型的基線序列。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 機器學習驗證模式與基線方案架構

package "驗證模式設計" {
    component [滾動交叉驗證] as rolling
    component [內外層驗證迴圈] as nested
    component [時間序列分割] as timesplit
}

package "基線方案選擇" {
    component [常數基線] as constant
    component [規則基礎模型] as rule
    component [線性模型基線] as linear
    component [預訓練模型微調] as pretrain
}

package "特徵工程策略" {
    component [最小特徵集] as minimal
    component [互動特徵] as interaction
    component [嵌入特徵] as embedding
}

package "效能評估權衡" {
    component [準確度 vs 開發成本] as tradeoff
    component [可解釋性分析] as interpret
    component [計算時間評估] as compute
}

collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型

note right of feature
  特徵工程包含:
  - 特徵選擇
  - 特徵轉換
  - 降維處理
end note

note right of eval
  評估指標:
  - 準確率/召回率
  - F1 Score
  - AUC-ROC
end note

@enduml

此圖示清晰地展示了從簡單到複雜的基線模型的演進過程。

基線模型與特徵基線的重要性

在開發諸如推薦系統等機器學習應用時,初始階段往往從簡單的方法開始,例如常數檢索(constant retrieval),接著嘗試協同過濾(collaborative filtering)、因子分解機(factorization machines),最後才考慮深度學習模型(如深度結構化語義模型)。瞭解並實踐簡單的基線方法至關重要,因為它們往往能夠達到與複雜模型相媲美的表現。

簡單基線方法的有效性

研究表明,許多複雜的深度學習模型並不總是優於簡單的基線方法。例如,Maurizio Ferrari Dacrema 等人在2019年發表的論文《Are We Really Making Much Progress? A Worrying Analysis of Recent Neural Recommendation Approaches》中,對多個頂級會議上的推薦系統演算法進行了分析,發現其中大部分無法被輕易複製,且多數簡單的啟發式方法表現更佳。這表明,簡單的基線方法在很多情況下是足夠有效的。

具體例項

  • 在表格資料上,根據樹的模型(如隨機森林、梯度提升)通常優於深度神經網路,尤其是在中小型資料集上。
  • 在組合圖問題上,貪婪演算法往往優於圖神經網路。
  • 在多工學習問題上,簡單的平均方法可能與複雜的最佳化器表現相似。
  • 在專案推薦和檢索任務中,嵌入向量的點積可能優於神經協同過濾。

特徵基線的重要性

除了模型選擇,特徵工程也是構建基線的重要部分。在傳統機器學習中,特徵需要手動設計。特徵基線的構建應從最基本、最容易計算的特徵開始,然後逐步新增互動特徵、計數特徵、嵌入特徵等更複雜的特徵。

特徵新增順序

  1. 原始最小特徵集:從最基本的特徵開始。
  2. 各種互動和計數:新增特徵之間的互動作用和計數特徵。
  3. 嵌入特徵:利用嵌入技術生成特徵。
  4. 更複雜的特徵:最後考慮更複雜的特徵工程。

深度學習基線的多樣性

對於需要深度學習解決的問題,重用預訓練模型和訓練/微調簡單模型是常見的基線方法。例如,在影像識別任務中,可以利用在ImageNet資料集上預訓練的模型作為基線。對於某些問題,如影像或文字分類別,簡單的淺層模型(如線性模型或樸素貝葉斯)也可以作為有效的基線。

基線方案的多樣性與選擇

在機器學習專案中,建立一個有效的基線方案(baseline solution)是至關重要的第一步。基線方案提供了一個基準,用於衡量後續開發的模型或方法的效能改進。在本章中,我們將探討多種深度學習基線方案,以及如何選擇合適的基線。

深度學習基線的多樣性

  1. 預訓練模型的重複使用:對於許多常見問題,如語音識別、物件檢測、文字分類別和情感分析等,可以直接重複使用在大型資料集(如ImageNet)上預訓練的模型,無需從頭開始訓練。

  2. 特徵重複使用:使用預訓練模型的特徵(或稱為嵌入或表示)來訓練一個簡單的淺層模型。這種方法在資料集較小且任務相對簡單時尤其有用。

  3. 零樣本或少樣本學習:利用具有零樣本或少樣本學習能力的預訓練模型或第三方API。這類別模型(如GPT系列)能夠在無需或僅需少量訓練樣本的情況下提供結果。

  4. 從頭開始訓練簡單模型:如果上述方法都不奏效,可以嘗試從頭開始訓練一個簡單的模型。建議避免使用最新的、最先進的模型,而是選擇一些經過時間驗證的、較簡單的模型,如ResNet系列或BERT系列。

基線比較

在選擇基線時,需要綜合考慮多個因素,包括:

  • 準確度:模型的準確度或其他相關的機器學習指標。
  • 開發成本:主要指開發時間和計算資源。
  • 可解釋性:模型的可理解程度。
  • 計算時間:模型的推理時間。

內容解密:

在選擇基線方案時,必須在模型的準確度和開發成本之間進行權衡。開發成本主要涉及實作、訓練、除錯和測試模型所需的時間和計算資源。同時,也需要考慮模型的可解釋性和計算時間,以確保所選擇的基線方案能夠滿足專案的需求和限制。

選擇適當的基線

選擇基線的過程涉及對多個因素的綜合評估。首先,從簡單的基線(如常數基線或規則基線)開始,逐步增加模型的複雜度,同時監測效能指標的變化。如果簡單模型的效能已經足夠好,則可能不需要進一步增加模型的複雜度。

內容解密:

在評估基線時,可以將其視為在時間-準確度坐標系中的一個點。例如,常數基線對應於(0, 0)點,而線性模型可能對應於右上方的一個點,表示其需要更多的開發時間但提供了更好的準確度。透過這種方式,可以直觀地比較不同基線方案之間的權衡。

基線比較與設計檔案:基線解決方案

在機器學習(ML)專案中,建立基線(baseline)是評估模型效能的重要步驟。基線提供了一個初始的效能基準,用於比較不同模型的改進效果。本文將討論基線的重要性、特性以及如何設計基線解決方案。

基線的重要性

基線模型是簡單且易於實作的模型,用於提供一個比較基準。透過基線比較,可以瞭解更複雜模型的改進效果是否值得投入額外的資源。

成本效益比

隨著模型複雜度的增加,成本效益比可能會下降。例如,梯度提升(gradient boosting)等複雜模型可能需要更多的輸入和計算資源,但並不一定能帶來顯著的準確度提升。

基線的特性

一個好的基線應該具備以下特性:

  1. 簡單性:基線模型應該簡單易懂,易於實作和維護。
  2. 計算時間:基線模型的計算時間應該足夠快,以滿足即時系統的需求。
  3. 可解釋性:基線模型應該容易解釋,特別是在處理敏感或醫療資料時。

簡單性與可維護性

簡單的基線模型更容易維護和除錯。例如,線性迴歸(linear regression)具有精確的解析解,易於實作和理解。

設計檔案:基線解決方案

以下是針對虛構公司Supermegaretail和PhotoStock, Inc.的基線設計檔案範例。

Supermegaretail的基線解決方案

Supermegaretail的需求預測系統需要考慮季節性因素。以下是四種基線解決方案:

  1. 常數基線:使用前一週同一天的實際銷售值作為預測值。
  2. 進階常數基線:使用過去一年的資料計算分位數損失(quantile loss)。
  3. 線性模型基線:使用線性迴歸模型,結合多個滯後變數(lagged variables)和聚合特徵(aggregated features)。
  4. 時間序列特定基線:使用自迴歸整合移動平均(ARIMA)和季節性ARIMA(SARIMA)模型,或是Facebook開發的Prophet模型。
特徵基線

除了上述基線模型外,還可以加入額外的靜態特徵(static features),如產品品牌、類別、商店地理特徵等,以提升模型的準確度。

程式碼範例
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# 載入資料
data = pd.read_csv('sales_data.csv')

# 切分訓練和測試資料
train_data, test_data = train_test_split(data, test_size=0.2, random_state=42)

# 建立線性迴歸模型
model = LinearRegression()

# 訓練模型
model.fit(train_data[['lagged_sales']], train_data['sales'])

# 預測測試資料
predictions = model.predict(test_data[['lagged_sales']])

# 評估模型效能
mse = mean_squared_error(test_data['sales'], predictions)
print(f'MSE: {mse:.2f}')

內容解密:

  1. 載入必要的函式庫,包括pandas用於資料處理,sklearn.model_selection用於資料切分,sklearn.linear_model用於建立線性迴歸模型,以及sklearn.metrics用於評估模型效能。
  2. 使用pd.read_csv載入銷售資料。
  3. 使用train_test_split將資料切分為訓練集和測試集,測試集佔比20%。
  4. 建立一個線性迴歸模型,並使用訓練資料進行訓練。
  5. 使用訓練好的模型預測測試資料的銷售值。
  6. 使用mean_squared_error計算預測值與實際值的均方誤差(MSE),並輸出結果。

此範例展示瞭如何使用線性迴歸模型作為基線,並評估其效能。透過比較不同模型的MSE,可以選擇最合適的模型。