支持向量机,硬间隔,软间隔,核技巧,超参数设置,分类与回归

  • SVM(Support Vector Machine,支持向量机)是一种非常常用并且有效的监督学习算法,在许多领域都有广泛应用。它可以用于二分类问题和多分类问题,并且在处理高维数据和特征选择方面非常强大。SVM算法的核心思想是通过找到一个超平面来最大化最小边界的方式进行分类,即找到一个能够将两类数据分开,并且最大化边界的超平面。对于线性可分的情况,SVM通过找到离超平面最近的数据点,即支持向量,计算出决策边界的法向量,从而得到分类结果。对于线性不可分的情况,可以通过引入松弛变量和核技巧来实现非线性的分类。

  • 以线性可分的情况为例,假设训练数据集为 ( x i , y i ) , i = 1 , 2 , . . . , n (x_i, y_i), i=1,2,...,n (xi,yi),i=1,2,...,n,其中 x i ∈ R d , y i ∈ { − 1 , 1 } x_i \in R^d, y_i \in \{-1,1\} xiRd,yi{1,1}。我们的目标是找到最优的超平面 W T x + b = 0 W^Tx + b =0 WTx+b=0,使得对于正例 y i = 1 y_i=1 yi=1,有 W T x i + b ≥ 1 W^Tx_i + b \geq 1 WTxi+b1,对于反例 y i = − 1 y_i=-1 yi=1,有 W T x i + b ≤ − 1 W^Tx_i + b \leq -1 WTxi+b1。我们可以通过最小化目标函数来求解 W W W b b b

    • min ⁡ W , b 1 2 ∣ ∣ W ∣ ∣ 2 \min_{W,b} \frac{1}{2} ||W||^2 W,bmin21∣∣W2

    • 约束条件为: y i ( W T x i + b ) ≥ 1 , ∀ i y_i(W^Tx_i + b) \geq 1, \forall i yi(WTxi+b)1,i;通过求解上述问题,我们可以得到最优的超平面,从而进行分类预测。

  • 计算过程

    • 导入所需的库和数据集
    • 数据预处理(标准化)
    • 拆分训练集和测试集
    • 构建SVM模型并进行训练
    • 对测试集进行预测
    • 评估模型性能
    • 可视化预测结果
  • from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import train_test_split
    from sklearn.svm import SVR
    from sklearn.metrics import r2_score
    import numpy as np
    import pandas as pd
    data_url = "http://lib.stat.cmu.edu/datasets/boston"
    raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
    data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
    target = raw_df.values[1::2, 2]
    s = StandardScaler()
    ds = s.fit_transform(data)
    x_tr,x_te,y_tr,y_te = train_test_split(ds,target,test_size=0.2,random_state=2023)
    svr_net = SVR(kernel='linear')
    svr_net.fit(x_tr,y_tr)
    y_p = svr_net.predict(x_te)
    r2 = r2_score(y_te,y_p)
    print(r2)
    # 可视化预测结果
    from matplotlib import pyplot as plt
    plt.scatter(range(len(y_te)), y_te, color='b', label='Actual')
    plt.plot(range(len(y_p)), y_p, color='r', label='Predicted')
    plt.xlabel('Sample')
    plt.ylabel('Price')
    plt.title('SVM Regression')
    plt.legend()
    plt.show()
    
  • 支持向量机,硬间隔,软间隔,核技巧,超参数设置,分类与回归_第1张图片

  • 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)
    
  • C:表示错误项的惩罚系数C越大,即对分错样本的惩罚程度越大,因此在训练样本中准确率越高,但是泛化能力降低;相反,减小C的话,容许训练样本中有一些误分类错误样本,泛化能力强。对于训练样本带有噪声的情况,一般采用后者,把训练样本集中错误分类的样本作为噪声。

  • kernel:该参数用于选择模型所使用的核函数,算法中常用的核函数有:-- linear:线性核函数**-- poly**:多项式核函数–rbf:径像核函数/高斯核–sigmod:sigmod核函数–precomputed:核矩阵,该矩阵表示自己事先计算好的,输入后算法内部将使用你提供的矩阵进行计算

  • degree:该参数只对’kernel=poly’(多项式核函数)有用,是指多项式核函数的阶数n,如果给的核函数参数是其他核函数,则会自动忽略该参数。

  • cache_size:该参数表示指定训练所需要的内存,以MB为单位,默认为200MB。

  • verbose:该参数表示是否启用详细输出。此设置利用libsvm中的每个进程运行时设置,如果启用,可能无法在多线程上下文中正常工作。一般情况都设为False,不用管它。

  • max_iter:该参数表示最大迭代次数,如果设置为-1则表示不受限制。

  • class_weight:该参数表示给每个类别分别设置不同的惩罚参数C,如果没有给,则会给所有类别都给C=1,即前面参数指出的参数C。如果给定参数‘balance’,则使用y的值自动调整与输入数据中的类频率成反比的权重。

    • svc.n_support_:各类各有多少个支持向量;
    • svc.support_:各类的支持向量在训练样本中的索引;
    • svc.support_vectors_:各类所有的支持向量。
  • sklearn.svm.SVR(kernel ='rbf',degree = 3,gamma ='auto_deprecated',coef0 = 0.0,
    tol = 0.001,C = 1.0,epsilon = 0.1,shrinking = True,cache_size = 200,verbose = False,max_iter = -1
  • kernel:可以是: ‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’ 或者自己指定。 默认使用‘rbf’ 。

  • coef0:kernel函数的常数项。 只有在 kernel为‘poly’或‘sigmoid’时有效,默认为0。

  • tol:误差项达到指定值时则停止训练,默认为1e-3,即0.001。

  • shrinking:如果能预知哪些变量对应着支持向量,则只要在这些样本上训练就够了,其他样本可不予考虑,这不影响训练结果,但降低了问题的规模并有助于迅速求解。进一步,如果能预知哪些变量在边界上(即a=C),则这些变量可保持不动,只对其他变量进行优化,从而使问题的规模更小,训练时间大大降低。这就是Shrinking技术。 Shrinking技术基于这样一个事实:支持向量只占训练样本的少部分,并且大多数支持向量的拉格朗日乘子等于C

  • 通过非线性支持向量机(Nonlinear Support Vector Machine,简称非线性SVM)来建立一个房价预测模型。非线性SVM是支持向量机的一种拓展,通过处理非线性可分数据,提高模型的拟合能力。与线性SVM不同的是,非线性SVM引入了核函数(kernel function),将原始数据映射到一个高维特征空间,从而使得原本非线性可分的问题变为线性可分的问题。常用的核函数有线性核、多项式核和径向基函数(Radial Basis Function,简称RBF)核。对于非线性SVM的目标函数,我们需要优化其参数,并通过解决一个凸优化问题来求解。同时,我们也需要对求解后的模型进行预测,来实现回归或分类任务。

    • 核函数的基本思想是通过构造一个映射函数将样本从原始特征空间转换到一个更高维的特征空间,在高维特征空间中使用线性SVM进行分类或回归。常见的核函数有多项式核和RBF核。其中,多项式核将数据映射到多项式特征空间,而RBF核通过计算样本点和支持向量之间的相似度来构造高维特征空间
  • 给定训练样本集 { ( x i , y i ) } i = 1 N \{(\mathbf{x}_i, y_i)\}_{i=1}^N {(xi,yi)}i=1N,其中 x i ∈ R d , y i ∈ { − 1 , 1 } \mathbf{x}_i \in \mathbb{R}^d,y_i \in \{-1, 1\} xiRdyi{1,1}代表样本点和样本标签。线性支持向量机的目标是找到一个最优的超平面,将不同类别的样本点分开。我们可以通过最小化以下目标函数来求解线性SVM的模型参数:

    • min ⁡ w , b 1 2 ∥ w ∥ 2 + C ∑ i = 1 N max ⁡ ( 0 , 1 − y i ( w T x i + b ) ) \min_{\mathbf{w}, b} \frac{1}{2}\|\mathbf{w}\|^2 + C\sum_{i=1}^N \max(0, 1-y_i(\mathbf{w}^T\mathbf{x}_i + b)) w,bmin21w2+Ci=1Nmax(0,1yi(wTxi+b))

    • 其中, w \mathbf{w} w b b b分别代表超平面的法向量和截距, C C C是一个正则化超参数。

  • 非线性SVM的核心思想是将原始样本数据映射到一个高维特征空间,通过高维特征空间中的线性SVM来实现对非线性数据的拟合。给定核函数 K ( x i , x j ) K(\mathbf{x}_i, \mathbf{x}_j) K(xi,xj),它可以计算 x i \mathbf{x}_i xi x j \mathbf{x}_j xj之间的相似度。我们可以通过核函数将输入样本映射到高维特征空间中。在高维特征空间中,非线性SVM的原始目标函数为:

    • min ⁡ w , b 1 2 ∥ w ∥ 2 + C ∑ i = 1 N max ⁡ ( 0 , 1 − y i ( w T ϕ ( x i ) + b ) ) \min_{\mathbf{w}, b} \frac{1}{2}\|\mathbf{w}\|^2 + C\sum_{i=1}^N \max(0, 1-y_i(\mathbf{w}^T\phi(\mathbf{x}_i) + b)) w,bmin21w2+Ci=1Nmax(0,1yi(wTϕ(xi)+b))

    • 其中, ϕ ( x ) \phi(\mathbf{x}) ϕ(x)表示核函数将 x \mathbf{x} x映射到高维特征空间的结果。

  • 计算流程

    • 导入数据集并进行数据预处理
    • 将数据集划分为训练集和测试集
    • 使用非线性SVM建立回归模型
    • 模型训练和参数优化
    • 模型预测和性能评估
  • 原理:SVR在线性函数两侧制造了一个“间隔带”,间距为ϵ (也叫容忍偏差,是一个由人工设定的经验值),对所有落入到间隔带内的样本不计算损失,也就是只有支持向量才会对其函数模型产生影响,最后通过最小化总损失和最大化间隔来得出优化后的模型。数据在间隔带内则不计算损失,当且仅当f(x)与y之间的差距的绝对值大于ϵ 才计算损失;通过最大化间隔带的宽度与最小化总损失来优化模型

  • import numpy as np
    import pandas as pd
    data_url = "http://lib.stat.cmu.edu/datasets/boston"
    raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
    data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
    target = raw_df.values[1::2, 2]
    from sklearn.model_selection import train_test_split
    xtrain,xtest,ytrain,ytest = train_test_split(data,target,test_size=0.2,random_state=2023)
    from sklearn.svm import SVR
    svr = SVR(kernel='rbf')
    svr.fit(xtrain,ytrain)
    y_pre =svr.predict(xtest)
    from sklearn.metrics import r2_score
    r2 = r2_score(ytest,y_pre)
    print(r2)
    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import StandardScaler
    pipe = Pipeline([("scaler", StandardScaler()), ("regressor", SVR(kernel='rbf', C=1e3, gamma=0.1))])
    pipe.fit(xtrain,ytrain)
    ypr = pipe.predict(xtest)
    r21 = r2_score(ytest,ypr)
    print(r21)
    import yaml
    # print(type(pipe.get_params()))
    # print(pipe.get_params())
    # print(yaml.dump(pipe.get_params()))
    param_grid = {"regressor__C": [0.1, 1, 10, 100, 1000],
                  "regressor__kernel": ["poly", "rbf", "sigmoid"],
                  "regressor__gamma": [1e-7, 1e-4, 1e-3, 1e-2]}
    from sklearn.model_selection import GridSearchCV
    gs = GridSearchCV(pipe, param_grid, n_jobs=-1, verbose=1)
    gs.fit(xtrain, ytrain)
    yp = gs.predict(xtest)
    r22 = r2_score(ytest,yp)
    print(r22)
    print(gs.best_estimator_)
    print(gs.best_score_)
    # 绘制预测结果和真实值曲线
    from matplotlib import pyplot as plt
    plt.scatter(range(len(ytest)), ytest, color="b", label="true")
    plt.plot(range(len(ytest)), yp, color="r", label="predicted")
    plt.xlabel("Sample Index")
    plt.ylabel("House Price")
    plt.legend()
    plt.show()
    
  • GridSearchCV,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化的结果和参数。但是这个方法适合于小数据集,一旦数据的量级上去了,很难得出结果。数据量比较大的时候可以使用一个快速调优的方法——坐标下降。它其实是一种贪心算法:拿当前对模型影响最大的参数调优,直到最优化;再拿下一个影响最大的参数调优,如此下去,直到所有的参数调整完毕。这个方法的缺点就是可能会调到局部最优而不是全局最优,但是省时间省力,巨大的优势面前,还是试一试吧,后续可以再拿bagging再优化。调参的要旨是:每次调一个或两个超参数,然后将找到的最优超参数代入到模型中继续调余下的参数。

  • class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True, refit=True, cv=None, verbose=0, pre_dispatch=2*n_jobs’, error_score=raise, return_train_score=’warn’)
    ##
    sklearn.model_selection.GridSearchCV(
    estimator, 
    param_grid, 
    scoring=None,
     n_jobs=None,
     iid=’warn’, 
    refit=True, 
    cv=’warn’, 
    verbose=0, 
    pre_dispatch=2*n_jobs’, 
    error_score=raise-deprecating’, 
    return_train_score=False)
    
    • estimator:选择使用的分类器,并且传入除需要确定最佳的参数之外的其他参数。每一个分类器都需要一个scoring参数,或者score方法:estimator=RandomForestClassifier(min_samples_split=100,min_samples_leaf=20,max_depth=8,max_features=‘sqrt’,random_state=10),
    • param_grid:需要最优化的参数的取值,值为字典或者列表,例如:param_grid = {‘n_estimators’:range(10,71,10)}。
    • scoring=None,根据所选模型不同,评价准则不同。比如scoring=”accuracy”。Classification:【‘accuracy’,‘average_precision’,‘f1’,‘f1_micro’,‘f1_macro’,‘f1_weighted’,‘f1_samples’,‘neg_log_loss’,‘roc_auc’,‘recall’ ,‘precision’ 】;Clustering:【‘adjusted_rand_score’】;Regression:【‘neg_mean_absolute_error’,‘neg_mean_squared_error’,‘neg_median_absolute_error’,‘r2’】
    • n_jobs=1 进程个数,默认为1。 若值为 -1,则用所有的CPU进行运算。 若值为1,则不进行并行运算,这样的话方便调试。
    • iid=True;默认True,为True时,默认为各个样本fold概率分布一致,误差估计为所有样本之和,而非各个fold的平均。
    • refit=True;默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。
    • cv=None;交叉验证参数,默认None,使用三折交叉验证。
    • pre_dispatch=‘2*n_jobs’;指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次。
  • 多类别支持向量机是通过将多个二分类问题相互比较来进行多类别分类的。一种常用的方法是一对一(One-vs-One)策略,在该策略下,每个类别之间都有一个分类器。假设有K个类别,那么将会有K * (K-1) / 2个分类器。每个分类器只关注其两个类别之一,对于属于其中一个类别的样本,将其标记为正例,而对于属于另一个类别的样本,将其标记为负例。最后,使用投票机制来确定对新样本的分类结果,即选择获得最多正例标签的类别作为最终的分类结果。

  • 在MC-SVM中,我们可以使用与二分类SVM类似的方法来训练分类器。对于每对类别之间的二分类任务,我们通过最小化带有正则化项的目标函数来找到一个最优的超平面。

    • min ⁡ w , b 1 2 w T w + C ∑ i = 1 n ξ i \min_{w,b} \frac{1}{2}w^Tw + C\sum_{i=1}^{n}\xi_{i} w,bmin21wTw+Ci=1nξi

    • 其中, w w w是超平面的法向量, b b b是偏置项, ξ i \xi_{i} ξi是松弛变量,n是样本数量,C是惩罚参数,用于控制误分类样本和决策边界之间的平衡。与二分类SVM类似,我们还可以使用软间隔(Soft Margin)来容忍某些样本的误分类。此时,目标函数需要加入松弛变量项,公式为:

    • min ⁡ w , b , ξ 1 2 w T w + C ∑ i = 1 n ξ i \min_{w,b,\xi} \frac{1}{2}w^Tw + C\sum_{i=1}^{n}\xi_{i} w,b,ξmin21wTw+Ci=1nξi

    • 同时,我们需要满足以下约束条件:

    • y i ( w T x i + b ) ≥ 1 − ξ i , ∀ i ξ i ≥ 0 , ∀ i y_{i}(w^Tx_{i} + b) \geq 1 - \xi_{i}, \forall i\\ \xi_{i} \geq 0, \forall i yi(wTxi+b)1ξi,iξi0,i

    • 其中, x i x_{i} xi表示样本特征, y i y_{i} yi为对应的类别标签。

  • 计算步骤

    • 导入所需的库和数据集。
    • 对数据集进行预处理,包括划分为训练集和测试集,并进行归一化处理。
    • 定义MC-SVM模型,并使用训练集进行训练。
    • 使用测试集评估模型的性能。
  • from sklearn.model_selection import train_test_split
    from sklearn.metrics import r2_score
    from sklearn.svm import SVC
    from sklearn.multiclass import OneVsOneClassifier
    from sklearn.datasets import load_iris
    # 分类算法数据集
    data = load_iris()
    idata,itarget = data.data, data.target
    Xtrain,Xtest,ytrain,ytest = train_test_split(idata,itarget,test_size=0.2,random_state=2023)
    from sklearn.preprocessing import StandardScaler
    s= StandardScaler()
    Xtrains = s.fit_transform(Xtrain)
    Xtests = s.fit_transform(Xtest)
    model = OneVsOneClassifier(SVC())
    model.fit(Xtrains,ytrain)
    y_pre = model.predict(Xtests)
    r2 = r2_score(ytest,y_pre)
    print(r2)
    
  • reshape()函数用于在不更改数据的情况下为数组赋予新形状。numpy.reshape(a, newshape, order=‘C’)

    • a:需要 reshape 的数组
    • newshape:新形状应与原始形状兼容。如果是整数,则结果将是该长度的一维数组。一个形状尺寸可以为-1。在这种情况下,该值是根据数组的长度和其余维来推断的。
    • order:order:{‘C’,‘F’,‘A’}可选;使用此索引顺序读取a的元素,并使用此索引顺序将元素放置到重新形成的数组中。'C’意味着使用C样索引顺序读取/写入元素,最后一个轴索引变化最快,回到第一个轴索引变化最慢。'F’意味着使用Fortran样索引顺序读取/写入元素,第一个索引变化最快,最后一个索引变化最慢。注意,'C’和’F’选项不考虑底层数组的内存布局,而只是参考索引的顺序。'A’意味着在Fortran类索引顺序中读/写元素,如果a 是Fortran 在内存中连续的,否则为C样顺序。
  • 在实际使用中,特别是在运用函数的时候,系统经常会提示是否需要对数据不知道几列,反正是1行:【使用reshape(1,-1)】或者不知道几行,反正是1列:【reshape(-1,1)】进行转换

    • import numpy as np
      temp = [i+1 for i in range(27)]
      print(temp)
      temp_333 = np.array(temp).reshape((3,3,3))
      print(temp_333,temp_333.shape)
      temp_n1 = temp_333.reshape((-1,1))
      print(temp_n1,temp_n1.shape)
      temp_1n = temp_n1.reshape((1,-1))
      print(temp_1n,temp_1n.shape)
      temp_13n = temp_1n.reshape((1,3,-1))
      print(temp_13n,temp_13n.shape)
      temp_1n3 = temp_13n.reshape((1,-1,3))
      print(temp_1n3,temp_1n3.shape)
      
  • transpose()函数的作用就是调换数组的行列值的索引值,类似于求矩阵的转置,numpy.transpose (arr, axes)。Numpy库中提供了转置函数 transepose()完成高维数组的转置,返回的是源数据的视图,不进行任何复制操作。二维数组(即矩阵)的转换较好理解,但高维数组的转置则比较抽象。

    • import numpy as np
      t = np.arange(1,25).reshape(2, 3, 4)
      print(t,t.shape)
      t1 = t.transpose(1, 0, 2)
      # 语句t1 = t.transpose(1, 0, 2)相当于把0轴和1轴位置进行了交换,2轴位置没有变化。对比一下:t: (0, 1, 2) → t1: (1, 0, 2).
      print(t1,t1.shape)
      t2 = t1.transpose(2,1,0)
      print(t2,t2.shape)
      
  • 支持向量机属于一类监督学习算法,主要用于分类和回归问题。在核函数支持向量机中,我们首先将输入特征映射到一个高维特征空间,然后在这个特征空间中构建一个最优超平面,用于对数据进行分类或回归。对于回归问题,根据SVM的原理,我们设定一个边界(超平面),使得所有数据点到这个边界的距离之和最小。通过引入核函数,我们可以在低维空间中进行计算(而不是在高维特征空间中),从而避免了高维度的计算开销。

  • 假设我们有一个训练集 { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } \{(\mathbf{x}_1, y_1), (\mathbf{x}_2, y_2), ..., (\mathbf{x}_m, y_m)\} {(x1,y1),(x2,y2),...,(xm,ym)},其中 x i ∈ R n \mathbf{x}_i \in \mathbb{R}^n xiRn 表示输入特征向量, y i ∈ R y_i \in \mathbb{R} yiR 表示对应的目标值。我们的目标是找到一个超平面 f ( x ) = w T ϕ ( x ) + b f(\mathbf{x}) = \mathbf{w}^T\phi(\mathbf{x}) + b f(x)=wTϕ(x)+b,使得对于所有的 i i i,有 ∣ f ( x i ) − y i ∣ ≤ ϵ |f(\mathbf{x}_i) - y_i| \leq \epsilon f(xi)yiϵ。可以通过构建一个拉格朗日函数来 将问题转换为一个凸优化问题。拉格朗日函数为:

    • L ( w , b , α , η ) = 1 2 ∥ w ∥ 2 − ∑ i = 1 m α i ( y i − w T ϕ ( x i ) − b ) − ∑ i = 1 m η i ( α i − C ) L(\mathbf{w}, b, \boldsymbol{\alpha}, \boldsymbol{\eta}) = \frac{1}{2}\|\mathbf{w}\|^2 - \sum_{i=1}^{m}\alpha_i (y_i - \mathbf{w}^T\phi(\mathbf{x}_i) - b) - \sum_{i=1}^{m}\eta_i(\alpha_i - C) L(w,b,α,η)=21w2i=1mαi(yiwTϕ(xi)b)i=1mηi(αiC)

    • 其中, α = [ α 1 , α 2 , . . . , α m ] T \boldsymbol{\alpha} = [\alpha_1, \alpha_2, ..., \alpha_m]^T α=[α1,α2,...,αm]T 是拉格朗日乘子向量, η = [ η 1 , η 2 , . . . , η m ] T \boldsymbol{\eta} = [\eta_1, \eta_2, ..., \eta_m]^T η=[η1,η2,...,ηm]T 是松弛变量乘子向量, C C C 是一个正则化参数,控制了拉格朗日乘子的惩罚。需要求解拉格朗日函数的对偶问题。对偶问题最终被转化为求解

    • max ⁡ α min ⁡ w , b L ( w , b , α , η ) \max_{\boldsymbol{\alpha}} \min_{\mathbf{w}, b} L(\mathbf{w}, b, \boldsymbol{\alpha}, \boldsymbol{\eta}) αmaxw,bminL(w,b,α,η)

    • 求解得到的 α \boldsymbol{\alpha} α 可以帮助我们确定支持向量,并用于预测新样本的目标值。

  • 计算流程

    • 加载数据集并进行预处理。
    • 切分数据集为训练集和测试集。
    • 定义核函数支持向量机模型。
    • 训练模型并进行预测。
    • 评估模型性能。
  • from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.metrics import r2_score,mean_squared_error
    from sklearn.svm import SVR
    import numpy as np
    import pandas as pd
    data_url = "http://lib.stat.cmu.edu/datasets/boston"
    raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
    data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
    target = raw_df.values[1::2, 2]
    data = StandardScaler().fit_transform(data)
    Xtrains,Xtests,ytrain,ytest = train_test_split(data,target,test_size=0.2,random_state=2023)
    # s = StandardScaler()
    # Xtrains = s.fit_transform(Xtrain)
    # Xtests = s.fit_transform(Xtest)
    model = SVR(kernel='rbf', C=1.0, epsilon=0.1)
    # 使用SVR类来创建一个支持向量机回归模型,指定核函数为高斯径向基核函数(RBF kernel),正则化参数为1.0,松弛变量容忍度为0.1。
    model.fit(Xtrains,ytrain)
    ypre = model.predict(Xtests)
    r2= r2_score(ytest,ypre)
    print(r2)
    
  • 数据标准化,应该在训练集和测试集划分后,分别对训练集和测试集进行数据标准化处理。不应该是数据标准化后,再进行划分。虽然从模型测试的结果看,可能出现的差距不大。在真正的部署过程中,测试数据实际上就是那些源源不断刚刚出现的数据,你不知道它什么分布,也不知道它出现什么样的数值。所以你要用训练数据得到的均值和标准偏差,去转换它。这更加贴近部署的实际。测试集的归一化的均值和标准偏差应该来源于训练集。数据预处理:我们使用StandardScaler对特征矩阵进行标准化处理,将所有特征缩放到均值为0、方差为1的标准正态分布。

  • 稀疏支持向量机(SSVM)通过引入稀疏性约束,可以在保持较小的存储和计算开销的同时,实现和经典支持向量机相近的性能。它在L1-正则化的基础上,添加了一个对偶问题的修正项。我们考虑一个线性的回归问题,其中有m个训练样本。给定输入矩阵X(大小为m×n,m为样本数,n为特征数量)和对应的目标向量y(大小为m×1),我们的目标是学习一个最佳的回归模型。稀疏支持向量机的目标函数可以表示为如下形式的优化问题:

    • min ⁡ w , b , ξ i 1 2 w T w + C ∑ i ξ i \min_{w,b,\xi_{i}} \frac{1}{2}w^{T}w + C \sum_{i} \xi_{i} w,b,ξimin21wTw+Ciξi

    • 最小化经验误差: 1 2 w T \frac{1}{2}w^{T} 21wT,其中w是回归系数。

    • 最小化目标函数中的正则项: C ∑ i ξ i C \sum_{i} \xi_{i} Ciξi.其中C是正则项系数, ξ i \xi_{i} ξi 是松弛变量。

    • 满足约束条件: y i − w T x i − b ≤ ϵ + ξ i y_{i} - w^{T}x_{i} - b \leq \epsilon + \xi_{i} yiwTxibϵ+ξi w T x i + b − y i ≤ ϵ + ξ i w^{T}x_{i} + b - y_{i} \leq \epsilon + \xi_{i} wTxi+byiϵ+ξi,其中 ϵ \epsilon ϵ是一个预定义的容忍度值。

  • 支持向量机(SVM:Support Vector Machine)是机器学习中常见的一种分类算法,是一种二分类模型,它的目的是寻找一个超平面来对样本进行分割,分割的原则是间隔最大化,最终转化为一个凸二次规划问题来求解。支持向量机要做的就是要在这些可以选择的直线中选择一条最好的直线来作为分类的直线。

    • 当训练样本线性可分时,通过硬间隔最大化,学习一个线性可分支持向量机;
    • 当训练样本近似线性可分时,通过软间隔最大化,学习一个线性支持向量机;
    • 当训练样本线性不可分时,通过核技巧和软间隔最大化,学习一个非线性支持向量机。
  • SVM算法可以让我们找到这样一个最佳的线(超平面),来划分数据。相比于KNN之类的算法,SVM算法只需要计算一次,得出最佳线(超平面)即可。面对测试数据,只需要判断数据点落在线的哪一侧,就可以知道该数据点所属分类了。比起KNN每次都需要计算一遍邻居点的分类,SVM算法显得简单无比。

    • from sklearn.svm import LinearSVC, LinearSVR,SVC,SVR
      LSVC = LinearSVC(
          penalty='l2',
          loss='squared_hinge',
          dual=True,
          tol=0.0001,
          C=1.0,
          multi_class='ovr',
          fit_intercept=True,
          intercept_scaling=1,
          class_weight=None,
          verbose=0,
          random_state=None,
          max_iter=1000)
      
    • penalty:正则化参数,L1和L2两种参数可选,仅LinearSVC有。

    • loss:损失函数,有‘hinge’和‘squared_hinge’两种可选,前者又称L1损失,后者称为L2损失,默认是是’squared_hinge’,其中hinge是SVM的标准损失,squared_hinge是hinge的平方。

    • dual:是否转化为对偶问题求解,默认是True。

    • tol:残差收敛条件,默认是0.0001,与LR中的一致。

    • C:惩罚系数,用来控制损失函数的惩罚系数,类似于LR中的正则化系数,默认值为1.0。C越大,即对分错样本的惩罚程度越大,因此在训练样本中准确率越高,但是泛化能力降低,也就是对测试数据的分类准确率降低。相反,减小C的话,容许训练样本中有一些误分类错误样本,泛化能力强。对于训练样本带有噪声的情况,一般采用后者,把训练样本集中错误分类的样本作为噪声。

    • multi_class:负责多分类问题中分类策略制定,有‘ovr’和‘crammer_singer’ 两种参数值可选,默认值是’ovr’,'ovr’的分类原则是将待分类中的某一类当作正类,其他全部归为负类,通过这样求取得到每个类别作为正类时的正确率,取正确率最高的那个类别为正类;‘crammer_singer’ 是直接针对目标函数设置多个参数值,最后进行优化,得到不同类别的参数值大小。

    • fit_intercept:是否计算截距,与LR模型中的意思一致。

    • class_weight:与其他模型中参数含义一样,也是用来处理不平衡样本数据的,可以直接以字典的形式指定不同类别的权重,也可以使用balanced参数值。

    • verbose:详细输出,默认是False.

    • random_state:随机种子的大小。

    • max_iter:最大迭代次数,默认是1000。

    • coef_:各特征的系数(重要性)。_

    • _intercept_:截距的大小(常数值)

  • import numpy as np
    import pandas as pd
    data_url = "http://lib.stat.cmu.edu/datasets/boston"
    raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
    data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
    target = raw_df.values[1::2, 2]
    from sklearn.model_selection import train_test_split
    Xtr,Xte,ytr,yte=train_test_split(data,target)
    from sklearn.preprocessing import StandardScaler
    s= StandardScaler()
    Xtrs = s.fit_transform(Xtr)
    Xtes = s.fit_transform(Xte)
    from sklearn.svm import LinearSVR
    model = LinearSVR()
    model.fit(Xtrs,ytr)
    ypr = model.predict(Xtes)
    from sklearn.metrics import r2_score
    r2 = r2_score(yte,ypr)
    print(r2)
    print(model.coef_)
    
  • 稀疏支持向量机是一种强大的机器学习算法,它可以用于处理大规模的回归问题。通过合适地选择超参数,稀疏支持向量机可以提供较好的回归性能,并具有较小的存储和计算开销。

  • 核贝叶斯支持向量机(Kernelized Bayesian Support Vector Machines)是基于贝叶斯定理和支持向量机(Support Vector Machines,SVM)的基础上发展起来的一种算法。相比于传统的SVM算法,核贝叶斯支持向量机能够充分利用概率信息,在处理一些复杂的问题时,更具优势。核贝叶斯支持向量机的算法原理如下:

    • 假设我们有一个包含N个训练样本的数据集,每个样本的特征表示为 x i x_i xi,目标变量表示为 y i y_i yi
    • 核贝叶斯支持向量机的目标是通过学习一个函数 f ( x ) f(x) f(x),来预测新样本 x x x 的目标变量 y y y
    • 核贝叶斯支持向量机通过使用一个非线性核函数来扩展支持向量机。核函数将样本映射到一个高维特征空间中,使得在该特征空间中样本是线性可分的
    • 核贝叶斯支持向量机通过最大化后验概率来确定模型参数,并通过最大化边缘似然来对超参数进行估计。
    • 在预测新样本 x x x的目标变量 y y y时,可以使用后验概率 p ( y ∣ x ) p(y|x) p(yx)或者求解最大后验概率 p ( y ∣ x ) p(y|x) p(yx)来进行分类。
  • 核贝叶斯支持向量机的公式推导包括对模型参数和超参数的后验概率求解。对于目标变量 y y y的后验概率:

    • p ( y ∣ x , D ) = ∫ p ( y , w ∣ x , D ) d w = ∫ p ( y ∣ w , x ) p ( w ∣ D ) d w p(y|x,D) = \int{p(y,w|x,D)}dw = \int{p(y|w,x)p(w|D)dw} p(yx,D)=p(y,wx,D)dw=p(yw,x)p(wD)dw

    • 其中, p ( y , w ∣ x , D ) p(y,w|x,D) p(y,wx,D)是联合概率、 p ( y ∣ w , x ) p(y|w,x) p(yw,x)是似然概率、 p ( w ∣ D ) p(w|D) p(wD)是先验概率。

    • 对于超参数 α \alpha α β \beta β的边缘似然(marginal likelihood): p ( D ∣ α , β ) = ∫ p ( D ∣ w , β ) p ( w ∣ α ) d w p(D|\alpha, \beta) = \int{p(D|w,\beta)p(w|\alpha)dw} p(Dα,β)=p(Dw,β)p(wα)dw; 通过最大化边缘似然的对数,可以得到超参数的估计值: α ^ , β ^ = arg ⁡ max ⁡ α , β log ⁡ p ( D ∣ α , β ) \hat{\alpha}, \hat{\beta} = \arg\max_{\alpha,\beta}{\log{p(D|\alpha,\beta)}} α^,β^=argα,βmaxlogp(Dα,β)

  • 不平衡类别SVM是一种监督学习算法,用于解决分类问题,特别是在样本类别分布不均衡的情况下。传统的SVM致力于找到两个类别之间的最佳分割超平面,而不平衡类别SVM则在此基础上加入了类别权重,以便给予少数类更多的关注。SVM的目标函数可以表示为:

    • min ⁡ w , b 1 2 ∥ w ∥ 2 + C ∑ i = 1 n ξ i \min_{w,b} \frac{1}{2}\|w\|^2 + C \sum_{i=1}^{n} \xi_i w,bmin21w2+Ci=1nξi

)$$是先验概率。

  • 对于超参数 α \alpha α β \beta β的边缘似然(marginal likelihood): p ( D ∣ α , β ) = ∫ p ( D ∣ w , β ) p ( w ∣ α ) d w p(D|\alpha, \beta) = \int{p(D|w,\beta)p(w|\alpha)dw} p(Dα,β)=p(Dw,β)p(wα)dw; 通过最大化边缘似然的对数,可以得到超参数的估计值: α ^ , β ^ = arg ⁡ max ⁡ α , β log ⁡ p ( D ∣ α , β ) \hat{\alpha}, \hat{\beta} = \arg\max_{\alpha,\beta}{\log{p(D|\alpha,\beta)}} α^,β^=argα,βmaxlogp(Dα,β)

  • 不平衡类别SVM是一种监督学习算法,用于解决分类问题,特别是在样本类别分布不均衡的情况下。传统的SVM致力于找到两个类别之间的最佳分割超平面,而不平衡类别SVM则在此基础上加入了类别权重,以便给予少数类更多的关注。SVM的目标函数可以表示为:

    • min ⁡ w , b 1 2 ∥ w ∥ 2 + C ∑ i = 1 n ξ i \min_{w,b} \frac{1}{2}\|w\|^2 + C \sum_{i=1}^{n} \xi_i w,bmin21w2+Ci=1nξi

    • 其中, w w w 是超平面的法向量, b b b是偏置项, ξ i \xi_i ξi是松弛变量, C C C是正则化参数。不平衡类别SVM通过为不同类别的样本设定不同的 C C C值来实现类别不平衡的处理。

你可能感兴趣的:(机器学习,支持向量机,分类,回归)