SVM官方教程:SVCs的正則化參數

In [1]:
%matplotlib inline

SVCs的正則化參數

下面的例子展示了使用svm去進行 scale 正則化參數javascript

若是咱們認爲損失函數是每一個樣本的單獨偏差,那麼數據擬合項,或每一個樣本的偏差之和,將隨着咱們添加更多的樣本而增長。可是,處罰部分不會增長。css

當使用cross validation去設置正則化參數Chtml

由於咱們的loss function依賴於樣本的數量,因此樣本的數量會影響C的取值。 由此產生的問題是「咱們如何優化調整C以適應不一樣數量的訓練樣本?」html5

下面的圖用於說明在使用 $l1$ 懲罰和 $l2$ 懲罰的狀況下,爲了補償樣本數量的變化,縮放咱們的「C」所產生的效果。java

$l1-penalty\ case$node

l1的狀況下,理論認爲因爲l1的誤差,預測一致性(即在給定的假設條件下,估計值學習預測以及模型知道真實分佈)是不可能的。然而,它確實代表,在找到正確的非零參數集及其符號方面,模型一致性能夠經過縮放C1來實現。python

$l2-penalty\ case$jquery

理論說爲了得到預測連續性,隨着樣本量的增長,懲罰參數應該保持固定linux

仿真結果說明:android

下面兩個圖繪製了C做爲橫軸,相應的交叉驗證分數做爲y周,對於生成的數據集的幾個不一樣部分。

在 $l1$ 懲罰項,交叉驗證偏差與測試偏差相關,當根據樣本個數n去放縮C時,這點能夠在第一二張圖中能夠看出。

在 $l2$ 懲罰項,最好的結果來源於 C 值沒有放縮的案例。


最多見的帶懲罰項的SVM 公式:

$$\begin{array}{l}{\min \frac{1}{2}\|w\|^{2}+C \sum_{i=1}^{n} \xi(i)} \\ {\text { s.t. } y^{(i)}\left(w^{T} \Phi\left(x^{(i)}\right)+b\right) \geq 1-\xi(i), i=1,2 \ldots n}\end{array}$$

解釋:SVM 的最優化公式等價於 hinge損失 + L2 正則化項

  1. hinge 損失的含義:
$$ max\{0,1-m\} $$

image.png

  1. hinge 損失與SVM的聯繫

假設咱們把hinge損失的橫軸座標變量 m 看作離 SVM 中超平面的距離

當 $\ \hat{y}\cdot y >1 $時,表明分類正確,即損失爲0,當$\ \hat{y}\cdot y <1 $,把離超平面的距離,即 1 - $\hat{y}\cdot y $ 視爲損失量。

因此就有: $min\{ \xi\} \Longleftrightarrow min\{hinge損失\} \Longleftrightarrow min\{max\{1-\hat{y}\cdot y\}\}$

因此就有:$$\begin{array}{l}{\min \frac{1}{2}\|w\|^{2}+C \sum_{i=1}^{n} \xi(i)} \\ {\text { s.t. } y^{(i)}\left(w^{T} \Phi\left(x^{(i)}\right)+b\right) \geq 1-\xi(i), i=1,2 \ldots n}\end{array} \\ \Longrightarrow \min _{\omega, \gamma}\left[C \sum_{i=1}^{n} \max \left\{0,1-\left(\omega^{T} x_{i}+\gamma\right) y_{i}\right\}+\frac{1}{2}\|\omega\|_{2}^{2}\right]$$

再將正則化參數C除到右項中,命名爲 $\lambda$

$$\Longrightarrow \min _{\omega, \gamma}\left[ \sum_{i=1}^{n} \max \left\{0,1-\left(\omega^{T} x_{i}+\gamma\right) y_{i}\right\}+\lambda \|\omega\|_{2}^{2}\right] $$

上式就爲:Hinge損失 + L2正則化。

  1. 很是好的損失函數介紹博客:https://blog.csdn.net/u010976453/article/details/78488279

導入數據和庫

In [2]:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import LinearSVC
from sklearn.model_selection import GridSearchCV
from sklearn import datasets

# 交叉驗證庫
from sklearn.model_selection import ShuffleSplit

# 新學的庫

from sklearn.utils import check_random_state

MAKE_CLASSIFICATION(分類生成器):

n_features :特徵個數= n_informative() + n_redundant + n_repeated
n_informative:多信息特徵的個數
n_redundant:冗餘信息,informative特徵的隨機線性組合
n_repeated :重複信息,隨機提取n_informative和n_redundant 特徵
n_classes:分類類別
n_clusters_per_class :某一個類別是由幾個cluster構成的

參考博文:http://www.freesion.com/article/606117357/

$check\_random\_state()$ : Turn seed into a $np.random.RandomState$ instance

In [23]:
rnd = check_random_state(1)
# set up dataset
n_samples = 100
n_features = 300
# l1 data (only 5 informative features)
X_1, y_1 = datasets.make_classification(n_samples=n_samples,
                                        n_features=n_features, n_informative=5,
                                        random_state=1)
In [24]:
print(y_1)
[1 1 1 0 0 0 1 0 1 1 1 1 0 0 0 1 1 0 1 1 0 1 1 0 1 0 0 1 1 0 0 0 1 1 0 1 1
 1 0 1 1 0 1 0 1 1 0 0 1 0 1 0 1 0 1 0 0 1 1 1 0 1 0 0 1 0 1 1 0 0 0 0 1 0
 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 1 0 0 1 1 0 1 1 1 0 0]
In [30]:
# L2 數據:沒有稀疏,可是特徵更少
y_2 = np.sign(.5 - rnd.rand(n_samples))
X_2 = rnd.randn(n_samples, n_features // 5) + y_2[:, np.newaxis]
X_2 += 5 * rnd.randn(n_samples, n_features // 5)

print(y_2)
print(y_2.reshape(100,-1).all()==y_2[:, np.newaxis].all())
print(X_2.shape)
print(X_2[:5,:5])
[ 1. -1. -1.  1.  1. -1.  1.  1. -1.  1. -1.  1.  1. -1.  1.  1. -1.  1.
  1. -1.  1. -1. -1. -1. -1.  1. -1.  1.  1. -1.  1. -1.  1. -1.  1. -1.
 -1.  1.  1.  1.  1. -1.  1.  1. -1. -1.  1. -1.  1. -1.  1.  1.  1.  1.
 -1.  1. -1.  1.  1. -1.  1. -1. -1.  1. -1.  1.  1.  1.  1. -1.  1.  1.
  1.  1.  1.  1.  1. -1. -1.  1. -1.  1.  1.  1. -1.  1. -1.  1.  1. -1.
 -1.  1.  1. -1. -1. -1.  1.  1. -1.  1.]
True
(100, 60)
[[ 6.01232332  1.14532968 -8.5996665   8.04569999 -3.9950747 ]
 [-8.23881306 -8.82447483 -5.90777693  9.59317826 -4.68055683]
 [-2.74578891  6.7955197   5.93798556  9.08262617 -4.40408565]
 [-2.60992335 -0.78653401 -1.48344612  7.13938015  6.75872993]
 [-1.54692851  0.92916065  3.52381451  1.37473455  2.65960139]]

生成一個列表類型,以便以後的循環。列表中輸入四個參數:

  • 第一參數:LinearSVC模型
  • 第二參數:交叉驗證須要搜索C值的範圍
  • 第3、四參數:訓練的數據以及標籤
In [26]:
clf_sets = [(LinearSVC(penalty='l1', loss='squared_hinge', dual=False,
                       tol=1e-3),
             np.logspace(-2.3, -1.3, 10), X_1, y_1),
            (LinearSVC(penalty='l2', loss='squared_hinge', dual=True,
                       tol=1e-4),
             np.logspace(-4.5, -2, 10), X_2, y_2)]

colors = ['navy', 'cyan', 'darkorange']
In [22]:
lw = 2

for clf, cs, X, y in clf_sets:
    # set up the plot for each regressor
    fig, axes = plt.subplots(nrows=2, sharey=True, figsize=(9, 10))

    for k, train_size in enumerate(np.linspace(0.3, 0.7, 3)[::-1]):
        param_grid = dict(C=cs)
        # To get nice curve, we need a large number of iterations to
        # reduce the variance
        grid = GridSearchCV(clf, refit=False, param_grid=param_grid,
                            cv=ShuffleSplit(train_size=train_size,
                                            test_size=.3,
                                            n_splits=250, random_state=1))
        grid.fit(X, y)
        scores = grid.cv_results_['mean_test_score']

        scales = [(1, 'No scaling'),
                  ((n_samples * train_size), '1/n_samples'),
                  ]

        for ax, (scaler, name) in zip(axes, scales):
            ax.set_xlabel('C')
            ax.set_ylabel('CV Score')
            grid_cs = cs * float(scaler)  # scale the C's
            ax.semilogx(grid_cs, scores, label="fraction %.2f" %
                        train_size, color=colors[k], lw=lw)
            ax.set_title('scaling=%s, penalty=%s, loss=%s' %
                         (name, clf.penalty, clf.loss))

    plt.legend(loc="best")
plt.show()
In [31]:
print(grid_cs)
[0.00094868 0.00179845 0.00340939 0.0064633  0.01225272 0.02322791
 0.04403398 0.08347678 0.15824991 0.3       ]

不是很理解這到底在幹什麼?L1 貌似處理稀疏數據有優點, L2:處理非稀疏數據。至於縮放C值的目的我也不知道是什麼?

In [ ]:
相關文章
相關標籤/搜索