核心点: 关于svm的介绍,以及代码示例!
哈喽,我是cos大壮!
记得最初学习SVM的时候,既有激动又有崇拜,也不知道为什么?总是和开始学习的回归、聚类不太一样。
在这之前咱们已经接触了 各个算法的优缺点的总结,以及8个回归类算法、7个正则化算法的总结、5 个集成算法模型的全部总结!
感兴趣的可以翻到之前看看~
咱们今天就大概一起学习一下关于SVM的方方面面。
先来啰嗦几点关于 SVM 的优势和劣势 !
优势:
1、适用性广泛 :SVM支持向量机在解决分类和回归问题上表现出色,可应用于各种数据类型和领域,例如文本分类、图像识别和生物信息学等。
2、鲁棒性强 :SVM支持向量机对于训练数据中的噪声和异常点具有一定的鲁棒性,可以有效地处理输入数据中的噪声。
3、可避免陷入局部最优解 :由于SVM支持向量机使用了结构风险最小化原则,它能够更好地避免陷入局部最优解,并且具有较低的泛化误差。
4、高维空间有效 :SVM支持向量机通过核技巧将低维空间的非线性问题映射到高维空间,在高维空间中进行线性划分,从而有效地解决了复杂的非线性问题。
5、可控制的过拟合 :SVM支持向量机通过调整正则化参数和松弛变量来控制模型的复杂度,从而可以有效地避免过拟合问题。
劣势:
1、计算复杂度高: SVM支持向量机在大规模数据集上的训练时间较长,特别是对于非线性问题和核函数的使用。
2、参数选择敏感: SVM支持向量机中的参数调优过程通常需要进行交叉验证,对于不同的问题和数据集,选择合适的参数可能会比较困难。
3、对缺失数据敏感: SVM支持向量机对于含有大量缺失数据的情况可能表现不佳,需要在预处理阶段进行适当的处理。
4、适用于二分类问题: 原始的SVM支持向量机算法只能解决二分类问题,对于多类别问题需要进行扩展或使用其他方法。
尽管SVM支持向量机存在一些劣势,但其优势使得它成为了数据分析和机器学习领域中一个重要的算法之一。
在实际工作中,我们可以根据具体问题的特点和需求来选择合适的分类算法。
大家伙如果觉得还不错!可以点赞、转发安排起来,让更多的朋友看到。
ok,咱们一起来学习一下~
线性支持向量机 线性支持向量机是一种用于解决分类问题的机器学习算法。
它的目标是找到一个能够在数据中画出一条直线(或者高维空间中的超平面),将不同类别的数据点分隔开,并且最大化两侧最靠近这条线的数据点之间的距离。
这两侧最靠近线的数据点被称为支持向量。
线性SVM在以下情况下非常有用:
当数据可以被线性分割时,即存在一条直线可以很好地将两个类别分开。 当需要一个高度可解释的模型,因为SVM的决策边界是直线或超平面,非常容易可视化和解释。 线性SVM的决策函数可以表示为:
其中, 是预测的类别, 是权重向量, 是输入特征向量, 是偏置(或截距), 表示向量的点积。决策函数的目标是使支持向量到决策边界的距离最大化,这个距离称为间隔。
我们创建一个简单的线性SVM模型,大家可以直接运行起来:
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsfrom sklearn import svm# 生成一些随机数据 X, y = datasets.make_classification(n_samples=100 , n_features=2 , n_classes=2 , n_clusters_per_class=1 , n_redundant=0 )# 创建SVM模型 clf = svm.SVC(kernel='linear' ) clf.fit(X, y)# 绘制数据点 plt.scatter(X[:, 0 ], X[:, 1 ], c=y, cmap=plt.cm.Paired)# 绘制决策边界 ax = plt.gca() xlim = ax.get_xlim() ylim = ax.get_ylim()# 创建网格来评估模型 xx, yy = np.meshgrid(np.linspace(xlim[0 ], xlim[1 ], 50 ), np.linspace(ylim[0 ], ylim[1 ], 50 )) Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape)# 绘制决策边界和间隔 plt.contour(xx, yy, Z, colors='k' , levels=[-1 , 0 , 1 ], alpha=0.5 , linestyles=['--' , '-' , '--' ]) plt.show()
其中包括数据点、决策边界和间隔。
非线性支持向量机 非线性支持向量机的神奇之处在于,它可以帮助我们把不同形状的数据分开,像拼图一样。
有时,我们不能仅仅用一条直线分开这些数据,所以我们需要一些特殊的技巧,这就是非线性SVM的用武之地。
非线性SVM在很多情况下都非常有用,比如:
当数据不是线性分布的,也就是说,不能只用一条直线把它们分开。 当我们需要解决更复杂的问题,如图像识别或自然语言处理,这些问题通常不适合线性方法。 当我们希望用一种更复杂的方式来分隔数据,以获取更好的结果。 另外,非线性SVM的数学公式比较复杂,但我们可以简化为:它是一种方法,可以将数据映射到一个不同的空间,然后在那个空间中使用线性SVM。这个映射是通过一个叫做核函数来完成的。这个核函数通常表示为 ,它将原始数据 和 映射到一个新的空间。
下面是一个使用非线性SVM的Python案例,以帮助理解。
我们将使用支持向量机库svm
中的SVC
类,并使用径向基函数(RBF)核。
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasetsfrom sklearn import svm# 创建一些具有非线性特征的数据 X, y = datasets.make_circles(n_samples=100 , factor=0.5 , noise=0.1 )# 创建非线性SVM模型 clf = svm.SVC(kernel='rbf' ) clf.fit(X, y)# 绘制数据点 plt.scatter(X[:, 0 ], X[:, 1 ], c=y, cmap=plt.cm.Paired)# 绘制决策边界 ax = plt.gca() xlim = ax.get_xlim() ylim = ax.get_ylim()# 创建网格来评估模型 xx, yy = np.meshgrid(np.linspace(xlim[0 ], xlim[1 ], 50 ), np.linspace(ylim[0 ], ylim[1 ], 50 )) Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape)# 绘制决策边界和间隔 plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8 ) plt.show()
上面代码,展示了使用非线性SVM将非线性数据分隔开。
多类别支持向量机 多类别支持向量机可以应用于许多实际问题中。
比如,当我们有很多动物的照片,我们想知道每个动物的种类;或者当我们有很多水果的特征数据,我们想根据这些特征将水果分类。
我们可以用一些数学公式来描述多类别支持向量机。假设我们有n个数据点,每个数据点有两个特征,分别用x和y表示。我们还有k个类别,用1到k的数字表示。
多类别支持向量机的目标是找到一条线(或曲线),可以将不同类别的点分开。我们可以使用以下公式表示多类别支持向量机的决策规则:
对于每个类别i(从 到 ):
如果 ,则数据点属于类别 ;否则,数据点不属于类别 。
其中 和 是用来控制决策边界的参数。
from sklearn import datasetsfrom sklearn.model_selection import train_test_splitfrom sklearn.svm import SVCimport matplotlib.pyplot as plt# 加载数据集(这里使用鸢尾花数据集作为示例) iris = datasets.load_iris() X = iris.data[:, :2 ] # 只选取前两个特征 y = iris.target# 将数据集拆分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2 , random_state=42 )# 创建多类别支持向量机模型,选择线性核函数 svm = SVC(kernel='linear' ) svm.fit(X_train, y_train)# 预测测试集中的类别 y_pred = svm.predict(X_test)# 绘制决策边界和样本点 plt.scatter(X[:, 0 ], X[:, 1 ], c=y, cmap=plt.cm.Set1) plt.xlabel('Sepal length' ) plt.ylabel('Sepal width' )# 绘制支持向量 support_vectors = svm.support_vectors_ plt.scatter(support_vectors[:, 0 ], support_vectors[:, 1 ], s=100 , facecolors='none' , edgecolors='k' )# 绘制特殊点 special_points = [[5.9 , 3.0 ], [6.2 , 2.8 ]] plt.scatter([point[0 ] for point in special_points], [point[1 ] for point in special_points], color='red' , marker='x' )# 绘制决策边界 xlim = plt.gca().get_xlim() ylim = plt.gca().get_ylim() xx = np.linspace(xlim[0 ], xlim[1 ], 30 ) yy = np.linspace(ylim[0 ], ylim[1 ], 30 ) YY, XX = np.meshgrid(yy, xx) xy = np.vstack([XX.ravel(), YY.ravel()]).T Z = svm.decision_function(xy).reshape(XX.shape) plt.contour(XX, YY, Z, colors='k' , levels=[-1 , 0 , 1 ], alpha=0.5 , linestyles=['--' , '-' , '--' ]) plt.show()
图中的点代表不同类型的花,颜色不同表示不同的类别。
核函数支持向量机 核函数支持向量机使用场景很多,比如在图像识别、文本分类和生物信息学等领域都有应用。
核函数支持向量机的公式表达如下:
给定一个训练集 ,其中 是输入特征向量, 是对应的类别标签。核函数支持向量机的目标是找到一个超平面,将不同类别的样本分隔开来。
公式表示为:
其中, 是核函数,它的作用是将输入特征映射到高维空间。 和 是模型参数,通过训练得到。
咱们再来举一个例子:
from sklearn import svmimport matplotlib.pyplot as pltimport numpy as np# 生成样本数据 X = np.array([[1 , 2 ], [3 , 4 ], [5 , 6 ], [7 , 8 ]]) y = np.array([0 , 0 , 1 , 1 ])# 创建核函数支持向量机模型 model = svm.SVC(kernel='rbf' )# 拟合数据 model.fit(X, y)# 绘制决策边界 plt.scatter(X[:, 0 ], X[:, 1 ], c=y, cmap='viridis' ) ax = plt.gca() xlim = ax.get_xlim() ylim = ax.get_ylim()# 创建网格来评估模型 xx = np.linspace(xlim[0 ], xlim[1 ], 30 ) yy = np.linspace(ylim[0 ], ylim[1 ], 30 ) YY, XX = np.meshgrid(yy, xx) xy = np.vstack([XX.ravel(), YY.ravel()]).T Z = model.decision_function(xy).reshape(XX.shape)# 绘制决策边界和支持向量 ax.contour(XX, YY, Z, colors='k' , levels=[-1 , 0 , 1 ], alpha=0.5 , linestyles=['--' , '-' , '--' ]) ax.scatter(model.support_vectors_[:, 0 ], model.support_vectors_[:, 1 ], s=100 , facecolors='none' , edgecolors='k' ) plt.show()
上述代码首先使用样本数据训练一个核函数支持向量机模型,然后通过绘制决策边界和支持向量的方式可视化分类结果。决策边界是用实线表示的,支持向量是用空心圆点表示的。
稀疏支持向量机 当我们使用稀疏支持向量机来解决一个分类问题时,我们希望找到一个超平面,能够将不同类别的数据点有效地分开。
稀疏支持向量机通常用于处理大规模数据集或高维特征的分类问题。例如,在医学图像识别中,当需要处理数百万个像素的图像数据时,稀疏支持向量机可以高效地分类;在自然语言处理中,当需要处理大量文本特征时,该算法也能发挥作用。
给定训练数据集 ,其中 是输入特征向量, 是对应的类别标签。
稀疏支持向量机的目标是找到一个超平面,使得尽可能多的训练数据点离该超平面的距离最大化。
公式表示为:
其中, 是关于训练数据点的权重系数, 是对应数据点的类别(1代表正类,-1代表负类), 是核函数,用于计算数据点 和 之间的相似度。
举一个关于稀疏支持向量机的例子,大家只要安装了相应的包即可直接运行起来:
from sklearn import svmimport matplotlib.pyplot as pltimport numpy as np# 生成样本数据 X = np.array([[1 , 2 ], [3 , 4 ], [5 , 6 ], [7 , 8 ]]) y = np.array([0 , 0 , 1 , 1 ])# 创建稀疏支持向量机模型 model = svm.SVC(kernel='linear' )# 拟合数据 model.fit(X, y)# 绘制数据点 plt.scatter(X[:, 0 ], X[:, 1 ], c=y, cmap='viridis' )# 绘制超平面 w = model.coef_[0 ] b = model.intercept_[0 ] x_min, x_max = plt.xlim() y_min, y_max = plt.ylim() xx = np.linspace(x_min, x_max) yy = -(w[0 ] * xx + b) / w[1 ] plt.plot(xx, yy, 'k-' )# 绘制支持向量 support_vectors = model.support_vectors_ plt.scatter(support_vectors[:, 0 ], support_vectors[:, 1 ], s=200 , facecolors='none' , edgecolors='k' ) plt.show()
上述代码使用给定的样本数据训练一个稀疏支持向量机模型,并绘制数据点、超平面以及支持向量。
超平面由w
和b
参数定义,支持向量表示离超平面最近的数据点。
核贝叶斯支持向量机 核贝叶斯支持向量机通过学习一些已知的例子,并找到一个特殊的边界,用于将不同的事物区分开来。
核贝叶斯支持向量机可以应用于很多现实生活中的问题。例如:
1、邮件分类:将电子邮件自动分为垃圾邮件和非垃圾邮件。
2、图像识别:判断图像中是猫还是狗。
3、情感分析:自动判断文本评论是正面还是负面情感。
核贝叶斯支持向量机的公式可以简化为以下形式:
在这个公式中, 代表我们要进行分类的事物。 是与样本数据相关的权重, 是每个样本数据对应的类别标签(例如,1代表一类事物,-1代表另一类事物)。
举个 Python 的例子
import numpy as npimport plotly.graph_objects as gofrom sklearn.svm import SVC# 生成示例数据 X = np.array([[1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ], [10 , 11 , 12 ]]) y = np.array([0 , 1 , 1 , 0 ])# 创建支持向量机模型 model = SVC(kernel='linear' )# 拟合数据 model.fit(X, y)# 绘制数据点 data = [ go.Scatter3d( x=X[:, 0 ], y=X[:, 1 ], z=X[:, 2 ], mode='markers' , marker=dict( size=6 , color=y, colorscale='Viridis' , opacity=0.8 ) ) ]# 绘制决策边界 x_min, x_max = X[:, 0 ].min() - 1 , X[:, 0 ].max() + 1 y_min, y_max = X[:, 1 ].min() - 1 , X[:, 1 ].max() + 1 z_min, z_max = X[:, 2 ].min() - 1 , X[:, 2 ].max() + 1 xx, yy, zz = np.meshgrid(np.arange(x_min, x_max, 0.1 ), np.arange(y_min, y_max, 0.1 ), np.arange(z_min, z_max, 0.1 )) Z = model.predict(np.c_[xx.ravel(), yy.ravel(), zz.ravel()]) Z = Z.reshape(xx.shape)# 添加决策边界到图形中 data.append( go.Surface( x=xx, y=yy, z=zz, surfacecolor=Z, colorscale='Viridis' , showscale=False ) )# 创建布局 layout = go.Layout( scene=dict( xaxis=dict(title='X' ), yaxis=dict(title='Y' ), zaxis=dict(title='Z' ) ), margin=dict(l=0 , r=0 , b=0 , t=0 ) )# 绘制图形 fig = go.Figure(data=data, layout=layout) fig.show()
上述代码使用示例数据训练了一个核贝叶斯支持向量机模型,并利用 Plotly 生成了直观的一个三维图像。
不平衡类别支持向量机 不平衡类别支持向量机是一种分类算法,它使用支持向量机的思想来处理不平衡类别数据集。
它的目标是通过调整决策边界,使得分类模型能够更好地识别少数类别,并提高整体分类准确率。
不平衡类别支持向量机常用于以下场景:
欺诈检测:在信用卡交易中,欺诈行为往往只占极小比例,而正常交易占大部分。 医学诊断:对于某些罕见病症或疾病,阳性样本数量通常较少。 文本分类:在某些特定的主题或事件中,负面评论或垃圾邮件的数量相对较少。 不平衡类别支持向量机的目标是最小化以下公式:
其中, 是决策边界的权重向量, 是偏置项, 是惩罚参数, 是松弛变量。
下面是一个简单的使用不平衡类别支持向量机进行分类的示例代码:
import numpy as npfrom sklearn.svm import SVCimport plotly.graph_objects as go# 创建训练数据 X = np.array([[3 , 4 ], [5 , 6 ], [7 , 8 ], [9 , 10 ]]) y = np.array([0 , 0 , 1 , 1 ])# 创建不平衡类别支持向量机模型 model = SVC(class_weight='balanced' )# 拟合模型 model.fit(X, y)# 生成网格点用于绘制决策边界 x_min, x_max = X[:, 0 ].min() - 1 , X[:, 0 ].max() + 1 y_min, y_max = X[:, 1 ].min() - 1 , X[:, 1 ].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1 ), np.arange(y_min, y_max, 0.1 )) Z = model.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape)# 绘制三维图 fig = go.Figure(data=[go.Surface(z=Z, x=xx, y=yy)]) fig.update_layout(title='Decision Boundary' , autosize=False , width=500 , height=500 , margin=dict(l=65 , r=50 , b=65 , t=90 )) fig.show()
这段代码使用 Scikit-learn 库中的 SVC 类来创建不平衡类别支持向量机模型,并使用plotly库绘制三维图来展示决策边界。在训练数据中,我们有两个特征和两个类别。通过拟合模型并预测网格点上的分类结果,我们可以得到决策边界,并将其可视化。