全面解析)
很多人問我機器學(xué)習(xí)入門最值得把原理原原本本學(xué)一遍的模型是什么我的答案一直是支持向量機。它明明只是一個二分類器卻把幾何間隔、凸優(yōu)化、對偶理論、核技巧全部串了起來讀一遍等于把機器學(xué)習(xí)里最硬核的幾塊地基都打了一遍。這篇是模型原理向的第一篇主要把支持向量機從目標(biāo)函數(shù)到對偶問題再到核函數(shù)的整條邏輯鏈走通不打算用“調(diào)用一個分類器就完事”來糊弄過去。文章適合三類人剛學(xué)完線性代數(shù)、想真正理解分類模型的初學(xué)者已經(jīng)在用支持向量機但總被 C 和 gamma 折磨的工程師準備算法崗位面試、需要把推導(dǎo)講清楚的人。準備好了就開始。1. 一句話看清支持向量機在做什么1.1 分類模型的本質(zhì)是找一條決策邊界支持向量機處理的是監(jiān)督學(xué)習(xí)里的分類問題。給定一組樣本 ((x_1, y_1), (x_2, y_2), \dots, (x_N, y_N))其中 (x_i) 是特征向量(y_i) 是類別標(biāo)簽在二分類場景下通常取 (1) 和 (-1)。模型要做的是在特征空間里找一個超平面 (w \cdot x b 0)把正樣本和負樣本分隔開。這里的“超平面”是直線在高維空間的推廣二維是一條線三維是一個平面更高維就沒辦法直觀畫出來了。分類時把樣本代入 (w \cdot x b)結(jié)果大于 0 判成正類小于 0 判成負類。所以支持向量機最核心的問題只有一個這個超平面應(yīng)該放在哪里。你可能覺得分對了不就行了問題是能把訓(xùn)練數(shù)據(jù)分對的超平面通常有無數(shù)個。稍微挪動一點點依然能讓所有樣本都分對但新的邊界對沒見過的數(shù)據(jù)可能完全不友好。支持向量機要做的就是從這無數(shù)個可行解里挑一個最穩(wěn)的。1.2 支持向量少數(shù)樣本決定最終模型“支持向量”這四個字點出了模型最本質(zhì)的特征最終影響邊界的只是訓(xùn)練集里極少一部分樣本。這些樣本位于決策邊界附近是“最難分”的那批點。只要它們的位置固定其他樣本無論怎么變化只要不越過邊界模型都不受影響??梢赃@樣類比一場考試劃獎學(xué)金線真正決定分數(shù)線的是排名剛好卡在名額邊緣的那幾位同學(xué)。前幾名考了多高的分其實不影響?yīng)剬W(xué)金線但邊緣同學(xué)的分數(shù)一旦變化獎學(xué)金線就會被推動。支持向量機里的支持向量就是這些“卡線”的樣本。這個特性帶來兩個直接好處第一訓(xùn)練完成后模型只需要保存支持向量不需要保存整個數(shù)據(jù)集預(yù)測階段的內(nèi)存和計算量都大幅下降第二模型不容易被距離邊界很遠的樣本干擾魯棒性比“每個樣本都參與決策”的模型更好。這一點也是支持向量機和邏輯回歸最明顯的差異邏輯回歸對所有樣本做概率建模每個樣本都會拉動決策邊界。1.3 間隔最大化為什么“分對”還不夠支持向量機追求的不只是把所有訓(xùn)練樣本分對還要讓決策邊界離最近的樣本盡量遠。這個“最近的樣本到邊界的距離”就是間隔。為什么要最大化它因為間隔越大分類器的“安全余量”越大。真實世界的數(shù)據(jù)總是帶噪聲的訓(xùn)練樣本稍微偏移一點一條貼著樣本的邊界就可能立刻出錯而一條離樣本足夠遠的邊界抗干擾能力明顯更強。統(tǒng)計學(xué)習(xí)理論也為間隔最大化提供了支撐對線性分類器來說間隔越大泛化誤差的上界越小。也就是說最大化間隔不僅是一個幾何上的直覺還是一個有理論保證的行為。后面所有數(shù)學(xué)推導(dǎo)本質(zhì)上都在圍繞“如何把這個間隔最大化的想法寫成可求解的優(yōu)化問題”展開。2. 從直覺到數(shù)學(xué)間隔最大化到底在優(yōu)化什么2.1 函數(shù)間隔與幾何間隔兩個容易混淆的定義在推導(dǎo)支持向量機時會遇到兩個名字很像的概念函數(shù)間隔和幾何間隔。函數(shù)間隔的定義是 (\hat{\gamma}_i y_i(w \cdot x_i b))。乘上 (y_i) 的原因很直接如果分類正確(w \cdot x_i b) 和 (y_i) 同號乘積為正分類錯誤乘積為負。所以函數(shù)間隔的符號能反映樣本是否被分對這一點比較好用。但函數(shù)間隔有一個致命問題它不能衡量“距離”。如果把 (w) 和 (b) 同時放大兩倍超平面本身一點沒變分類規(guī)則也沒變函數(shù)間隔卻變成了原來的兩倍。這說明函數(shù)間隔的值受參數(shù)尺度影響不能直接用來描述樣本到平面的遠近。幾何間隔的定義是 (\gamma_i \frac{y_i(w \cdot x_i b)}{|w|})。分母上的 (|w|) 把參數(shù)的縮放影響消掉了這時幾何間隔對應(yīng)的才是樣本到超平面的帶符號歐氏距離。支持向量機要最大化的是這個幾何間隔而不是函數(shù)間隔。2.2 從間隔到目標(biāo)函數(shù)(1/2|w|^2) 怎么來的因為函數(shù)間隔可以隨意縮放直接優(yōu)化幾何間隔會遇到一個尺度漂移的問題你可以把 (w) 任意縮小讓幾何間隔變得非常大但超平面的方向其實完全沒變這種“變大”沒有意義。所以必須先把尺度固定住。支持向量機的做法是令距離超平面最近的那個樣本的函數(shù)間隔等于 1。也就是說對所有樣本要求y_i(w · x_i b) ≥ 1在這個約束下最近樣本的幾何間隔恰好等于 (1/|w|)。最大化幾何間隔等價于最大化 (1/|w|)也等價于最小化 (|w|^2)。為了方便求導(dǎo)通常寫成最小化 (\frac{1}{2}|w|^2)。于是原始問題變成一個標(biāo)準的凸二次規(guī)劃min 1/2 ||w||^2 s.t. y_i(w · x_i b) ≥ 1, i 1, ..., N為什么強調(diào)它是凸問題因為凸優(yōu)化沒有局部最優(yōu)解這個坑目標(biāo)函數(shù)是二次的、約束是線性的可行域是凸集因此找到的解一定就是全局最優(yōu)。這一點讓支持向量機在優(yōu)化上非常干凈也是它能被大規(guī)模應(yīng)用的重要原因。2.3 固定函數(shù)間隔為 1 的尺度約定很多人第一次看支持向量機推導(dǎo)會在“為什么約束寫成 ≥ 1”這里卡住。其實這個 1 不是一個強行的魔法數(shù)字而是一個尺度約定。因為超平面 (w \cdot x b 0) 和 (2w \cdot x 2b 0) 表示的是同一個決策面所以參數(shù)的絕對大小本來就沒有固定含義。我們利用這種自由度把所有樣本的函數(shù)間隔下限統(tǒng)一壓到 1相當(dāng)于給參數(shù)定了一個標(biāo)尺。這個約定帶來的效果是(w) 的模長 (|w|) 成了間隔的倒數(shù)。模長越小間隔越大模長越大間隔越小。于是“最大化間隔”被轉(zhuǎn)化成了“最小化模長”而“樣本要分對且留有余量”被寫成了線性約束。理解了這個尺度約定后面看 KKT 條件時就不會覺得突兀。2.4 決策函數(shù)模型實際存什么超平面確定后分類決策函數(shù)就是f(x) sign(w · x b)在線性支持向量機中通過求解對偶問題可以得到 (w \sum_{i} \alpha_i y_i x_i)。把 (w) 代回決策函數(shù)就會發(fā)現(xiàn)真正參與預(yù)測計算的只有那些 (\alpha_i \neq 0) 的樣本也就是支持向量。其他樣本的 (\alpha_i) 都是 0它們在預(yù)測階段完全不會出現(xiàn)。所以支持向量機訓(xùn)練完成后模型里保存的并不是“一整條超平面方程然后用全部數(shù)據(jù)更新”而是一小撮支持向量和它們對應(yīng)的權(quán)重。這個稀疏性在部署時很值錢尤其是在嵌入式設(shè)備或者接口服務(wù)里需要控制模型體積的場景。3. 對偶問題為什么非要把原始優(yōu)化變個形3.1 直接優(yōu)化原始問題的瓶頸原始問題是以 (w) 和 (b) 為變量的優(yōu)化問題變量數(shù)量等于特征維度加 1。如果特征維度很高比如文本處理中動輒幾十萬維直接拿通用二次規(guī)劃求解器去優(yōu)化原始問題計算量會非常夸張。對偶問題的變量數(shù)是 (\alpha_1, \alpha_2, \dots, \alpha_N)恰好等于訓(xùn)練樣本數(shù)。當(dāng)樣本數(shù)遠小于特征維度時對偶問題的規(guī)模比原始問題小得多。反過來當(dāng)樣本數(shù)很大時對偶問題又變得很難處理。所以支持向量機其實存在兩種形態(tài)線性支持向量機在樣本量大時用專門方法求解原始問題非線性支持向量機在對偶問題上做文章。理解這一點后面看工業(yè)實現(xiàn)時會清楚很多。3.2 拉格朗日乘子法推導(dǎo)過程把原始問題加上拉格朗日乘子 (\alpha_i \geq 0)構(gòu)造拉格朗日函數(shù)L(w, b, α) 1/2 ||w||^2 - Σ α_i [ y_i(w · x_i b) - 1 ]對 (w) 求偏導(dǎo)并令其等于 0得到w Σ α_i y_i x_i對 (b) 求偏導(dǎo)并令其等于 0得到Σ α_i y_i 0把這兩個結(jié)果代回拉格朗日函數(shù)(w) 和 (b) 會被消掉剩下的函數(shù)只含 (\alpha)。原來的問題是先對 (w, b) 做最小化再對 (\alpha) 做最大化消元之后它就變成了一個純粹關(guān)于 (\alpha) 的最大化問題。這段推導(dǎo)是支持向量機最核心的手推內(nèi)容面試時也經(jīng)常被要求現(xiàn)場寫。建議不要只背結(jié)論自己拿紙筆推一遍把每一步為什么能消元搞清楚。3.3 對偶目標(biāo)函數(shù)長什么樣消元之后得到的對偶問題如下max Σ_i α_i - 1/2 Σ_i Σ_j α_i α_j y_i y_j (x_i · x_j) s.t. α_i ≥ 0 Σ_i α_i y_i 0這是一個變量數(shù)為 (N) 的二次規(guī)劃。最值得注意的地方是樣本 (x_i) 和 (x_j) 在目標(biāo)函數(shù)里永遠以內(nèi)積 (x_i \cdot x_j) 的形式出現(xiàn)。這個“內(nèi)積形式”是整個核技巧的伏筆后面能不能處理非線性問題靠的就是把這個內(nèi)積替換成核函數(shù)。從矩陣視角看可以定義矩陣 (Q_{ij} y_i y_j (x_i \cdot x_j))那么目標(biāo)函數(shù)就是 (\sum \alpha_i - \frac{1}{2} \alpha^T Q \alpha)。矩陣 (Q) 是半正定的所以對偶問題同樣是凸優(yōu)化。3.4 KKT 條件支持向量的數(shù)學(xué)標(biāo)志原始問題和對偶問題要想有相同的解必須滿足 KKT 條件。其中最關(guān)鍵的一條是互補松弛條件α_i [ y_i(w · x_i b) - 1 ] 0這個等式帶來一個非常漂亮的結(jié)論如果 (\alpha_i 0)那么括號里的值必須等于 0也就是說樣本 (x_i) 正好落在函數(shù)間隔等于 1 的邊界上它就是支持向量如果樣本遠離邊界括號里的值大于 0為了讓等式成立(\alpha_i) 必須等于 0。所以“支持向量”不是一個人為圈定的概念而是優(yōu)化問題解完之后自然浮現(xiàn)出來的樣本集合。這也是為什么支持向量機的名字起得極其精準真正撐住決策邊界的就是那一小撮樣本。3.5 對偶問題帶來的兩個工程收益對偶化至少帶來兩個實實在在的收益。第一核函數(shù)可以無縫嵌入。既然目標(biāo)函數(shù)里只有內(nèi)積 (x_i \cdot x_j)那直接把內(nèi)積替換成核函數(shù) (K(x_i, x_j))就能在高維特征空間中做線性分類而實際計算量沒有明顯增加。這個收益在下一節(jié)展開。第二當(dāng)特征維度遠大于樣本數(shù)時對偶問題的規(guī)模遠小于原始問題。比如有 1000 個樣本、100 萬維特征原始問題要解 100 萬個變量對偶問題只需要解 1000 個變量。這種場景下對偶形式就是救命的。不過對偶也不是沒有代價。它的優(yōu)化難度和樣本數(shù)強相關(guān)當(dāng)樣本量到百萬級別時(N \times N) 的核矩陣根本存不下來。所以在工業(yè)級的線性分類場景里大家反而更愿意回到原始問題用專門為線性支持向量機設(shè)計的優(yōu)化器。4. 軟間隔數(shù)據(jù)不干凈才是常態(tài)4.1 硬間隔的短板離群點會帶崩邊界前面推導(dǎo)的硬間隔支持向量機要求所有訓(xùn)練樣本都滿足 (y_i(w \cdot x_i b) \geq 1)一個都不允許放行。這個要求看上去很美但現(xiàn)實數(shù)據(jù)里幾乎不存在嚴格線性可分的情況。就算存在也可能是噪聲樣本碰巧把空間切開了硬間隔會讓邊界變得極其敏感。舉例來說數(shù)據(jù)里有一個點明顯是標(biāo)注錯誤落到了對方陣營里。硬間隔為了滿足所有約束會把決策邊界強行拉向這個異常點邊界變得扭曲泛化能力急劇下降。這個問題不解決支持向量機就沒法在真實項目里使用。4.2 松弛變量和目標(biāo)函數(shù)的變化軟間隔的做法是給每個樣本引入一個松弛變量 (\xi_i \geq 0)允許樣本突破“函數(shù)間隔至少為 1”的約束突破多少懲罰多少。約束變成y_i(w · x_i b) ≥ 1 - ξ_i目標(biāo)函數(shù)變成min 1/2 ||w||^2 C Σ_i ξ_i這里的 (C) 是懲罰系數(shù)。(\xi_i) 的含義可以拆開看等于 0 時樣本在正確位置且留有足夠間隔大于 0 但小于 1 時樣本落進了間隔帶里但分類還是對的大于等于 1 時樣本已經(jīng)被錯誤分類。所以軟間隔并不是放棄約束而是允許約束以一定的代價被違反。4.3 等價損失視角合頁損失與正則化把軟間隔的約束寫進目標(biāo)函數(shù)可以得到一個非常直觀的等價形式min 1/2 ||w||^2 C Σ_i max(0, 1 - y_i(w · x_i b))第二項就是著名的 hinge loss中文常叫合頁損失。它的行為很特別當(dāng) (y_i(w · x_i b) \geq 1)損失直接歸零當(dāng)樣本落在間隔帶內(nèi)或分錯時損失隨著距離線性增長。對比邏輯回歸里的對數(shù)損失合頁損失更“克制”。邏輯回歸的每個樣本只要不是無窮遠都會持續(xù)對模型產(chǎn)生影響合頁損失則對已經(jīng)分得足夠好的樣本完全放手。這正好解釋了支持向量機為什么天然稀疏只要樣本離邊界足夠遠它對模型不再有任何拉動作用。從正則化的角度理解第一項 (\frac{1}{2}|w|^2) 是結(jié)構(gòu)風(fēng)險項第二項 (C \sum \xi_i) 是經(jīng)驗風(fēng)險項。(C) 本質(zhì)上就是這兩者之間的天平它控制的是“你要更平滑的邊界還是更少訓(xùn)練錯誤”。4.4 C 值怎么選交叉驗證的方法(C) 的理論取值范圍是 ((0, \infty))實際調(diào)參時按數(shù)量級去掃比較高效。常見的做法是先跑一輪對數(shù)網(wǎng)格比如 0.01、0.1、1、10、100找到表現(xiàn)比較好的區(qū)間再在最優(yōu)值附近加密網(wǎng)格做細調(diào)。選 (C) 不能靠單次訓(xùn)練集精度判斷最好用交叉驗證。觀察驗證曲線時有個常見規(guī)律(C) 增大訓(xùn)練集精度持續(xù)上升驗證集精度通常先升后降開始下降的那個點往往就是過擬合的起點。如果驗證曲線一直上漲不下降說明問題可能不在 (C)而在核函數(shù)參數(shù)或特征預(yù)處理上不要盲目繼續(xù)加大 (C)。5. 核函數(shù)支持向量機如何做到非線性5.1 線性不可分先升維再看有些數(shù)據(jù)在原特征空間里就是線性不可分的比如二維平面上的同心圓分布一類在里圈一類在外圈任何直線都切不開。但如果在原始特征上增加一個“半徑”特征把二維點映射到三維讓內(nèi)圈的點半徑小、外圈的點半徑大那么一個平面就能把它們分開。這就是處理非線性問題的核心思路把原始特征映射到更高維的空間在高維空間里做線性分類回到原空間就變成了非線性邊界。問題是手工設(shè)計高維映射非常困難而且特征空間可能高到無法想象直接顯式計算映射后的向量根本不現(xiàn)實。5.2 核技巧不用展開高維特征的“查書函數(shù)”對偶問題里有一個幸運的結(jié)構(gòu)樣本 (x_i) 和 (x_j) 永遠以內(nèi)積 (x_i \cdot x_j) 的形式出現(xiàn)。如果映射是 (\phi(x))那么高維空間里的內(nèi)積是 (\phi(x_i) \cdot \phi(x_j))。核技巧要做的事情就是直接定義一個函數(shù)K(x_i, x_j) φ(x_i) · φ(x_j)然后把這個函數(shù)值代入對偶目標(biāo)替換掉內(nèi)積。整個過程完全不需要顯式算出 (\phi(x))。這里可以用一個類比來理解你不需要把一整本書的內(nèi)容都背下來只需要一個能快速查詢問題答案的工具核函數(shù)就是那個工具。它告訴你兩個樣本在高維空間的內(nèi)積是多少卻不告訴你高維向量長什么樣。RBF 核更夸張它對應(yīng)的特征空間是無窮維的。如果要求先算出無窮維向量再做內(nèi)積那計算量是不可能完成的但直接用 (\exp(-\gamma|x - z|^2)) 計算卻非常簡單。這就是核技巧被稱為“技巧”的原因它讓不可能的計算變成了幾行公式。5.3 常用核函數(shù)怎么選實際工程中最常見的核函數(shù)有四個核函數(shù)表達式適用場景注意點線性核(x_i \cdot x_j)特征維度很高、樣本量很大、文本類數(shù)據(jù)最快可解釋性強多項式核((\gamma x_i \cdot x_j r)^d)對特征交互階數(shù)有先驗時參數(shù)多易數(shù)值不穩(wěn)定RBF 核(\exp(-\gamma|x_i - x_j|^2))中小規(guī)模結(jié)構(gòu)化數(shù)據(jù)默認首選(\gamma) 對結(jié)果影響很大sigmoid 核(\tanh(\gamma x_i \cdot x_j r))偶爾使用可能不滿足正定性容易失效一個比較穩(wěn)妥的選擇順序是先試線性核如果效果不夠好再試 RBF 核。數(shù)據(jù)規(guī)模很大或特征已經(jīng)非常稀疏時線性核通常又快又夠用數(shù)據(jù)規(guī)模適中、特征稠密且有非線性關(guān)系時RBF 核更能發(fā)揮核技巧的威力。5.4 gamma 參數(shù)RBF 的“作用半徑”RBF 核的公式里(\gamma) 決定了每個樣本影響的“半徑”。(\gamma) 越大(\sigma) 越小樣本的影響范圍越窄每個支持向量都只在很小范圍內(nèi)起作用決策邊界會變得非常曲折容易過擬合(\gamma) 越小樣本的影響范圍越寬邊界越平滑但過小了會把兩類樣本合并成一個大面團造成欠擬合。如果把特征標(biāo)準化到均值 0 方差 1一個常用的起點是 (\gamma 1/\text{特征維度})但這只是個起點不是最優(yōu)值。實際調(diào)參時人們常把 (\gamma) 和 (C) 放在一起做網(wǎng)格搜索比如 (C \in {0.1, 1, 10, 100})(\gamma \in {0.001, 0.01, 0.1, 1})。這兩個參數(shù)是聯(lián)動的單獨調(diào)一個往往找不到好點。5.5 Mercer 條件并不是任何相似度都行不是隨便定義一個相似度函數(shù)就能當(dāng)核函數(shù)用。核函數(shù)要成立需要滿足 Mercer 條件通俗地說就是對任意一組樣本核矩陣 (K_{ij} K(x_i, x_j)) 必須是半正定的。只有半正定才能保證它等價于某個高維空間里的內(nèi)積也才能保證優(yōu)化問題仍然是凸的。如果你試著自定義核函數(shù)比如用某種自定義距離構(gòu)造相似度必須小心。一個不滿足 Mercer 條件的核輕則優(yōu)化不收斂重則結(jié)果完全沒意義。工程上如果沒有充分驗證盡量不要自己發(fā)明核函數(shù)。經(jīng)典核函數(shù)經(jīng)過大量實踐檢驗比新造一個輪子靠譜得多。6. 從推導(dǎo)到實現(xiàn)支持向量機是怎么解出來的6.1 SMO 求解思路兩個 α 一個子問題對偶問題雖然是一個凸二次規(guī)劃但直接用通用 QP 求解器處理大規(guī)模數(shù)據(jù)仍然太慢。SMO序列最小優(yōu)化算法的核心思想非常巧妙每次只挑兩個變量 (\alpha_i) 和 (\alpha_j) 來優(yōu)化其他變量全部固定。為什么要挑兩個而不是一個因為對偶問題里有一個線性約束 (\sum \alpha_i y_i 0)如果只改一個變量約束必然被破壞。改成兩個之后當(dāng)一個變量變化時另一個變量可以根據(jù)約束自動調(diào)整保持等式成立。兩個變量的子問題可以用解析方法直接求解不需要迭代數(shù)值優(yōu)化。外循環(huán)負責(zé)挑一個最違反 KKT 條件的樣本內(nèi)循環(huán)負責(zé)挑一個能和它形成最大優(yōu)化步長的樣本。SMO 在絕大多數(shù)情況下不需要像通用 QP 那樣存下整個核矩陣內(nèi)存占用小速度也快。這也解釋了為什么支持向量機能在個人電腦上處理幾萬條樣本。6.2 一套可復(fù)用的支持向量機訓(xùn)練流程工程實現(xiàn)上無論用什么工具庫流程基本一致。下面是一個接口示意具體方法名以你使用的庫為準scaler Scaler() X_train_norm scaler.fit_transform(X_train) X_test_norm scaler.transform(X_test) model SVCClassifier(kernelrbf, C1.0, gammascale) model.fit(X_train_norm, y_train) print(train_acc, model.score(X_train_norm, y_train)) print(test_acc, model.score(X_test_norm, y_test)) print(support_vectors_count, len(model.support_vectors_))流程拆開看先標(biāo)準化特征再初始化模型然后在標(biāo)準化后的數(shù)據(jù)上訓(xùn)練最后還要看一個容易忽略的指標(biāo)——支持向量數(shù)量。如果支持向量數(shù)量幾乎等于訓(xùn)練樣本數(shù)說明模型邊界非常扭曲這是過擬合的警報。6.3 特征預(yù)處理支持向量機比很多模型都敏感支持向量機對特征尺度非常敏感這一點比樹模型要明顯得多。因為它的核心運算是內(nèi)積和距離如果某個特征的量綱特別大比如收入從 0 到 100000而年齡從 0 到 100那么在計算距離時收入特征會完全主導(dǎo)結(jié)果年齡特征相當(dāng)于被無視了。所以用支持向量機之前特征標(biāo)準化是默認動作。最常用的方法是 Z-scorex_new (x - mean) / std把每個特征變成均值 0、方差 1。對稀疏特征場景比如 TF-IDF 之后的文本向量是否標(biāo)準化要看具體情況但如果要用 RBF 核一般還是建議做歸一化處理否則 (\exp(-\gamma|x - z|^2)) 中的距離很可能被某些異常大值帶偏。6.4 多分類一對多與一對一的取舍支持向量機天然是二分類器處理多分類時需要把多個二分類器組合起來。常見策略有兩種一對多one-vs-rest訓(xùn)練 (K) 個分類器每個分類器負責(zé)區(qū)分“第 k 類”和“其他類”一對一one-vs-one訓(xùn)練 (K(K-1)/2) 個分類器每兩個類別之間訓(xùn)練一個最后投票決定結(jié)果。一對一策略在小類別數(shù)下效果穩(wěn)定但類別一多模型數(shù)量會爆炸。比如 10 個類別就要訓(xùn)練 45 個分類器20 個類別要訓(xùn)練 190 個。一對多策略模型數(shù)量少但每個分類器面對的正負樣本比例可能嚴重失衡。實務(wù)中類別數(shù)不大時可以用一對一類別很多時優(yōu)先考慮一對多。6.5 距離不是概率概率校準是怎么回事支持向量機給出的決策值 (w \cdot x b) 是樣本到超平面的距離它反映的是“離邊界多遠”并不是“屬于正類的概率有多大”。如果需要概率輸出通常會做一層校準最常見的是 Platt 縮放在決策值上訓(xùn)練一個邏輯回歸把距離映射到 ((0, 1)) 區(qū)間。校準的過程必須額外小心如果直接用訓(xùn)練數(shù)據(jù)來擬校準器會嚴重過擬合得到非常自信的錯誤概率。正確做法是用交叉驗證得到的決策值來訓(xùn)練校準器或者預(yù)留一部分數(shù)據(jù)。記住一個前提支持向量機校準后的“概率”只是決策值的單調(diào)映射并不是貝葉斯意義上的真實概率對比置信度時要留個心眼。7. 調(diào)參與避坑支持向量機項目落地記錄7.1 高維稀疏數(shù)據(jù)別上來就 RBF我踩過的第一個坑就是在高維稀疏特征上直接用 RBF 核。當(dāng)時做一個文本分類任務(wù)TF-IDF 之后特征維度到了幾十萬樣本量幾萬。RBF 核訓(xùn)練非常慢核矩陣計算量巨大最后的準確率也沒有比線性核高出哪怕一個百分點。這類數(shù)據(jù)的特征空間本來就已經(jīng)很高維線性核往往夠用強行再套 RBF 等于疊床架屋。換成線性核之后訓(xùn)練時間大幅下降模型體積也更小。所以“默認用 RBF”成立的前提是低維稠密的結(jié)構(gòu)化數(shù)據(jù)而不是高維稀疏文本數(shù)據(jù)。7.2 訓(xùn)練集滿分驗證集掉分C 和 γ 的聯(lián)動調(diào)試一個手寫數(shù)字識別小項目時出現(xiàn)過訓(xùn)練集準確率接近 100%、驗證集準確率掉到 80% 的情況。檢查之后發(fā)現(xiàn)罪魁禍首是 (\gamma) 設(shè)得太大。RBF 核的 (\gamma) 過大每個樣本都只影響自己周圍很小的區(qū)域決策邊界像一朵帶刺的花緊貼著訓(xùn)練點走訓(xùn)練集自然幾乎滿分泛化自然很差。處理辦法是同時降低 (\gamma) 和 (C)。(\gamma) 讓邊界變平滑(C) 減少對訓(xùn)練誤差的過分執(zhí)著。調(diào)整之后驗證集準確率回到 94% 左右。這個案例說明看到過擬合不要只想到調(diào)小 (C)(\gamma) 對 RBF 影響往往更直接。7.3 類別不平衡支持向量被多數(shù)類淹沒當(dāng)正負樣本比例嚴重失衡時支持向量機的表現(xiàn)會非常糟糕。原因很直觀目標(biāo)函數(shù)里所有樣本的松弛變量求和多數(shù)類的錯誤會占大頭模型只要把所有樣本都判成多數(shù)類總損失就很小。少數(shù)類樣本幾乎沒有機會成為支持向量邊界自然偏向多數(shù)類。對策有三種一是給少數(shù)類樣本更高的權(quán)重相當(dāng)于放大它的 (C)二是對少數(shù)類做過采樣比如人工合成新的少數(shù)類樣本三是改用專門的代價敏感學(xué)習(xí)。評估指標(biāo)上別只看準確率這種情況要特別關(guān)注精確率、召回率和 F1。準確率在這個場景下會欺騙人。7.4 訓(xùn)練時間與內(nèi)存什么時候支持向量機不合適當(dāng)樣本量達到幾十萬甚至上百萬支持向量機的訓(xùn)練時間和內(nèi)存消耗會明顯吃緊。原因在于對偶問題要處理 (N \times N) 的核矩陣百萬樣本的核矩陣幾乎不可能完整放進內(nèi)存。這種情況下有幾種退路使用線性核加專門優(yōu)化器訓(xùn)練成本比非線性核低很多對樣本做隨機采樣先在小數(shù)據(jù)集上驗證效果或者先用特征降維把維度壓下來再用 RBF。如果問題規(guī)模還是太大就要考慮換成更適合大數(shù)據(jù)的模型了。支持向量機的優(yōu)雅和它的代價是并存的不存在萬能模型。7.5 支持向量占比過高的排查訓(xùn)練結(jié)束后多看一眼支持向量數(shù)量占樣本總數(shù)的比例是一個好習(xí)慣。如果這個比例接近 100%說明模型基本把訓(xùn)練集全背下來了邊界非常復(fù)雜泛化能力值得懷疑。常見原因包括 (C) 太大、(\gamma) 太大、數(shù)據(jù)噪聲過多或者當(dāng)前數(shù)據(jù)根本不適合用這個模型。排查順序建議是先調(diào)小 (C)再調(diào)小 (\gamma)如果效果不明顯檢查訓(xùn)練數(shù)據(jù)里有沒有大量邊界糾纏的樣本。也可以用線性核對同一份數(shù)據(jù)做個對比如果線性核效果差不了太多那優(yōu)先選線性核模型越簡單越不容易出事。8. 常見問題與排查速查8.1 常見問題排查速查表現(xiàn)象可能原因處理辦法訓(xùn)練集準確率高驗證集掉分過擬合(\gamma) 或 (C) 偏大降低 (\gamma)調(diào)小 (C)檢查支持向量占比訓(xùn)練集和驗證集都低欠擬合模型太弱提高 (\gamma) 或 (C)檢查特征標(biāo)準化訓(xùn)練非常慢樣本多核矩陣太大換線性核、采樣、降維支持向量數(shù)量幾乎等于樣本數(shù)邊界過擬合參數(shù)過大調(diào)小 (C)、(\gamma)清洗噪聲預(yù)測結(jié)果幾乎全是多數(shù)類類別不平衡設(shè)置類別權(quán)重少數(shù)類過采樣概率輸出偏高且不靠譜概率校準過擬合交叉驗證擬合校準器內(nèi)存不足核矩陣無法加載線性核、分塊計算、降維自定義核表現(xiàn)極差核函數(shù)不滿足條件回到經(jīng)典核函數(shù)8.2 一個更省事的實踐順序如果你想快速跑出一個能用的支持向量機模型我建議按這個順序操作先做特征標(biāo)準化。然后根據(jù)數(shù)據(jù)規(guī)模選核函數(shù)樣本量小、特征稠密用 RBF樣本量大或特征稀疏用線性核。初始化參數(shù)時(C) 取 1(\gamma) 取1/特征維度。跑一個交叉驗證網(wǎng)格重點看 (C) 和 (\gamma) 的交互。模型訓(xùn)練好之后檢查支持向量占比同時回憶一下類別是否均衡如果不均衡給少數(shù)類加權(quán)重并換用 F1 評估。這幾步看起來簡單但能解決八成以上的支持向量機實戰(zhàn)問題。至于那些數(shù)學(xué)推導(dǎo)它們會在你真正需要調(diào)參、解釋模型、設(shè)計核函數(shù)的時候變成最重要的底氣。最后說點個人經(jīng)驗。我做了不少支持向量機相關(guān)的實驗最深的體會是它的數(shù)學(xué)證明很漂亮但真正讓它在工程里有效的往往不是邊界公式本身而是數(shù)據(jù)預(yù)處理、參數(shù)耦合和類別結(jié)構(gòu)。調(diào)參時不要一上來就掃大網(wǎng)格先把數(shù)據(jù)標(biāo)準化、選對核類型再去看 (C) 和 (\gamma) 的交互。支持向量占比和驗證集精度一樣是需要一直盯著的指標(biāo)。按這條思路走一遍大多數(shù)坑都能提前避開。