给定训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . ( x N , y N ) } T=\{(x_1, y_1),(x_2,y_2),...(x_N,y_N)\} T={(x1,y1),(x2,y2),...(xN,yN)}和超平面 ( w , b ) (w,b) (w,b),若用SVM求解需要首先确定 T T T可由超平面 ( w , b ) (w,b) (w,b)线性可分,如果非线性可分,需要先选择核函数做变换,使得变换后的训练集由超平面线性可分。
支持向量到超平面的距离为所有训练集到超平面的距离的最小值
γ = min i = 1 , 2 , . . . N γ i \gamma=\min\limits_{ i=1,2,...N}\quad \gamma_i γ=i=1,2,...Nminγi,
支持向量机做的是最大化 γ \gamma γ,即
max w , b γ \max\limits_{w,b} \quad \gamma w,bmaxγ
s . t . y i ( w ∣ ∣ w ∣ ∣ ⋅ x i + b ∣ ∣ w ∣ ∣ ) ≥ γ , i = 1 , 2 , . . . , N s.t.\quad y_i(\frac{w}{||w||}\cdot x_i+\frac{b}{||w||})\ge \gamma,\quad i=1,2,...,N s.t.yi(∣∣w∣∣w⋅xi+∣∣w∣∣b)≥γ,i=1,2,...,N
经过化简得到线性可分支持向量机学习的最优化问题如下:
min w , b 1 2 ∣ ∣ w ∣ ∣ 2 \min\limits_{w,b} \quad \frac{1}{2}||w||^2 w,bmin21∣∣w∣∣2
s . t . y i ( w ⋅ x i + b ) − 1 ≥ 0 , i = 1 , 2 , . . . , N s.t.\quad y_i(w\cdot x_i+b)-1\ge 0,\quad i=1,2,...,N s.t.yi(w⋅xi+b)−1≥0,i=1,2,...,N
这是含有不等式约束的凸优化问题,因此采用拉格朗乘子法求解。
经过化简可得该对偶问题为:
max α ∑ i = 1 m α i − 1 2 ∑ i = 1 m ∑ j = 1 m α i α j y i y j x i T x j \max\limits_\alpha\sum\limits_{i=1}^m\alpha_i-\frac{1}{2}\sum\limits_{i=1}^m\sum\limits_{j=1}^m\alpha_i\alpha_jy_iy_j x_i^Tx_j αmaxi=1∑mαi−21i=1∑mj=1∑mαiαjyiyjxiTxj
s . t . ∑ i = 1 m α i y i = 0 s.t.\sum\limits_{i=1}^m\alpha_iy_i=0 s.t.i=1∑mαiyi=0
α i ≥ 0 , i = 1 , 2 , . . . , m \quad\quad\alpha_i\ge0,i=1,2,...,m αi≥0,i=1,2,...,m
注意到 x i T x j x_i^Tx_j xiTxj是两个向量的乘积,这里可以引入核函数的概念,假如映射到另一个空间,映射函数为 ϕ \phi ϕ,在这里不需要知道 ϕ \phi ϕ,只需要知道 ϕ ( x i T ) ⋅ ϕ ( x j ) \phi(x_i^T)\cdot\phi(x_j) ϕ(xiT)⋅ϕ(xj),就可以求解,这是因为,获得内积比获得映射更容易。
由于需要满足不等式约束,因此对偶问题需要满足KKT条件:
α i ≥ 0 \alpha_i\ge0 αi≥0
y i f ( x i ) − 1 ≥ 0 y_if(x_i)-1\ge0 yif(xi)−1≥0
α i ( y i f ( x i ) − 1 ) = 0 \alpha_i(y_if(x_i)-1)=0 αi(yif(xi)−1)=0
了解公式推导,对于模型调优、参数调优有帮助。
from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from sklearn.model_selection import learning_curve
import numpy as np
iris = load_iris()
iris_X = iris.data #x有4个属性,共有600个样本点
iris_y = iris.target #y的取值有3个,分别是0,1,2
clf = SVC()
X_train, X_test, y_train, y_test = train_test_split(iris_X, iris_y, test_size=0.3)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
# print(clf.predict(X_test))
# print(y_test)
X_train, X_test, y_train, y_test = train_test_split(iris_X, iris_y, test_size=0.0)
train_sizes, train_loss, test_loss = learning_curve( clf, X_train, y_train, cv=10,
train_sizes=[0.1, 0.25, 0.5, 0.75, 1])
train_loss_mean = 1-np.mean(train_loss, axis=1)
test_loss_mean = 1-np.mean(test_loss, axis=1)
plt.plot(train_sizes, train_loss_mean, 'o-', color="r",
label="Training")
plt.plot(train_sizes, test_loss_mean, 'o-', color="g",
label="Cross-validation")
plt.xlabel("Training examples")
plt.ylabel("Loss")
plt.legend(loc="best")
plt.show()
sklearn中SVM用于分类时,叫SVC(Classification);那用于回归估计就叫SVR(Regression)了,名字起得也是棒棒的!
模型参数调整是最为重要的环节,输出模型参数:
from sklearn.svm import SVC
clf = SVC()
clf
输出结果:
sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True,
probability=False, tol=0.001, cache_size=200, class_weight=None,
verbose=False, max_iter=-1, decision_function_shape='ovr',
random_state=None)
其中kernel的选项有如下几项:
– linear:线性核函数
– poly:多项式核函数
–rbf:径像核函数/高斯核
–sigmod:sigmod核函数
–precomputed:核矩阵,该矩阵表示自己事先计算好的,输入后算法内部将使用你提供的矩阵进行计算1
https://www.jianshu.com/p/a9f9954355b3?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation ↩︎