# 1.4. 支持向量機
校驗者:
[@維](https://github.com/apachecn/scikit-learn-doc-zh)
[@子浪](https://github.com/apachecn/scikit-learn-doc-zh)
[@小瑤](https://github.com/apachecn/scikit-learn-doc-zh)
翻譯者:
[@Damon](https://github.com/apachecn/scikit-learn-doc-zh)
[@Leon晉](https://github.com/apachecn/scikit-learn-doc-zh)
**支持向量機 (SVMs)** 可用于以下監督學習算法 [分類](#svm-classification), [回歸](#svm-regression) and [異常檢測](#svm-outlier-detection).
支持向量機的優勢在于:
> - 在高維空間中非常高效.
> - 即使在數據維度比樣本數量大的情況下仍然有效.
> - 在決策函數(稱為支持向量)中使用訓練集的子集,因此它也是高效利用內存的.
> - 通用性: 不同的核函數 [核函數](#svm-kernels) 與特定的決策函數一一對應.常見的 kernel 已
>
> 經提供,也可以指定定制的內核.
支持向量機的缺點包括:
> - 如果特征數量比樣本數量大得多,在選擇核函數 [核函數](#svm-kernels) 時要避免過擬合,
>
> 而且正則化項是非常重要的.
>
> - 支持向量機不直接提供概率估計,這些都是使用昂貴的五次交叉驗算計算的. (詳情見 [Scores and probabilities](#scores-probabilities), 在下文中).
在 scikit-learn 中,支持向量機提供 dense(`numpy.ndarray` ,可以通過 `numpy.asarray` 進行轉換) 和 sparse (任何 `scipy.sparse`) 樣例向量作為輸出.然而,要使用支持向量機來對 sparse 數據作預測,它必須已經擬合這樣的數據.使用 C 代碼的 `numpy.ndarray` (dense) 或者帶有 `dtype=float64` 的 `scipy.sparse.csr_matrix` (sparse) 來優化性能.
## 1.4.1. 分類
[`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC"), [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC") 和 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 能在數據集中實現多元分類.
[](../auto_examples/svm/plot_iris.html)
[`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC") 和 [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC") 是相似的方法, 但是接受稍許不同的參數設置并且有不同的數學方程(在這部分看 [數學公式](#svm-mathematical-formulation)). 另一方面, [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 是另一個實現線性核函數的支持向量分類. 記住 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 不接受關鍵詞 `kernel`, 因為它被假設為線性的. 它也缺少一些 [`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC") 和 [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC") 的成員(members) 比如 `support_` .
和其他分類器一樣, [`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC"), [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC") 和 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 將兩個數組作為輸入: `[n_samples, n_features]` 大小的數組 X 作為訓練樣本, `[n_samples]` 大小的數組 y 作為類別標簽(字符串或者整數):
```
>>> from sklearn import svm
>>> X = [[0, 0], [1, 1]]
>>> y = [0, 1]
>>> clf = svm.SVC()
>>> clf.fit(X, y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
```
在擬合后, 這個模型可以用來預測新的值:
```
>>> clf.predict([[2., 2.]])
array([1])
```
SVMs 決策函數取決于訓練集的一些子集, 稱作支持向量. 這些支持向量的部分特性可以在 `support_vectors_`, `support_` 和 `n_support` 找到:
```
>>> # 獲得支持向量
>>> clf.support_vectors_
array([[ 0., 0.],
[ 1., 1.]])
>>> # 獲得支持向量的索引get indices of support vectors
>>> clf.support_
array([0, 1]...)
>>> # 為每一個類別獲得支持向量的數量
>>> clf.n_support_
array([1, 1]...)
```
### 1.4.1.1. 多元分類
[`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC") 和 [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC") 為多元分類實現了 “one-against-one” 的方法 (Knerr et al., 1990) 如果 `n_class` 是類別的數量, 那么 `n_class * (n_class - 1) / 2` 分類器被重構, 而且每一個從兩個類別中訓練數據. 為了給其他分類器提供一致的交互, `decision_function_shape` 選項允許聚合 “one-against-one” 分類器的結果成 `(n_samples, n_classes)` 的大小到決策函數:
```
>>> X = [[0], [1], [2], [3]]
>>> Y = [0, 1, 2, 3]
>>> clf = svm.SVC(decision_function_shape='ovo')
>>> clf.fit(X, Y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovo', degree=3, gamma='auto', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
>>> dec = clf.decision_function([[1]])
>>> dec.shape[1] # 4 classes: 4*3/2 = 6
6
>>> clf.decision_function_shape = "ovr"
>>> dec = clf.decision_function([[1]])
>>> dec.shape[1] # 4 classes
4
```
另一方面, [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 實現 “one-vs-the-rest” 多類別策略, 從而訓練 n 類別的模型. 如果只有兩類, 只訓練一個模型.:
```
>>> lin_clf = svm.LinearSVC()
>>> lin_clf.fit(X, Y)
LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
intercept_scaling=1, loss='squared_hinge', max_iter=1000,
multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
verbose=0)
>>> dec = lin_clf.decision_function([[1]])
>>> dec.shape[1]
4
```
參見 [數學公式](#svm-mathematical-formulation) 查看決策函數的完整描述.
記住 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 也實現了可選擇的多類別策略, 通過使用選項 `multi_class='crammer_singer'`, 所謂的多元 SVM 由 Crammer 和 Singer 明確表達. 這個方法是一致的, 對于 one-vs-rest 是不正確的. 實際上, one-vs-rest 分類通常受到青睞, 因為結果大多數是相似的, 但是運行時間卻顯著減少.
對于 “one-vs-rest” [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC"), 屬性 `coef_` 和 `intercept_` 分別具有 `[n_class, n_features]` 和 `[n_class]` 尺寸. 系數的每一行符合 `n_class` 的許多 one-vs-rest 分類器之一, 并且就以這一類的順序與攔截器(intercepts)相似.
至于 one-vs-one [`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC"), 屬性特征的布局(layout)有少多些復雜. 考慮到有一種線性核函數, `coef_` 和 `intercept_` 的布局(layout)與上文描述成 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 相似, 除了 `coef_` 的形狀 `[n_class * (n_class - 1) / 2, n_features]`, 與許多二元的分類器相似. 0到n的類別順序是 “0 vs 1”, “0 vs 2” , … “0 vs n”, “1 vs 2”, “1 vs 3”, “1 vs n”, … “n-1 vs n”.
`dual_coef_` 的 shape 是 `[n_class-1, n_SV]`, 這個結構有些難以理解. 對應于支持向量的列與 `n_class * (n_class - 1) / 2` “one-vs-one” 分類器相關. 每一個支持向量用于 `n_class - 1` 分類器中.對于這些分類器,每一行的 `n_class - 1`條目對應于對偶系數(dual coefficients).
通過這個例子更容易說明:
考慮一個三類的問題,類0有三個支持向量  而類 1 和 2 分別有 如下兩個支持向量  and .對于每個支持 向量 , 有兩個對偶系數.在類別  和  中, 我們將支持向量的系數記錄為 那么 `dual_coef_` 可以表示為:
Coefficients for SVs of class 0Coefficients for SVs of class 1Coefficients for SVs of class 2
### 1.4.1.2. 得分和概率
[`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC") 方法的 `decision_function` 給每一個樣例每一個類別分值(scores)(或者在一個二元類中每一個樣例一個分值). 當構造器(constructor)選項 `probability` 設置為 `True` 的時候, 類成員可能性評估開啟.(來自 `predict_proba` 和 `predict_log_proba` 方法) 在二元分類中,概率使用 Platt scaling 進行標準化: 在 SVM 分數上的邏輯回歸,在訓練集上用額外的交叉驗證來擬合.在多類情況下,這可以擴展為 per Wu et al.(2004)
不用說,對于大數據集來說,在 Platt scaling 中進行交叉驗證是一項昂貴的操作. 另外,可能性預測可能與 scores 不一致,因為 scores 的 “argmax” 可能不是可能性的 argmax. (例如,在二元分類中,一個樣本可能被標記為一個有可能性的類 `predict` <? according to `predict_proba`.) Platt 的方法也有理論問題. 如果 confidence scores 必要,但是這些沒必要是可能性, 那么建議設置 `probability=False` 并使用 `decision_function` 而不是 `predict_proba`.
參考:
- Wu, Lin and Weng, [`"Probability estimates for multi-class classification by pairwise coupling(成對耦合的多類分類的概率估計)"<http://www.csie.ntu.edu.tw/~cjlin/papers/svmprob/svmprob.pdf>`\_](#id13), JMLR 5:975-1005, 2004.
- Platt [`"Probabilistic outputs for SVMs and comparisons to regularized likelihood methods(SVMs 的概率輸出和與規則化似然方法的比較)"<http://www.cs.colorado.edu/~mozer/Teaching/syllabi/6622/papers/Platt1999.pdf>`\_](#id15) .
### 1.4.1.3. 非均衡問題
這個問題期望給予某一類或某個別樣例能使用的關鍵詞 `class_weight` 和 `sample_weight` 提高權重(importance).
[`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC") (而不是 [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC")) 在 `fit` 方法中生成了一個關鍵詞 `class_weight`. 它是形如 `{class_label : value}` 的字典, value 是浮點數大于 0 的值, 把類 `class_label` 的參數 `C` 設置為 `C * value`.
[](../auto_examples/svm/plot_separating_hyperplane_unbalanced.html)
[`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC"), [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC"), [`SVR`](generated/sklearn.svm.SVR.html#sklearn.svm.SVR "sklearn.svm.SVR"), [`NuSVR`](generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR "sklearn.svm.NuSVR") 和 [`OneClassSVM`](generated/sklearn.svm.OneClassSVM.html#sklearn.svm.OneClassSVM "sklearn.svm.OneClassSVM") 在 `fit` 方法中通過關鍵詞 `sample_weight` 為單一樣例實現權重weights.與 `class_weight` 相似, 這些把第i個樣例的參數 `C` 換成 `C * sample_weight[i]`.
[](../auto_examples/svm/plot_weighted_samples.html)
例子:
- [Plot different SVM classifiers in the iris dataset](../auto_examples/svm/plot_iris.html#sphx-glr-auto-examples-svm-plot-iris-py),
- [SVM: Maximum margin separating hyperplane](../auto_examples/svm/plot_separating_hyperplane.html#sphx-glr-auto-examples-svm-plot-separating-hyperplane-py),
- [SVM: Separating hyperplane for unbalanced classes](../auto_examples/svm/plot_separating_hyperplane_unbalanced.html#sphx-glr-auto-examples-svm-plot-separating-hyperplane-unbalanced-py)
- [SVM-Anova: SVM with univariate feature selection](../auto_examples/svm/plot_svm_anova.html#sphx-glr-auto-examples-svm-plot-svm-anova-py),
- [Non-linear SVM](../auto_examples/svm/plot_svm_nonlinear.html#sphx-glr-auto-examples-svm-plot-svm-nonlinear-py)
- [SVM: Weighted samples](../auto_examples/svm/plot_weighted_samples.html#sphx-glr-auto-examples-svm-plot-weighted-samples-py),
## 1.4.2. 回歸
支持向量分類的方法可以被擴展用作解決回歸問題. 這個方法被稱作支持向量回歸.
支持向量分類生成的模型(如前描述)只依賴于訓練集的子集,因為構建模型的 cost function 不在乎邊緣之外的訓練點. 類似的,支持向量回歸生成的模型只依賴于訓練集的子集, 因為構建模型的 cost function 忽略任何接近于模型預測的訓練數據.
支持向量分類有三種不同的實現形式: [`SVR`](generated/sklearn.svm.SVR.html#sklearn.svm.SVR "sklearn.svm.SVR"), [`NuSVR`](generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR "sklearn.svm.NuSVR") 和 [`LinearSVR`](generated/sklearn.svm.LinearSVR.html#sklearn.svm.LinearSVR "sklearn.svm.LinearSVR"). 在只考慮線性核的情況下, [`LinearSVR`](generated/sklearn.svm.LinearSVR.html#sklearn.svm.LinearSVR "sklearn.svm.LinearSVR") 比 [`SVR`](generated/sklearn.svm.SVR.html#sklearn.svm.SVR "sklearn.svm.SVR") 提供一個更快的實現形式, 然而比起 [`SVR`](generated/sklearn.svm.SVR.html#sklearn.svm.SVR "sklearn.svm.SVR") 和 [`LinearSVR`](generated/sklearn.svm.LinearSVR.html#sklearn.svm.LinearSVR "sklearn.svm.LinearSVR"), [`NuSVR`](generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR "sklearn.svm.NuSVR") 實現一個稍微不同的構思(formulation).細節參見 [實現細節](#svm-implementation-details).
與分類的類別一樣, fit方法會調用參數向量 X, y, 只在 y 是浮點數而不是整數型.:
```
>>> from sklearn import svm
>>> X = [[0, 0], [2, 2]]
>>> y = [0.5, 2.5]
>>> clf = svm.SVR()
>>> clf.fit(X, y)
SVR(C=1.0, cache_size=200, coef0=0.0, degree=3, epsilon=0.1, gamma='auto',
kernel='rbf', max_iter=-1, shrinking=True, tol=0.001, verbose=False)
>>> clf.predict([[1, 1]])
array([ 1.5])
```
樣例:
- [Support Vector Regression (SVR) using linear and non-linear kernels](../auto_examples/svm/plot_svm_regression.html#sphx-glr-auto-examples-svm-plot-svm-regression-py)
## 1.4.3. 密度估計, 異常(novelty)檢測
但類別的 SVM 用于異常檢測, 即給予一個樣例集, 它會檢測這個樣例集的 soft boundary 以便給新的數據點分類, 看它是否屬于這個樣例集. 生成的類稱作 [`OneClassSVM`](generated/sklearn.svm.OneClassSVM.html#sklearn.svm.OneClassSVM "sklearn.svm.OneClassSVM").
這種情況下, 因為它屬于非監督學習的一類, 沒有類標簽, fit 方法只會考慮輸入數組X.
在章節 [新奇和異常值檢測](outlier_detection.html#outlier-detection) 查看這個應用的更多細節.
[](../auto_examples/svm/plot_oneclass.html)
示例:
- [One-class SVM with non-linear kernel (RBF)](../auto_examples/svm/plot_oneclass.html#sphx-glr-auto-examples-svm-plot-oneclass-py)
- [Species distribution modeling](../auto_examples/applications/plot_species_distribution_modeling.html#sphx-glr-auto-examples-applications-plot-species-distribution-modeling-py)
## 1.4.4. 復雜度
支持向量機是個強大的工具,不過它的計算和存儲空間要求也會隨著要訓練向量的數目增加而快速增加。 SVM的核心是一個二次規劃問題(Quadratic Programming, QP),是將支持向量和訓練數據的其余部分分離開來。 在實踐中(數據集相關),會根據 [libsvm](http://www.csie.ntu.edu.tw/~cjlin/libsvm/) 的緩存有多效,在  和  之間基于 [libsvm](http://www.csie.ntu.edu.tw/~cjlin/libsvm/) 的縮放操作才會調用這個 QP 解析器。 如果數據是非常稀疏,那  就用樣本向量中非零特征的平均數量去替換。
另外請注意,在線性情況下,由 [liblinear](http://www.csie.ntu.edu.tw/~cjlin/liblinear/) 操作的 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 算法要比由它的 [libsvm](http://www.csie.ntu.edu.tw/~cjlin/libsvm/) 對應的 [`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC") 更為高效,并且它幾乎可以線性縮放到數百萬樣本或者特征。
## 1.4.5. 使用訣竅
> - **避免數據復制**: 對于 [`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC"), [`SVR`](generated/sklearn.svm.SVR.html#sklearn.svm.SVR "sklearn.svm.SVR"), [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC") 和 [`NuSVR`](generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR "sklearn.svm.NuSVR"), 如果數據是通過某些方法而不是用 C 有序的連續雙精度,那它先會調用底層的 C 命令再復制。 您可以通過檢查它的 `flags` 屬性,來確定給定的 numpy 數組是不是 C 連續的。
>
> 對于 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") (和 [`LogisticRegression`](generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression "sklearn.linear_model.LogisticRegression")) 的任何輸入,都會以 numpy 數組形式,被復制和轉換為 用 liblinear 內部稀疏數據去表達(雙精度浮點型 float 和非零部分的 int32 索引)。 如果您想要一個適合大規模的線性分類器,又不打算復制一個密集的 C-contiguous 雙精度 numpy 數組作為輸入, 那我們建議您去使用 [`SGDClassifier`](generated/sklearn.linear_model.SGDClassifier.html#sklearn.linear_model.SGDClassifier "sklearn.linear_model.SGDClassifier") 類作為替代。目標函數可以配置為和 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC")模型差不多相同的。
> - **內核的緩存大小**: 在大規模問題上,對于 [`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC"), [`SVR`](generated/sklearn.svm.SVR.html#sklearn.svm.SVR "sklearn.svm.SVR"), `nuSVC` 和 [`NuSVR`](generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR "sklearn.svm.NuSVR"), 內核緩存的大小會特別影響到運行時間。如果您有足夠可用的 RAM,不妨把它的 `緩存大小`設得比默認的 200(MB) 要高,例如為 500(MB) 或者 1000(MB)。
> - **懲罰系數C的設置**:在合理的情況下, `C` 的默認選擇為 `1` 。如果您有很多混雜的觀察數據, 您應該要去調小它。 `C` 越小,就能更好地去正規化估計。
> - 支持向量機算法本身不是用來擴大不變性,所以 **我們強烈建議您去擴大數據量**. 舉個例子,對于輸入向量 X, 規整它的每個數值范圍為 \[0, 1\] 或 \[-1, +1\] ,或者標準化它的為均值為0方差為1的數據分布。請注意, 相同的縮放標準必須要應用到所有的測試向量,從而獲得有意義的結果。 請參考章節 [預處理數據](preprocessing.html#preprocessing) ,那里會提供到更多關于縮放和規整。
> - 在 [`NuSVC`](generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC "sklearn.svm.NuSVC")/[`OneClassSVM`](generated/sklearn.svm.OneClassSVM.html#sklearn.svm.OneClassSVM "sklearn.svm.OneClassSVM")/[`NuSVR`](generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR "sklearn.svm.NuSVR") 內的參數 `nu` , 近似是訓練誤差和支持向量的比值。
> - 在 [`SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC"), ,如果分類器的數據不均衡(就是說,很多正例很少負例),設置 `class_weight='balanced'`與/或嘗試不同的懲罰系數 `C` 。
> - 在擬合模型時,底層 [`LinearSVC`](generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC "sklearn.svm.LinearSVC") 操作使用了隨機數生成器去選擇特征。 所以不要感到意外,對于相同的數據輸入,也會略有不同的輸出結果。如果這個發生了, 嘗試用更小的 tol 參數。
> - 使用由
> ```
> LinearSVC(loss='l2', penalty='l1',
> dual=False)
> ```
> 提供的 L1 懲罰去產生稀疏解,也就是說,特征權重的子集不同于零,這樣做有助于決策函數。 隨著增加 `C` 會產生一個更復雜的模型(要做更多的特征選擇)。可以使用 [`l1_min_c`](generated/sklearn.svm.l1_min_c.html#sklearn.svm.l1_min_c "sklearn.svm.l1_min_c") 去計算 `C` 的數值,去產生一個”null” 模型(所有的權重等于零)。
## 1.4.6. 核函數
*核函數* 可以是以下任何形式::
> - 線性: .
> - 多項式: .  是關鍵詞 `degree`,  指定 `coef0`。
> - rbf: .  是關鍵詞 `gamma`, 必須大于 0。
> - sigmoid (), 其中  指定 `coef0`。
初始化時,不同內核由不同的函數名調用:
```
>>> linear_svc = svm.SVC(kernel='linear')
>>> linear_svc.kernel
'linear'
>>> rbf_svc = svm.SVC(kernel='rbf')
>>> rbf_svc.kernel
'rbf'
```
### 1.4.6.1. 自定義核
您可以自定義自己的核,通過使用python函數作為內核或者通過預計算 Gram 矩陣。
自定義內核的分類器和別的分類器一樣,除了下面這幾點:
> - 空間 `support_vectors_` 現在不是空的, 只有支持向量的索引被存儲在 `support_`
> - 請把 `fit()` 模型中的第一個參數的引用(不是副本)存儲為將來的引用。 如果在 `fit()` 和 `predict()` 之間有數組發生改變,您將會碰到意料外的結果。
#### 1.4.6.1.1. 使用 python 函數作為內核
在構造時,您同樣可以通過一個函數傳遞到關鍵詞 `kernel` ,來使用您自己定義的內核。
您的內核必須要以兩個矩陣作為參數,大小分別是 `(n_samples_1, n_features)`, `(n_samples_2, n_features)`和返回一個內核矩陣,shape 是 `(n_samples_1, n_samples_2)`.
以下代碼定義一個線性核,和構造一個使用該內核的分類器例子:
```
>>> import numpy as np
>>> from sklearn import svm
>>> def my_kernel(X, Y):
... return np.dot(X, Y.T)
...
>>> clf = svm.SVC(kernel=my_kernel)
```
例子:
- [SVM with custom kernel](../auto_examples/svm/plot_custom_kernel.html#sphx-glr-auto-examples-svm-plot-custom-kernel-py).
#### 1.4.6.1.2. 使用 Gram 矩陣
在適應算法中,設置 `kernel='precomputed'` 和把 X 替換為 Gram 矩陣。 此時,必須要提供在 *所有* 訓練矢量和測試矢量中的內核值。
```
>>> import numpy as np
>>> from sklearn import svm
>>> X = np.array([[0, 0], [1, 1]])
>>> y = [0, 1]
>>> clf = svm.SVC(kernel='precomputed')
>>> # 線性內核計算
>>> gram = np.dot(X, X.T)
>>> clf.fit(gram, y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto',
kernel='precomputed', max_iter=-1, probability=False,
random_state=None, shrinking=True, tol=0.001, verbose=False)
>>> # 預測訓練樣本
>>> clf.predict(gram)
array([0, 1])
```
#### 1.4.6.1.3. RBF 內核參數
當用 *徑向基* (RBF) 內核去訓練 SVM,有兩個參數必須要去考慮: `C` 懲罰系數和 `gamma` 。參數 `C` , 通用在所有 SVM 內核,與決策表面的簡單性相抗衡,可以對訓練樣本的誤分類進行有價轉換。 較小的 `C` 會使決策表面更平滑,同時較高的 `C` 旨在正確地分類所有訓練樣本。 `Gamma` 定義了單一 訓練樣本能起到多大的影響。較大的 `gamma` 會更讓其他樣本受到影響。
選擇合適的 `C` 和 `gamma` ,對SVM的性能起到很關鍵的作用。建議一點是 使用 [`sklearn.model_selection.GridSearchCV`](generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV "sklearn.model_selection.GridSearchCV") 與 `C` 和 `gamma` 相隔 成倍差距從而選擇到好的數值。
例子:
- [RBF SVM parameters](../auto_examples/svm/plot_rbf_parameters.html#sphx-glr-auto-examples-svm-plot-rbf-parameters-py)
## 1.4.7. 數學公式
支持向量機在高維度或無窮維度空間中,構建一個超平面或者一系列的超平面,可以用于分類、回歸或者別的任務。 直觀地看,借助超平面去實現一個好的分割, 能在任意類別中使最為接近的訓練數據點具有最大的間隔距離(即所 謂的函數余量),這樣做是因為通常更大的余量能有更低的分類器泛化誤差。
[](http://sklearn.apachecn.org/cn/0.19.0/_images/sphx_glr_plot_separating_hyperplane_0011.png)
### 1.4.7.1. SVC
在兩類中,給定訓練向量 , i=1,…, n, 和一個向量 , SVC能解決 如下主要問題:

它的對偶是

其中  是所有的向量,  是上界, 是一個  由  個半正定矩陣, 而  ,其中  是內核。所以訓練向量是通過函數 ,間接反映到一個更高維度的(無窮的)空間。
決策函數是:

注意:
雖然這些SVM模型是從 [libsvm](http://www.csie.ntu.edu.tw/~cjlin/libsvm/) 和 [liblinear](http://www.csie.ntu.edu.tw/~cjlin/liblinear/) 中派生出來,使用了 `C` 作為調整參數,但是大多數的 攻擊使用了 `alpha`。兩個模型的正則化量之間的精確等價,取決于模型優化的準確目標函數。舉 個例子,當使用的估計器是 `sklearn.linear_model.Ridge` 做回歸時,他們之間的相關性是 。
這些參數能通過成員 `dual_coef_`、 `support_vectors_` 、 `intercept_` 去訪問,這些成員分別控制了輸出 、支持向量和無關項  :
參考文獻:
- [“Automatic Capacity Tuning of Very Large VC-dimension Classifiers”](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.17.7215), I. Guyon, B. Boser, V. Vapnik - Advances in neural information processing 1993.
- [“Support-vector networks”](http://link.springer.com/article/10.1007%2FBF00994018), C. Cortes, V. Vapnik - Machine Learning, 20, 273-297 (1995).
### 1.4.7.2. NuSVC
我們引入一個新的參數  來控制支持向量的數量和訓練誤差。參數 ![\nu \in (0, 1]](https://box.kancloud.cn/ca9bdc313d48716469bc55f8fbd0b168_68x19.jpg) 是訓練誤差分數的上限和支持向量分數的下限。
可以看出, -SVC 公式是 -SVC 的再參數化,所以數學上是等效的。
### 1.4.7.3. SVR
給定訓練向量 , i=1,…, n,向量 -SVR 能解決以下的主要問題:

它的對偶是

其中  是所有的向量,  是上界, 是一個  由  個半正定矩陣, 而  是內核。 所以訓練向量是通過函數 ,間接反映到一個更高維度的(無窮的)空間。
決策函數是:

這些參數能通過成員 `dual_coef_`、 `support_vectors_` 、 `intercept_` 去訪問,這些 成員分別控制了不同的 、支持向量和無關項 :
參考文獻:
- [“A Tutorial on Support Vector Regression”](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.114.4288), Alex J. Smola, Bernhard Sch?lkopf - Statistics and Computing archive Volume 14 Issue 3, August 2004, p. 199-222.
## 1.4.8. 實現細節
在底層里,我們使用 [libsvm](http://www.csie.ntu.edu.tw/~cjlin/libsvm/) 和 [liblinear](http://www.csie.ntu.edu.tw/~cjlin/liblinear/) 去處理所有的計算。這些庫都使用了 C 和 Cython 去包裝。
參考文獻:
有關實現的描述和使用算法的細節,請參考
> - [LIBSVM: A Library for Support Vector Machines](http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.pdf).
> - [LIBLINEAR – A Library for Large Linear Classification](http://www.csie.ntu.edu.tw/~cjlin/liblinear/).
- scikit-learn 0.19 中文文檔
- 用戶指南
- 1. 監督學習
- 1.1. 廣義線性模型
- 1.2. 線性和二次判別分析
- 1.3. 內核嶺回歸
- 1.4. 支持向量機
- 1.5. 隨機梯度下降
- 1.6. 最近鄰
- 1.7. 高斯過程
- 1.8. 交叉分解
- 1.9. 樸素貝葉斯
- 1.10. 決策樹
- 1.11. 集成方法
- 1.12. 多類和多標簽算法
- 1.13. 特征選擇
- 1.14. 半監督學習
- 1.15. 等式回歸
- 1.16. 概率校準
- 1.17. 神經網絡模型(有監督)
- 2. 無監督學習
- 2.1. 高斯混合模型
- 2.2. 流形學習
- 2.3. 聚類
- 2.4. 雙聚類
- 2.5. 分解成分中的信號(矩陣分解問題)
- 2.6. 協方差估計
- 2.7. 經驗協方差
- 2.8. 收斂協方差
- 2.9. 稀疏逆協方差
- 2.10. Robust 協方差估計
- 2.11. 新奇和異常值檢測
- 2.12. 密度估計
- 2.13. 神經網絡模型(無監督)
- 3. 模型選擇和評估
- 3.1. 交叉驗證:評估估算器的表現
- 3.2. 調整估計器的超參數
- 3.3. 模型評估: 量化預測的質量
- 3.4. 模型持久化
- 3.5. 驗證曲線: 繪制分數以評估模型
- 4. 數據集轉換
- 4.1. Pipeline(管道)和 FeatureUnion(特征聯合): 合并的評估器
- 4.2. 特征提取
- 4.3. 預處理數據
- 4.4. 無監督降維
- 4.5. 隨機投影
- 4.6. 內核近似
- 4.7. 成對的矩陣, 類別和核函數
- 4.8. 預測目標 (y) 的轉換
- 5. 數據集加載工具
- 6. 大規模計算的策略: 更大量的數據
- 7. 計算性能
- 教程
- 使用 scikit-learn 介紹機器學習
- 關于科學數據處理的統計學習教程
- 機器學習: scikit-learn 中的設置以及預估對象
- 監督學習:從高維觀察預測輸出變量
- 模型選擇:選擇估計量及其參數
- 無監督學習: 尋求數據表示
- 把它們放在一起
- 尋求幫助
- 處理文本數據
- 選擇正確的評估器(estimator)
- 外部資源,視頻和談話