4种SVM主要核函数及相关参数的比较

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
实时数仓Hologres,5000CU*H 100GB 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本文将用数据可视化的方法解释4种支持向量机核函数和参数的区别

简单地说,支持向量机(SVM)是一种用于分类的监督机器学习技术。它的工作原理是计算一个最好地分隔类的最大边距的超平面。

支持向量机除了提供简单的线性分离之外,还可以通过应用不同的核方法进行非线性分类。参数设置也是SVM更好地工作的另一个重要因素。通过适当的选择,我们可以使用支持向量机来处理高维数据。

本文旨将使用Scikit-learn库来展示每个核函数以及如何使用不同的参数设置。并且通过数据可视化进行解释和比较。

如果你正在寻找常见数据集(如Iris Flowers或Titanic)之外的另一个数据集,那么poksammon数据集可以是另一个选择。尽管你可能不是这些口袋怪物的粉丝,但它们的属性很容易理解,并且有各种各样的特征可供使用。

Pokemon的属性,如hp,攻击和速度,可以作为连续变量使用。对于分类变量,有类型(草、火、水等)、等级(普通、传奇)等。此外,如果有新一代或Pokemon出现,数据集将在未来进行更新。

免责声明:Pokemon和所有相关名称均为任天堂公司的版权和商标。

导入数据和库

为了直观地展示每个SVM的内核是如何分离分类的的,我们将只选择baby, legendary, mythical。我们先从导入数据和库开始。

 import numpy as np
 import pandas as pd
 import matplotlib.pyplot as plt
 import seaborn as sns

 df = pd.read_csv('pokemons.csv', index_col=0)
 df.reset_index(drop=True, inplace=True)

 df = df[df['rank'].isin(['baby', 'legendary'])]
 df.reset_index(drop=True, inplace=True)
 df.head()

EDA

Pokemon有7种基本的属性- hp,攻击,防御,特殊攻击,特殊防御,速度和高度。下面的步骤是使用我们选择的统计数据执行一个快速EDA。

 select_col = ['hp','atk', 'def', 'spatk', 'spdef', 'speed', 'height']
 df_s = df[select_col]
 df_s.info()

幸运的是,没有空值。接下来,让我们绘制Box和Whisker图,以查看这些变量的分布。

 sns.set_style('darkgrid')
 df_s.iloc[:,].boxplot(figsize=(11,5))
 plt.show()

height变量的分布与其他变量有很大的不同。在继续之前应该执行标准化。我们将使用来自sklearn的StandardScaler来进行处理

 from sklearn.preprocessing import StandardScaler
 scaler = StandardScaler()
 array_s = scaler.fit_transform(df_s)      

 df_scal = pd.DataFrame(array_s, columns=[i+'_std' for i in select_col])
 df_scal.boxplot(figsize=(11,5))
 plt.show()

标准化之后,分布看起来更好。

由于我们的数据集有多个特征,我们需要进行降维绘图。使用来自sklearn.decomposition的类PCA将维数减少到两个。结果将使用Plotly的散点图显示。

 from sklearn.decomposition import PCA
 import plotly.express as px

 #encoding
 dict_y = {'baby':1, 'legendary':2}
 df['s_code'] = [dict_y.get(i) for i in df['rank']]
 df.head()

 pca = PCA(n_components=2)
 pca_result = pca.fit_transform(array_s)
 df_pca = pd.DataFrame(pca_result, columns=['PCA_1','PCA_2'])

 df = pd.concat([df, df_pca], axis=1)

 fig = px.scatter(df, x='PCA_1', y='PCA_2', hover_name='name',
                  color='rank', opacity=0.9, 
                  color_discrete_sequence=['red', 'blue'])
 fig.update_xaxes(showgrid=False)
 fig.update_yaxes(showgrid=False)
 fig.show()

我们把Pokemon图片带入散点图。

再次免责声明:Pokemon和所有相关名称均为任天堂公司的版权和商标。

baby和legendary这两个类别之间的大多数数据点是分开的。尽管这两个类并没有完全分离,但在本文中对每个内核函数进行实验还是很有用的。

下一步是在三维空间中获得更多细节。让我们将PCA组件的数量更改为三个。这是3D散点图可以显示的最大数字。

 pcaz = PCA(n_components=3)
 pcaz_result = pcaz.fit_transform(array_s)
 df_pcaz = pd.DataFrame(pcaz_result, columns=['PCAz_1', 'PCAz_2', 'PCAz_3'])

 df = pd.concat([df, df_pcaz], axis=1)

 fig = px.scatter_3d(df, x='PCAz_1', y='PCAz_2', z='PCAz_3', hover_name='name',
                  color='rank', opacity=0.9, 
                  color_discrete_sequence=['red', 'blue'])
 fig.update_traces(marker=dict(size=4))
 fig.update_layout(margin=dict(l=0, r=0, t=0, b=0))
 fig.show()

结果显示了更多关于数据点如何在三维空间中定位的细节。在一些区域两个类仍然混合在一起。下面我们讨论核方法。

核方法

支持向量机可以简单地使用Scikit-learn库中的sklearn.svm.SVC类执行。可以通过修改核参数来选择核函数。总共有五种方法可用:

 Linear
 Poly
 RBF (Radial Basis Function)
 Sigmoid
 Precomputed

本文将主要关注前四种核方法,因为最后一种方法是预计算的,它要求输入矩阵是方阵,不适合我们的数据集

除了核函数之外,我们还将调整三个主要参数,以便稍后比较结果。

C:正则化参数

Gamma(γ): rbf、poly和sigmoid函数的核系数

Coef0:核函数中的独立项,只在poly和s型函数中有意义

在下面的代码中,predict_proba()将计算网格上可能结果的概率。最终结果将显示为等高线图。

 from sklearn import svm
 import plotly.graph_objects as go

 y = df['s_code']     # y values
 h = 0.2              # step in meshgrid
 x_min, x_max = df_pca.iloc[:, 0].min(), df_pca.iloc[:, 0].max()
 y_min, y_max = df_pca.iloc[:, 1].min(), df_pca.iloc[:, 1].max()
 xx, yy = np.meshgrid(np.arange(x_min-0.5, x_max+0.5, h),       #create meshgrid
                      np.arange(y_min-0.5, y_max+0.5, h))

 def plot_svm(kernel, df_input, y, C, gamma, coef):
     svc_model = svm.SVC(kernel=kernel, C=C, gamma=gamma, coef0=coef,
                         random_state=11, probability=True).fit(df_input, y)

     Z = svc_model.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 0]
     Z = Z.reshape(xx.shape)

     fig = px.scatter_3d(df, x='PCAz_1', y='PCAz_2', z='PCAz_3',  #3D Scatter plot
                         hover_name='name',    
                         color='rank', opacity=0.9,
                         color_discrete_sequence=['red', 'blue'])

     fig.update_traces(marker=dict(size=4))
     fig.add_traces(go.Surface(x=xx, y=yy,             # prediction probability contour plot 
                               z=Z+round(df.PCAz_3.min(),3),  # adjust the contour plot position 
                               name='SVM Prediction',
                               colorscale='viridis', showscale=False, 
                               contours = {"z": {"show": True, "start": x_min, "end": x_max,
                                                 "size": 0.1}}))

     title = kernel.capitalize() + ' C=' + str(i) + ', γ=' + str(j) + ', coef0=' + str(coef)     
     fig.update_layout(margin=dict(l=0, r=0, t=0, b=0), showlegend=False,
                       title={'text': title,
                              'font':dict(size=39),
                              'y':0.95,'x':0.5,'xanchor': 'center','yanchor': 'top'})
     return fig.show()

最后,创建三个参数的列表以进行比较,这里将比较0.01和100之间的值。如果您想尝试不同的值,可以调整该数字。

 from itertools import product
 C_list = [0.01, 100]
 gamma_list = [0.01, 100]
 coef_list = [0.01, 100]
 param = [(r) for r in product(C_list, gamma_list, coef_list)]

 print(param)

现在一切都准备好了,让我们用不同类型的核函数绘制结果。

1、线性核

这是最常见、最简单的SVM的核函数。这个核函数返回一个线性超平面,它被用作分离类的决策边界。通过计算特征空间中两个输入向量的点积得到超平面。

 for i,j,k in param:
     plot_svm('linear', df_pca, y, i, j, k)

结果中的平面(等高线图)不是超平面。它们是predict_proba()的预测概率的结果,其值在0到1之间。

概率平面表示数据点被分类的概率。黄色区域意味着成为Baby可能性很大,而蓝色区域则表示成为Legend的可能性很大。

改变SVM结果的唯一参数是正则化参数(C)。理论上,当C的数量增加时,超平面的裕度会变小。当来自不同类别的数据点混合在一起时,使用高C可能会很好。过高的正则化会导致过拟合。

2、径向基函数(RBF)核

RBF(径向基函数)。该核函数计算欧几里得距离的平方来度量两个特征向量之间的相似性。

只需更改内核名称,就可以使用相同的for循环进程。

 for i,j,k in param:
     plot_svm('rbf', df_pca, y, i, j, k)

结果表明,除了正则化参数(C)外,γ (γ)也会影响RBF核的结果,coef0对RBF核函数没有影响。

伽马参数决定了数据点对超平面的影响。对于高伽马值,靠近超平面的数据点将比更远的数据点有更大的影响。

低伽马值的概率平面比高伽马值的概率平面平滑。结果在高伽马值的后4个散点图中更为明显;每个数据点对预测概率影响很大。

3、多项式核

多项式核通过将数据映射到高维空间来工作。取变换后的高维空间中数据点与原始空间的点积。由于它处理高维数据的能力,这个内核被推荐用于执行非线性分离。

多项式核与其他核相比,处理时间是最长的。这可能是将数据映射到高维空间的结果。

 for i,j,k in param:
     plot_svm('poly', df_pca, y, i, j, k)

可以看出,这三个参数都会影响SVM的分类效果。除正则化参数(C)和γ (γ)外,coef0参数控制高次多项式对模型的影响程度。coef0值越高,预测概率等高线越趋于弯曲。

4、Sigmoid核

理论上,sigmoid函数擅长映射输入值并返回0到1之间的值。该函数通常用于神经网络中,其中s形函数作为分类的激活函数。

尽管它可以应用于SVM任务并且看起来很有用,但一些文章说结果可能太复杂而无法解释。我们这里使用数据可视化来查看这个问题。

 for i,j,k in param:
     plot_svm('sigmoid', df_pca, y, i, j, k)

可以看到从Sigmoid核得到的图很复杂,也无法解释。预测概率等值线图与其他核的预测概率等值线图完全不同。并且等高线图的颜色不在它对应的数据点下面。最主要的是当改变参数值时,结果没有模式可循。

但是我个人认为,这并不意味着这个内核很糟糕或者应该避免使用。也许他找到了我们未察觉的数据特征,所以可能会有一些分类任务,sigmoid将适合使用。

总结

支持向量机是一种有效的机器学习分类技术,因为它能够提供简单的线性和非线性分类。

因为每个数据集都有不同的特征,所以不存在银弹。为了使支持向量机有效,必须选择好核和参数,同时还要注意避免过拟合,我们以上的总结希望对你的选择有所帮助。

https://avoid.overfit.cn/post/96c405b7aecf40c5a324ac8a2718f019

作者:Boriharn K

目录
相关文章
|
7月前
|
机器学习/深度学习
为什么在二分类问题中使用交叉熵函数作为损失函数
为什么在二分类问题中使用交叉熵函数作为损失函数
282 2
|
1月前
|
机器学习/深度学习 算法
深入理解SVM中的核函数及其应用
深入理解SVM中的核函数及其应用
|
1月前
|
机器学习/深度学习 算法
如何在SVM中应用核函数
如何在SVM中应用核函数
|
4月前
|
机器学习/深度学习 算法
XGBoost中正则化的9个超参数
本文探讨了XGBoost中多种正则化方法及其重要性,旨在通过防止过拟合来提升模型性能。文章首先强调了XGBoost作为一种高效算法在机器学习任务中的应用价值,并指出正则化对于缓解过拟合问题的关键作用,具体包括降低模型复杂度、改善泛化能力和防止模型过度适应训练数据。随后,文章详细介绍了四种正则化方法:减少估计器数量(如使用`early_stopping_rounds`)、使用更简单的树(如调整`gamma`和`max_depth`)、采样(如设置`subsample`和`colsample`)以及收缩(如调节`learning_rate`, `lambda`和`alpha`)。
61 0
XGBoost中正则化的9个超参数
|
4月前
|
机器学习/深度学习 算法
【机器学习】SVM面试题:简单介绍一下SVM?支持向量机SVM、逻辑回归LR、决策树DT的直观对比和理论对比,该如何选择?SVM为什么采用间隔最大化?为什么要将求解SVM的原始问题转换为其对偶问题?
支持向量机(SVM)的介绍,包括其基本概念、与逻辑回归(LR)和决策树(DT)的直观和理论对比,如何选择这些算法,SVM为何采用间隔最大化,求解SVM时为何转换为对偶问题,核函数的引入原因,以及SVM对缺失数据的敏感性。
89 3
|
7月前
|
机器学习/深度学习 存储 算法
SVM不同核函数区别与选择
支持向量机(Support Vector Machine,SVM)是一种常用的监督学习算法,它可以将数据从低维空间映射到高维空间,以便更好地进行分类或回归分析。SVM的关键思想是找到一个能够最大化分类边界(或称为超平面)的决策边界,这个边界可以最好地区分不同类别的数据点。
307 0
|
机器学习/深度学习 资源调度 Serverless
核函数:RBF 是如何让线性 SVM 可以分类非线性数据的?
如果原始空间是有限维,即属性数有限,那么一定存在一个高维特征空间使得样本可分。
258 1
核函数:RBF 是如何让线性 SVM 可以分类非线性数据的?
|
机器学习/深度学习 数据可视化 算法
分别用线性SVM和高斯核SVM预测对数据进行分类
分别用线性SVM和高斯核SVM预测对数据进行分类
164 0
|
机器学习/深度学习 数据可视化 Python
Lasso 和 Ridge回归中的超参数调整技巧(上)
Lasso 和 Ridge回归中的超参数调整技巧
888 0
Lasso 和 Ridge回归中的超参数调整技巧(上)
|
Python
Lasso 和 Ridge回归中的超参数调整技巧(下)
Lasso 和 Ridge回归中的超参数调整技巧
394 0
Lasso 和 Ridge回归中的超参数调整技巧(下)