问题:高斯核在delta(方差)变大的情况下,整个模型容易overfitting还是underfitting?
看本文前半部分就明白了 ^_^
sklearn中svm.SVC()有比较重要的参数C和gamma,默认使用径向基核(kernel=‘rbf’)。
RBF的核函数: K ( x , z ) = e x p ( − γ ∥ x − z ∥ 2 ) , γ > 0 K(x,z)=exp(-\gamma\|x-z\|^2),\, \gamma>0 K(x,z)=exp(−γ∥x−z∥2),γ>0
高斯核的RBF时,核函数: K ( x , z ) = e x p ( − ∥ x − z ∥ 2 2 ⋅ δ 2 ) K(x,z)=exp(-\dfrac{\|x-z\|^2}{2\cdot \delta^2}) K(x,z)=exp(−2⋅δ2∥x−z∥2)
直觉上来看,RBF核函数的参数 γ \gamma γ(gamma),效果等同于 1 δ ′ \dfrac{1}{\delta'} δ′1,决定了数据映射到新的特征空间后的分布(正态分布)。
gamma较大时,相当于正态分布中的 δ \delta δ(方差)较小,映射出的高斯分布又高又瘦较为集中,那么单个样本对周围样本的影响力度大,范围窄,比较容易被选为支持向量,或者说整个模型的支持向量也会多,更容易过拟合。
反之,当gamma比较小时,单个样本对整个分类超平面的影响比较小,不容易被选择为支持向量,整个模型的支持向量较少,不容易过拟合。
scikit-learn中默认值是: 1 / (样本特征数*样本方差)
C是惩罚系数,即对误差的宽容度。C越高,说明越不能容忍出现误差,容易过拟合。C越小,容易欠拟合。不管是 SVC(分类)还是 SVR(回归),参数C都是为了在模型准确率与模型复杂度之间取得一个平衡。sklearn中默认值是1.0。
SVC的优化目标: min ω , b , ζ 1 2 ω T ω + C ∑ i = 1 n ζ i s . t . y i ( ω T ϕ ( x i ) + b ) ≥ 1 − ζ i , ζ i ≥ 0 \mathop{\min}_{\omega,b,\zeta}\frac{1}{2}\omega^T\omega+C\sum\limits_{i=1}^{n}\zeta_i \\ s.t.\quad y_i(\omega^T\phi(x_i)+b)\geq 1-\zeta_i,\, \zeta_i\geq 0 minω,b,ζ21ωTω+Ci=1∑nζis.t.yi(ωTϕ(xi)+b)≥1−ζi,ζi≥0
模型误差的部分 ζ i \zeta_i ζi被乘以一个系数 C 以后(可以看作正则项),如果 C 比较大,那么要想达到最小化的目标,模型误差就会被逼迫着尽量减小,此时模型对异常值的容忍度降低,
会尽可能多地拟合训练样本,泛化能力较差。
如果 C 比较小,那么就会鼓励模型去寻找一个较大间隔的决策边界,不强求对于训练数据完美得拟合,对极端值的容忍度比较高。此时,会牺牲一定的准确性。
svm对MNIST手写体数字图片识别的例子
sklearn-svm 网格搜索官网例子
SVM的网格搜索耗时太久,下面代码不要轻易尝试。
from sklearn import svm, metrics
from sklearn.datasets import fetch_mldata
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
import matplotlib.pyplot as plt
import numpy as np
import datetime as dt
if __name__ == "__main__":
mnist = fetch_mldata('MNIST original')
# dict_keys(['DESCR', 'COL_NAMES', 'target', 'data'])
print(mnist.keys())
# data field is 70k x 784 array, each row represents pixels from 28x28=784 image
images = mnist.data
targets = mnist.target
print(images.shape)
X_data = images/255.0
Y = targets
X_train, X_test, y_train, y_test = train_test_split(X_data, Y, test_size=0.15, random_state=13)
################ Classifier with Grid Search ###########
param_grid = {"gamma":[0.01, 0.05, 0.1],
"C":[1, 3.8, 5]}
print("Parameters:{}".format(param_grid))
# 开始计时
start_time = dt.datetime.now()
print('Start training at {}'.format(str(start_time)))
# 交叉验证和训练
model = GridSearchCV(svm.SVC(), param_grid, n_jobs=-1, cv=3)
model.fit(X_train,y_train)
print("Test set score:{:.2f}".format(model.score(X_test,y_test)))
print("Best parameters:{}".format(model.best_params_))
print("Best score on train set:{:.2f}".format(model.best_score_))
# 计时结束
end_time = dt.datetime.now()
elapsed_time= end_time - start_time
print('Elapsed training {}'.format(str(elapsed_time)))
################ predict ###########
predicted = model.predict(X_test)
# y_test is the True value
cm = metrics.confusion_matrix(y_test, predicted)
print("Confusion matrix:\n%s" % cm)
print("\nAccuracy={}".format(metrics.accuracy_score(y_test, predicted)))
Ref:
接地气的程序媛 - RBF SVM 参数解读