SVM参数理解和分类实践

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

高斯核的RBF时,核函数: K ( x , z ) = e x p ( x z 2 2 δ 2 ) K(x,z)=exp(-\dfrac{\|x-z\|^2}{2\cdot \delta^2})

直觉上来看,RBF核函数的参数 γ \gamma (gamma),效果等同于 1 δ \dfrac{1}{\delta'} ,决定了数据映射到新的特征空间后的分布(正态分布)。

gamma较大时,相当于正态分布中的 δ \delta 较小,映射出的高斯分布又高又瘦较为集中,那么单个样本对周围样本的影响力度大,范围窄,比较容易被选为支持向量,或者说整个模型的支持向量也会多,更容易过拟合。
反之,当gamma比较小时,单个样本对整个分类超平面的影响比较小,不容易被选择为支持向量,整个模型的支持向量较少。

scikit-learn中默认值是: 1 / (样本特征数*样本方差)

  • if gamma=‘scale’ (default) is passed then it uses 1 / (n_features * X.var()) as value of gamma
  • if ‘auto’, uses 1 / n_features.

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

模型误差的部分 ζ i \zeta_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 参数解读

猜你喜欢

转载自blog.csdn.net/rover2002/article/details/106280837
今日推荐