%matplotlib inline
下面的例子展示了使用svm
去進行 scale 正則化參數javascript
若是咱們認爲損失函數是每一個樣本的單獨偏差,那麼數據擬合項,或每一個樣本的偏差之和,將隨着咱們添加更多的樣本而增長。可是,處罰部分不會增長。css
當使用cross validation
去設置正則化參數C
html
由於咱們的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 正則化項
假設咱們把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$
上式就爲:Hinge損失 + L2正則化。
導入數據和庫
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
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)
print(y_1)
# 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])
生成一個列表類型,以便以後的循環。列表中輸入四個參數:
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']
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()
print(grid_cs)
不是很理解這到底在幹什麼?L1 貌似處理稀疏數據有優點, L2:處理非稀疏數據。至於縮放C值的目的我也不知道是什麼?