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

  • 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()
    
  • 在这里插入图片描述

  • 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值来实现类别不平衡的处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/205973.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 账号管理实例一,stdin,passwd复习

需求 账号名称全名次要用户组是否可登录主机密码 myuser1 1st usermygroup1yespasswordmyuser22st usermygroup1yespasswordmyuser33st user无nopassword 第一:用户,和用户组创建,并分配有效用户组(初始用户组是passwd里…

浅谈安科瑞ASJ继电器在菲律宾矿厂的应用

摘要:对电气线路进行接地故障保护,方式接地故障电流引起的设备和电气火灾事故越来越成为日常所需。针对用户侧主要的用能节点,设计安装剩余电流继电器,实时监控各用能回路的剩余电流状态。通过实时监控用能以及相关电力参数、提高…

展开运算符(...)

假如我们有一个数组: const arr [7,8,9];● 我们如果想要数组中的元素,我们必须一个一个手动的去获取,如下: const arr [7,8,9]; const badNewArr [5, 6, arr[0], arr[1],arr[2]]; console.log(badNewArr);● 但是通过展开运…

(Spring学习06)Spring之循环依赖底层源码解析

什么是循环依赖? 很简单,就是A对象依赖了B对象,B对象依赖了A对象。 比如: // A依赖了B class A{public B b; }// B依赖了A class B{public A a; }那么循环依赖是个问题吗? 如果不考虑Spring,循环依赖并不…

MindStudio学习一 整体介绍

一场景介绍 二 安装介绍 1.LINUX 采用无昇腾硬件采用linux 分部署 2.WINDOWS 3.linux下安装整体步骤 3.1安装依赖 3.2 安装步骤 1.gcc cmake 等依赖 2.python3.7.5 3.pip 安装依赖 4.安装JDK 5.安装 Ascend-cann-toolkit 6.解压安装Mindstudio 7.进入bin路径 ./…

爱创科技总裁谢朝晖荣获“推动医药健康产业高质量发展人物”

中国医药市场规模已经成为全球第二大医药市场,仅次于美国。近年来,随着中国经济的持续增长和人民生活水平的提高,医药市场需求不断扩大。政府对医疗卫生事业的投入也在不断加大,为医药行业的发展创造了良好的政策环境。为推动医药…

Maven下载与安装教程

一、下载 Maven 进入 Maven 官网:maven.apache.org/download.cgi 选择 .zip 文件下载,最新版本是 3.9.5 二、安装 Maven 将 .zip 文件解压到没有中文没有空格的路径下。例如下图,在创建一个repository的空文件夹在他的下面,用于…

php爬虫实现把目标页面变成自己的网站页面

最近又被烦的不行,琐事不断,要是比起懒来一个人比一个人懒,但是懒要转换成动力啊,能让自己真正的偷懒,而不是浪费时间。每天还是需要不断的学习的,才能更好的提高效率,把之前做的简单小功能爬虫…

5.3 Windows驱动开发:内核取应用层模块基址

在上一篇文章《内核取ntoskrnl模块基地址》中我们通过调用内核API函数获取到了内核进程ntoskrnl.exe的基址,当在某些场景中,我们不仅需要得到内核的基地址,也需要得到特定进程内某个模块的基地址,显然上篇文章中的方法是做不到的&…

TCP 连接建立

1:TCP 三次握手过程是怎样的? 客户端和服务端都处于 CLOSE 状态,服务端主动监听某个端口,处于 LISTEN 状态 第一次握手:客户端带着序号和SYN为1,把第一个 SYN 报文发送给服务端,客户端处于 SYN-…

mybatis项目中添加logback日志

1、pom.xml <dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></dependency><!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! --><dependency&g…

vuepress-----3、导航栏

3、导航栏 # 页面目录结构约定 . ├── docs │ ├── .vuepress (可选的) │ │ ├── components (可选的) │ │ ├── theme (可选的) │ │ │ └── Layout.vue │ │ ├── public (可选的) │ │ ├── styles (可选的) │ │ │…

C++学习之路(十三)C++ 用Qt5实现一个工具箱(增加一个Base64加解密功能)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《XML文本格式化功能》功能。为了继续丰富我们的工具箱&#xff0c;今天我们就再增加一个平时经常用到的功能吧&#xff0c;就是「 Base64加解密 」功能。下面我们就来看看如何来规划开发一个这样的小功能并且添加到我…

arp报文及使用go实现

一、ARP协议报文格式及ARP表 ARP&#xff08;Address Resolution Protocal&#xff0c;地址解析协议&#xff09;是将IP地址解析为以太网的MAC地址&#xff08;或者称为物理地址&#xff09;的协议。在局域网中&#xff0c;当主机或其他网络设备有数据要发送给另一个主机或设备…

spring aop核心原理概念

目录 概述aop核心概念解析Target(目标对象)Joinpoint(连接点)Advice(通知/增加)Pointcut(切入点)Aspect(切面)Advisor(通知器)Weaving(织入)Proxy(代理)Introduction(引介) 结束 概述 aop核心概念解析 Target(目标对象) 代理的目标对象 目标对象(Target)的确立&#xff0c;是…

计算方法 c++代码

环境 &#xff1a;Windows 10 Dev-C 5.11 Lagrange 插值方法 Lagrange 插值多项式&#xff1a; #include<bits/stdc.h> using namespace std; #define int long long #define fer(i,a,b) for(int ia;i<b;i) signed main(){cout<<"拉格朗日插值法&…

Linux加强篇005-用户身份与文件权限

目录 前言 1. 用户身份与能力 2. 文件权限与归属 3. 文件的特殊权限 4. 文件的隐藏属性 5. 文件访问控制列表 6. su命令与sudo服务 前言 悟已往之不谏&#xff0c;知来者之可追。实迷途其未远&#xff0c;觉今是而昨非。舟遥遥以轻飏&#xff0c;风飘飘而吹衣。问征夫以…

【Web】NewStarCTF Week3 个人复现

目录 ①Include &#x1f350; ②medium_sql ③POP Gadget ④R!!!C!!!E!!! ⑤GenShin ⑥OtenkiGirl ①Include &#x1f350; ?filephpinfo 提示查下register_argc_argv 发现为on LFI包含 pearcmd命令执行学习 pearcmd.php文件包含妙用 ?file/usr/local/lib/php/p…

AI模特换装的前端实现

本文作者为 360 奇舞团前端开发工程师 随着AI的火热发展&#xff0c;涌现了一些AI模特换装的前端工具&#xff08;比如weshop网站&#xff09;&#xff0c;他们是怎么实现的呢&#xff1f;使用了什么技术呢&#xff1f;下文我们就来探索一下其实现原理。 总体的实现流程如下&am…