赞
踩
支持向量机(SVM)是一种常见的监督学习算法,主要用于分类和回归问题。它的基本思想是将数据映射到高维空间中,并在该空间中找到一个最优超平面来区分不同的类别。
具体来说,对于二分类问题,SVM算法将数据点视为n维向量,并尝试找到一个超平面,使得该平面可以将两个类别的样本点分开,并且其间隔最大。这个超平面只由离它最近的一些数据点决定,称为“支持向量”。
SVM可以通过核函数实现非线性分类,将低维空间的数据点映射到高维空间,从而构造出更加复杂的分类器。此外,SVM还可以解决多分类问题,如使用“一对多”方法将多个二分类问题转化为单个问题。
SVM算法在处理小型和中型数据集时表现良好,并且具有广泛的应用范围,包括图像识别、文本分类、生物信息学等领域。
优点:
支持向量机算法可以解决小样本情况下的机器学习问题,简化了通常的分类和回归等问题。
由于采用核函数方法克服了维数灾难和非线性可分的问题,所以向高维空间映射时没有增加计算的复杂性。换句话说,由于支持向量计算法的最终决策函数只由少数的支持向量所确定,所以计算的复杂性取决于支持向量的数目,而不是样本空间的维数。
支持向量机算法利用松弛变量可以允许一些点到分类平面的距离不满足原先要求,从而避免这些点对模型学习的影响。
缺点:
支持向量机算法对大规模训练样本难以实施。这是因为支持向量机算法借助二次规划求解支持向量,这其中会涉及m阶矩阵的计算,所以矩阵阶数很大时将耗费大量的机器内存和运算时间。
经典的支持向量机算法只给出了二分类的算法,而在数据挖掘的实际应用中,一般要解决多分类问题,但支持向量机对于多分类问题解决效果并不理想。
SVM算法效果与核函数的选择关系很大,往往需要尝试多种核函数,即使选择了效果比较好的高斯核函数,也要调参选择恰当的 γ参数。另一方面就是现在常用的SVM理论都是使用固定惩罚系数 C,但正负样本的两种错误造成的损失是不一样的。
函数间隔是没有统一量度,没有规范化,并不能正常反应点到超平面的距离,在感知机模型里,当分子成比例的增长时,分母也是成倍增长。为了统一度量,需要对法向量w加上约束条件,这样就得到了几何间隔 γ , 定义为:
在样本空间中,划分超平面可通过如下线性方程来描述:
其中w=(w1;w2;...;wd)为法向量,决定了超平面的方向;b为位移项,决定了超平面与原点之间的距离。划分超平面可被法向量ω和位移b确定,并将其记为(ω,b)。样本空间中任意点x到超平面(ω,b)的距离可写为:
假设超平面(ω,b)能将训练样本正确分类,即对于(xi,yi)∈D:
若yi=+1,则有wT+b>0;
若yi=−1,则有wT+b<0。
令
如下图所示,距离超平面最近的这几个训练样本点使上式等号成立,他们被称为“支持向量”
两个异类支持向量到超平面的的距离之和为
它被称为“间隔”。
欲找到具有“最大间隔”的划分超平面,也就是要找到能满足式
约束的参数ω和b,使得γ最大,即
显然,为了最大化间隔,仅需最大化||ω||−1,这等价于最小化||ω||2,于是上式可写成
这就是支持向量机(SVM)的基本型。
如下图所示,分离超平面为 wT+b=0,如果所有的样本不光可以被超平面分开,还和超平面保持一定的函数距离(下图函数距离为1),那么这样的分类超平面是比感知机的分类超平面优的。
可以证明,这样的超平面只有一个。
和超平面平行的保持一定的函数距离的这两个超平面对应的向量,我们定义为支持向量,如下图虚线所示。
★超平面方程:wT+b=0
★最大间隔: 寻找参数ω和b, 使得γ最大
即:
这是一个二次规划问题。然而,该问题的规模正比于训练样本数,这会在实际任务中造成很大的开销。为了避开这个方案,人们提出了很多高效算法,SMO是其中一个著名的代表。
若不存在一个能正确划分两类样本的超平面怎么办?将样本从原始空间映射到一个更高维的特征空间, 使得样本在这个特征空间内线性可分。
工作原理:当低维空间内线性不可分时,可以通过高位空间实现线性可分。但如果在高维空间内直接进行分类或回归时,则存在确定非线性映射函数的形式和参数问题,而最大的障碍就是高维空间的运算困难且结果不理想。通过核函数的方法,可以将高维空间内的点积运算,巧妙转化为低维输入空间内核函数的运算,从而有效解决这一问题。
- import numpy as np
- import pandas as pd
- from sklearn import datasets
- from sklearn.model_selection import train_test_split
- from sklearn.svm import SVC
- from sklearn.metrics import accuracy_score
- import 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模型对象并进行训练
- svm = SVC(kernel='linear', C=1.0, random_state=42)
- svm.fit(X_train, y_train)
-
- # 预测测试集和预测集的结果
- y_pred_test = svm.predict(X_test)
- y_pred_new = svm.predict(np.array([[5.1, 3.5], [6.2, 2.9], [4.8, 3.1]])) # 预测新样本
-
- # 计算模型在测试集的准确率
- accuracy_test = accuracy_score(y_test, y_pred_test)
- print("测试集准确率:", accuracy_test)
-
- # 绘制散点图
- 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.02),
- np.arange(y_min, y_max, 0.02))
- Z = svm.predict(np.c_[xx.ravel(), yy.ravel()])
- Z = Z.reshape(xx.shape)
- plt.contourf(xx, yy, Z, alpha=0.4)
- plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, alpha=0.8)
- plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, s=80, edgecolors='k', alpha=0.8, marker='^')
- plt.scatter(np.array([5.1, 6.2, 4.8]), np.array([3.5, 2.9, 3.1]), s=80, edgecolors='k', alpha=0.8, marker='s')
- plt.xlabel('Sepal length')
- plt.ylabel('Sepal width')
- plt.title('SVM on Iris Data')
- plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。