Scikit-Learn - 支援向量機



本章討論一種稱為支援向量機 (SVM) 的機器學習方法。

介紹

支援向量機 (SVM) 是一種強大而靈活的監督式機器學習方法,用於分類、迴歸和異常值檢測。SVM 在高維空間中非常有效,通常用於分類問題。SVM 廣受歡迎且記憶體效率高,因為它們在決策函式中使用了訓練點的子集。

SVM 的主要目標是將資料集劃分為多個類別,以便找到一個**最大間隔超平面 (MMH)**,這可以透過以下兩個步驟完成:

  • 支援向量機將首先迭代生成超平面,以最佳方式分離類別。

  • 之後,它將選擇正確分離類別的超平面。

SVM 中的一些重要概念如下:

  • **支援向量** - 可以定義為最靠近超平面的資料點。支援向量有助於確定分離線。

  • **超平面** - 分割具有不同類別的物件集的決策平面或空間。

  • **間隔** - 不同類別最靠近資料點之間的兩條線之間的間隙稱為間隔。

以下圖表將讓您深入瞭解這些 SVM 概念:

Marginal Hyperplane

Scikit-learn 中的 SVM 支援稀疏和密集樣本向量作為輸入。

SVM 的分類

Scikit-learn 提供了三個類,即**SVC、NuSVC** 和**LinearSVC**,它們可以執行多類分類。

SVC

它是 C 支援向量分類,其實現基於**libsvm**。Scikit-learn 使用的模組是**sklearn.svm.SVC**。此類根據一對一方案處理多類支援。

引數

下表包含**sklearn.svm.SVC** 類使用的引數:

序號 引數及描述
1

C - float,可選,預設值 = 1.0

它是誤差項的懲罰引數。

2

kernel - string,可選,預設值 = 'rbf'

此引數指定演算法中要使用的核心型別。我們可以從以下選項中選擇一個:**'linear'、'poly'、'rbf'、'sigmoid'、'precomputed'**。核心的預設值為**'rbf'**。

3

degree - int,可選,預設值 = 3

它表示“poly”核心函式的度數,其他所有核心都會忽略它。

4

gamma - {'scale'、'auto'} 或 float,

它是核心“rbf”、“poly”和“sigmoid”的核心係數。

5

可選預設值 - = 'scale'

如果您選擇預設值,即 gamma = 'scale',則 SVC 使用的 gamma 值為 1/(𝑛_𝑓𝑒𝑎𝑡𝑢𝑟𝑒𝑠∗𝑋.𝑣𝑎𝑟())。

另一方面,如果 gamma = 'auto',則它使用 1/𝑛_𝑓𝑒𝑎𝑡𝑢𝑟𝑒𝑠。

6

coef0 - float,可選,預設值 = 0.0

核心函式中的一個獨立項,僅在“poly”和“sigmoid”中有效。

7

tol - float,可選,預設值 = 1.e-3

此引數表示迭代的停止條件。

8

shrinking - Boolean,可選,預設值 = True

此引數表示我們是否要使用收縮啟發式方法。

9

verbose - Boolean,預設值:false

它啟用或停用詳細輸出。其預設值為 false。

10

probability - boolean,可選,預設值 = true

此引數啟用或停用機率估計。預設值為 false,但在呼叫 fit 之前必須啟用它。

11

max_iter - int,可選,預設值 = -1

顧名思義,它表示求解器中的最大迭代次數。值 -1 表示迭代次數沒有限制。

12

cache_size - float,可選

此引數將指定核心快取的大小。該值將以 MB(兆位元組)為單位。

13

random_state - int、RandomState 例項或 None,可選,預設值 = none

此引數表示用於在洗牌資料時生成的偽隨機數的種子。選項如下:

  • int - 在這種情況下,random_state 是隨機數生成器使用的種子。

  • RandomState 例項 - 在這種情況下,random_state 是隨機數生成器。

  • None - 在這種情況下,隨機數生成器是 np.random 使用的 RandonState 例項。

14

class_weight - {dict、'balanced'},可選

此引數將類 j 的引數 C 設定為 𝑐𝑙𝑎𝑠𝑠_𝑤𝑒𝑖𝑔ℎ𝑡[𝑗]∗𝐶 用於 SVC。如果我們使用預設選項,則意味著所有類都應該具有權重 1。另一方面,如果您選擇class_weight:balanced,它將使用 y 的值來自動調整權重。

15

decision_function_shape - 'ovo'、'ovr',預設值 = 'ovr'

此引數將決定演算法是否返回形狀為所有其他分類器的'ovr'(一對多)決策函式,或 libsvm 的原始ovo(一對一)決策函式。

16

break_ties - boolean,可選,預設值 = false

True - predict 將根據 decision_function 的置信度值打破平局

False - predict 將返回平局類中的第一個類。

屬性

下表包含**sklearn.svm.SVC** 類使用的屬性:

序號 屬性及描述
1

support_ - 類似陣列,形狀 = [n_SV]

它返回支援向量的索引。

2

support_vectors_ - 類似陣列,形狀 = [n_SV, n_features]

它返回支援向量。

3

n_support_ - 類似陣列,dtype=int32,形狀 = [n_class]

它表示每個類的支援向量數量。

4

dual_coef_ - 陣列,形狀 = [n_class-1,n_SV]

這些是決策函式中支援向量的係數。

5

coef_ - 陣列,形狀 = [n_class * (n_class-1)/2, n_features]

此屬性僅在使用線性核心時可用,它提供了分配給特徵的權重。

6

intercept_ - 陣列,形狀 = [n_class * (n_class-1)/2]

它表示決策函式中的獨立項(常數)。

7

fit_status_ - int

如果正確擬合,則輸出為 0。如果擬合不正確,則輸出為 1。

8

classes_ - 形狀為 [n_classes] 的陣列

它給出類的標籤。

實現示例

與其他分類器一樣,SVC 也必須使用以下兩個陣列進行擬合:

  • 包含訓練樣本的陣列X。其大小為 [n_samples, n_features]。

  • 包含訓練樣本的目標值,即類標籤的陣列Y。其大小為 [n_samples]。

以下 Python 指令碼使用sklearn.svm.SVC 類:

import numpy as np
X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
y = np.array([1, 1, 2, 2])
from sklearn.svm import SVC
SVCClf = SVC(kernel = 'linear',gamma = 'scale', shrinking = False,)
SVCClf.fit(X, y)

輸出

SVC(C = 1.0, cache_size = 200, class_weight = None, coef0 = 0.0,
   decision_function_shape = 'ovr', degree = 3, gamma = 'scale', kernel = 'linear',
   max_iter = -1, probability = False, random_state = None, shrinking = False,
   tol = 0.001, verbose = False)

示例

現在,一旦擬合,我們就可以藉助以下 Python 指令碼獲取權重向量:

SVCClf.coef_

輸出

array([[0.5, 0.5]])

示例

類似地,我們可以獲取其他屬性的值,如下所示:

SVCClf.predict([[-0.5,-0.8]])

輸出

array([1])

示例

SVCClf.n_support_

輸出

array([1, 1])

示例

SVCClf.support_vectors_

輸出

array(
   [
      [-1., -1.],
      [ 1., 1.]
   ]
)

示例

SVCClf.support_

輸出

array([0, 2])

示例

SVCClf.intercept_

輸出

array([-0.])

示例

SVCClf.fit_status_

輸出

0

NuSVC

NuSVC 是 Nu 支援向量分類。它是 Scikit-learn 提供的另一個可以執行多類分類的類。它類似於 SVC,但 NuSVC 接受略微不同的引數集。與 SVC 不同的引數如下:

  • nu - float,可選,預設值 = 0.5

它表示訓練誤差分數的上限和支援向量分數的下限。其值應在 (o,1] 的區間內。

其餘引數和屬性與 SVC 相同。

實現示例

我們也可以使用sklearn.svm.NuSVC 類實現相同的示例。

import numpy as np
X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
y = np.array([1, 1, 2, 2])
from sklearn.svm import NuSVC
NuSVCClf = NuSVC(kernel = 'linear',gamma = 'scale', shrinking = False,)
NuSVCClf.fit(X, y)

輸出

NuSVC(cache_size = 200, class_weight = None, coef0 = 0.0,
   decision_function_shape = 'ovr', degree = 3, gamma = 'scale', kernel = 'linear',
   max_iter = -1, nu = 0.5, probability = False, random_state = None,
   shrinking = False, tol = 0.001, verbose = False)

我們可以像在 SVC 中一樣獲取其餘屬性的輸出。

LinearSVC

它是線性支援向量分類。它類似於具有 kernel = 'linear' 的 SVC。它們之間的區別在於LinearSVC 是根據 liblinear 實現的,而 SVC 是在libsvm 中實現的。這就是LinearSVC 在懲罰和損失函式的選擇方面具有更大靈活性的原因。它還可以更好地擴充套件到大量樣本。

如果我們談論它的引數和屬性,那麼它不支援'kernel',因為它被假定為線性,並且它也缺少一些屬性,例如support_、support_vectors_、n_support_、fit_status_dual_coef_

但是,它支援penaltyloss 引數,如下所示:

  • penalty - string,L1 或 L2(預設值 = 'L2')

    此引數用於指定懲罰(正則化)中使用的範數(L1 或 L2)。

  • loss - string,hinge、squared_hinge(預設值 = squared_hinge)

    它表示損失函式,其中“hinge”是標準 SVM 損失,“squared_hinge”是 hinge 損失的平方。

實現示例

以下 Python 指令碼使用sklearn.svm.LinearSVC 類:

from sklearn.svm import LinearSVC
from sklearn.datasets import make_classification
X, y = make_classification(n_features = 4, random_state = 0)
LSVCClf = LinearSVC(dual = False, random_state = 0, penalty = 'l1',tol = 1e-5)
LSVCClf.fit(X, y)

輸出

LinearSVC(C = 1.0, class_weight = None, dual = False, fit_intercept = True,
   intercept_scaling = 1, loss = 'squared_hinge', max_iter = 1000,
   multi_class = 'ovr', penalty = 'l1', random_state = 0, tol = 1e-05, verbose = 0)

示例

現在,一旦擬合,模型就可以預測新值,如下所示:

LSVCClf.predict([[0,0,0,0]])

輸出

[1]

示例

對於上述示例,我們可以藉助以下 Python 指令碼獲取權重向量:

LSVCClf.coef_

輸出

[[0. 0. 0.91214955 0.22630686]]

示例

類似地,我們可以藉助以下 Python 指令碼獲取截距的值:

LSVCClf.intercept_

輸出

[0.26860518]

SVM 迴歸

如前所述,SVM 用於分類和迴歸問題。Scikit-learn 的支援向量分類 (SVC) 方法也可以擴充套件到解決迴歸問題。該擴充套件方法稱為支援向量迴歸 (SVR)。

SVM 和 SVR 之間的基本相似性

SVC 建立的模型僅依賴於訓練資料的一個子集。為什麼?因為構建模型的成本函式不關心位於間隔之外的訓練資料點。

而 SVR(支援向量迴歸)生成的模型也僅依賴於訓練資料的一個子集。為什麼?因為構建模型的成本函式會忽略任何靠近模型預測的訓練資料點。

Scikit-learn 提供了三個類,即**SVR、NuSVR 和 LinearSVR**,作為 SVR 的三種不同實現。

SVR

它是 Epsilon 支援向量迴歸,其實現基於**libsvm**。與SVC 相反,模型中有兩個自由引數,即'C''epsilon'

  • epsilon - float,可選,預設值 = 0.1

它表示 epsilon-SVR 模型中的 epsilon,並指定 epsilon 管,在該管內,在訓練損失函式中,對預測值與實際值之間的距離在 epsilon 內的點不關聯任何懲罰。

其餘引數和屬性與我們在SVC 中使用的類似。

實現示例

以下 Python 指令碼使用sklearn.svm.SVR 類:

from sklearn import svm
X = [[1, 1], [2, 2]]
y = [1, 2]
SVRReg = svm.SVR(kernel = ’linear’, gamma = ’auto’)
SVRReg.fit(X, y)

輸出

SVR(C = 1.0, cache_size = 200, coef0 = 0.0, degree = 3, epsilon = 0.1, gamma = 'auto',
   kernel = 'linear', max_iter = -1, shrinking = True, tol = 0.001, verbose = False)

示例

現在,一旦擬合,我們就可以藉助以下 Python 指令碼獲取權重向量:

SVRReg.coef_

輸出

array([[0.4, 0.4]])

示例

類似地,我們可以獲取其他屬性的值,如下所示:

SVRReg.predict([[1,1]])

輸出

array([1.1])

類似地,我們也可以獲取其他屬性的值。

NuSVR

NuSVR 是 Nu 支援向量迴歸。它類似於 NuSVC,但 NuSVR 使用引數nu來控制支援向量的數量。此外,與 NuSVC 中nu替換 C 引數不同,這裡它替換了epsilon

實現示例

以下 Python 指令碼使用sklearn.svm.SVR 類:

from sklearn.svm import NuSVR
import numpy as np
n_samples, n_features = 20, 15
np.random.seed(0)
y = np.random.randn(n_samples)
X = np.random.randn(n_samples, n_features)
NuSVRReg = NuSVR(kernel = 'linear', gamma = 'auto',C = 1.0, nu = 0.1)^M
NuSVRReg.fit(X, y)

輸出

NuSVR(C = 1.0, cache_size = 200, coef0 = 0.0, degree = 3, gamma = 'auto',
   kernel = 'linear', max_iter = -1, nu = 0.1, shrinking = True, tol = 0.001,
   verbose = False)

示例

現在,一旦擬合,我們就可以藉助以下 Python 指令碼獲取權重向量:

NuSVRReg.coef_

輸出

array(
   [
      [-0.14904483, 0.04596145, 0.22605216, -0.08125403, 0.06564533,
      0.01104285, 0.04068767, 0.2918337 , -0.13473211, 0.36006765,
      -0.2185713 , -0.31836476, -0.03048429, 0.16102126, -0.29317051]
   ]
)

類似地,我們也可以獲取其他屬性的值。

LinearSVR

它是線性支援向量迴歸。它類似於具有 kernel = 'linear' 的 SVR。它們之間的區別在於LinearSVR是用liblinear實現的,而 SVC是用libsvm實現的。這就是LinearSVR在懲罰和損失函式的選擇方面具有更多靈活性的原因。它也更適合於大量樣本。

如果我們談論它的引數和屬性,那麼它不支援'kernel',因為它被假定為線性,並且它也缺少一些屬性,例如support_、support_vectors_、n_support_、fit_status_dual_coef_

但是,它支援以下'loss'引數:

  • loss - 字串,可選,預設值 = 'epsilon_insensitive'

它表示損失函式,其中 epsilon_insensitive 損失是 L1 損失,而平方 epsilon_insensitive 損失是 L2 損失。

實現示例

以下 Python 指令碼使用sklearn.svm.LinearSVR類:

from sklearn.svm import LinearSVR
from sklearn.datasets import make_regression
X, y = make_regression(n_features = 4, random_state = 0)
LSVRReg = LinearSVR(dual = False, random_state = 0,
loss = 'squared_epsilon_insensitive',tol = 1e-5)
LSVRReg.fit(X, y)

輸出

LinearSVR(
   C=1.0, dual=False, epsilon=0.0, fit_intercept=True,
   intercept_scaling=1.0, loss='squared_epsilon_insensitive',
   max_iter=1000, random_state=0, tol=1e-05, verbose=0
)

示例

現在,一旦擬合,模型就可以預測新值,如下所示:

LSRReg.predict([[0,0,0,0]])

輸出

array([-0.01041416])

示例

對於上述示例,我們可以藉助以下 Python 指令碼獲取權重向量:

LSRReg.coef_

輸出

array([20.47354746, 34.08619401, 67.23189022, 87.47017787])

示例

類似地,我們可以藉助以下 Python 指令碼獲取截距的值:

LSRReg.intercept_

輸出

array([-0.01041416])
廣告