Python 数据分析入门:不只是画一条线,一文认识支持向量机(SVM)
适合人群:Python 初学者 / 数据分析入门 / 机器学习入门 / 教学案例分享
前面几篇文章里,我们已经从不同角度认识了分类问题:
- K近邻:看新样本和谁最像
- 决策树:像老师一样一步步做判断
- 随机森林:很多棵树一起投票
- 朴素贝叶斯:比较样本属于各个类别的概率
到了这里,再往下看分类方法,就会碰到一个非常经典、也非常有代表性的模型:
支持向量机(Support Vector Machine,SVM)
第一次看到这个名字,很多人会觉得它有点"硬核":
- 什么叫"支持向量"?
- 什么叫"超平面"?
- 为什么总听人说它适合做分类?
- 它和前面那些方法到底有什么不同?
其实入门阶段,不需要一上来就掉进复杂公式里。
你可以先把支持向量机理解成一句很直白的话:
它想做的事情,是找到一条尽可能"分得好、分得稳"的分类边界。
还是拿"学生能否通过技能考核"这个案例来说:
- 有一批学生最后通过了考核
- 也有一批学生没有通过
如果把这些学生的特征画在图里,我们当然希望能找到一条分界线,把"通过"和"未通过"尽量分开。
但问题在于:
- 不是所有数据都能轻松用一条直线分开
- 即使能分开,也不一定随便画一条线就最好
这就是支持向量机最核心的关注点:
不仅要分开,还要尽量分得更稳。
这一篇文章,我会继续用通俗方式,把 SVM 最关键的思路讲清楚:
- 支持向量机到底想解决什么问题
- 什么叫"最佳分离超平面"
- 什么是线性可分、线性不可分、非线性分类
- 为什么会提到"高维映射"
- 核方法到底是干什么的
- 如何用 Python 跑一个简单的 SVM 分类模型
一、先从一个很自然的问题开始:分类边界到底怎么画?
先回到一个很直观的想法。
假设我们要根据学生的两个特征来预测他是否能通过技能考核,比如:
- 横轴:实训成绩
- 纵轴:出勤率
如果把历史学生画成散点图,可能会出现这样的情况:
- 一部分点代表"通过"
- 一部分点代表"未通过"
这时候,一个最自然的想法就是:
能不能画一条线,把这两类点分开?
如果能分开,那新学生来了以后,只要看他落在线的哪一边,就能做出分类判断。
这就是支持向量机最容易理解的入口:
先找一条分类边界。
二、支持向量机到底在做什么?
支持向量机本质上是一种分类方法,它既可以处理线性分类,也可以处理非线性分类。
如果先不讲复杂术语,它最核心的事情可以概括成一句话:
在样本之间找到一个尽可能好的分界面,把不同类别分开。
注意,不是随便找一条线,而是找一条:
- 分得开
- 分得稳
- 泛化能力尽量好的边界
也就是说,SVM 的目标不是"只要分开就行",而是:
找一个最优的分界面。
从原理上看,支持向量机建立在统计学习理论基础上,希望在模型复杂性和学习能力之间取得平衡,从而获得更好的推广能力。
这句话如果用更直白的话来说,其实就是:
既要能把训练数据分开,也不能分得太死,得尽量让它对新数据也有效。
三、什么叫"最佳分离超平面"?
这是支持向量机里最经典、也是最容易把人吓到的词。
其实你可以先把它拆开来看。
1)什么是"分离"?
就是把不同类别分开。
比如:
- "通过"的学生分在一边
- "未通过"的学生分在另一边
2)什么是"平面"?
如果数据是二维的,那这个分界面看起来就是一条直线。
如果数据是三维的,那它就是一个平面。
如果数据维度更高,那它就是一个"超平面"。
所以你可以先简单理解成:
超平面,就是高维空间里的分类边界。
3)什么叫"最佳"?
这才是重点。
支持向量机并不满足于"只找一条能分开的线",而是希望找到一条离两边样本都尽量远 的边界。
因为这样通常会更稳。
所以"最佳分离超平面"最通俗的理解就是:
一条不仅能把两类样本分开,而且尽量离两边样本都远一点的边界。
四、为什么 SVM 不是随便画条线就行?
这个问题特别关键。
假设现在有两类点,确实可以用直线分开。
那是不是任意一条能分开的线都一样?
当然不是。
想象一下:
- 有的线虽然能分开样本,但离某些样本特别近
- 有的线分得更居中,两边留出的"安全距离"更大
直觉上你也会觉得:
第二种线更稳。
因为如果新样本稍微有点波动,第一种线就可能把它分错,第二种线则更有缓冲空间。
所以支持向量机最核心的思想之一就是:
希望分类边界尽量留出更大的间隔。
也正因为这样,SVM 通常不只是追求"分得开",而是追求"分得稳"。
五、什么是支持向量?为什么这个模型叫支持向量机?
这个名字第一次看确实会有点抽象。
其实可以这样理解:
在那条最佳分界线附近,总会有一些离边界最近的样本点。
这些点非常关键,因为:
真正决定这条边界位置的,往往就是这些最靠近边界的样本。
这些关键样本,就叫做:
支持向量
你可以把它理解成:
- 不是所有样本都同样重要
- 真正"撑住"这条边界位置的,是那几个最关键、最靠近边界的点
所以支持向量机这个名字的意思其实就是:
由支持向量来决定分类边界的模型。
这个理解先建立起来,后面再看到"支持向量"这个词,就不会觉得那么陌生了。
六、线性可分、线性不可分、非线性分类,分别是什么意思?
SVM 的分类情况,通常可以从简单到复杂分成几种。
1)线性可分
线性可分的意思是:
可以直接用一条直线(或高维中的超平面)把两类样本分开。
比如:
- 一边大多数都是"通过"
- 一边大多数都是"未通过"
- 中间留出一条明显的空隙
这种情况是最理想的,也是最容易理解的。
2)线性不可分
有些时候,两类样本分布比较乱,想用一条线完全分开会比较困难。
这时候就会出现:
- 你画哪条线,都可能有少数点分错
- 完全"零错误"地分开,做不到
这就叫线性不可分。
但这不代表 SVM 就没法用了。
实际中,支持向量机并不是要求数据必须完美分开,而是允许有一定误差,并在"分得开"和"不过度复杂"之间找平衡。
你可以先这样理解:
有时候现实数据并不那么理想,SVM 会尽量找一个总体更合理的边界。
3)非线性分类
还有一些数据更麻烦,根本不是"画条直线"就能解决的。
比如两类样本分布成:
- 环状
- 月牙状
- 弯曲交错状
这时候别说"最佳直线"了,连"普通直线"都很难分清。
这就进入了非线性分类的场景。
支持向量机之所以经典,很大一个原因就在于:
它不只会处理线性分类,也能处理非线性分类。
七、SVM 怎么处理非线性问题?为什么会提到"高维映射"?
这是 SVM 里最容易听到、也最容易发懵的一个点。
支持向量机的一个经典思路是:
如果原来的空间里不好分,那就把数据映射到更高维的空间里,再尝试去分。
什么意思?
可以这样理解:
- 在低维空间里,两类点缠在一起,不好切
- 但如果把它们变换到一个更高维的空间里,可能就变得更容易分开了
所以 SVM 的一个重要思想就是:
通过映射,把原来不好分的数据,变成更容易分的数据。
你可以先不用深究几何细节,先抓住这个直觉:
不是数据本身不能分,而是它在当前空间里不好分。换个空间,也许就好分了。
八、那"核方法"又是干什么的?
一听到"映射到高维空间",很多人马上又会想到一个问题:
那不是很麻烦吗?维度一高,计算不是更重?
这时候就轮到核方法出场了。
核方法的作用,可以先非常粗略地理解成:
不真的把数据显式搬到高维空间里,但又能得到类似"高维计算"的效果。
也就是说,它像是在帮我们"绕开"高维映射带来的直接计算问题。
所以入门阶段,你可以这样理解核方法:
- 高维映射是思路
- 核方法是实现这个思路的技巧
换句话说:
核方法是 SVM 处理非线性问题的关键工具。
九、SVM 和前面学过的方法,到底有什么不同?
学到这里,最好把它和前面的方法做一个对比。
K近邻
思路是:
看谁和新样本更像
决策树
思路是:
一步一步问问题,最后走到某个类别
随机森林
思路是:
让很多棵树一起判断,提高稳定性
朴素贝叶斯
思路是:
比较样本属于各类别的概率
支持向量机
思路是:
找一个尽量分得开、分得稳的最优分类边界
所以你可以把它们简化记成:
- KNN:看邻居
- 决策树:看规则
- 贝叶斯:看概率
- SVM:看边界
这也是为什么学到 SVM 时,很多人会明显感觉:
它是在用"几何边界"的方式思考分类问题。
十、Python 实操之前,先说一下这次用的是什么数据
下面代码里继续使用 sklearn 自带的 鸢尾花数据集(Iris)。
这个数据集一共包含:
- 150 条样本
- 4 个数值特征
- 3 个类别
4 个特征分别是:
- 花萼长度
- 花萼宽度
- 花瓣长度
- 花瓣宽度
模型的任务是根据这 4 个特征,判断样本属于哪一种鸢尾花。
所以这本质上是一个三分类任务。
虽然这个例子不是"学生能否通过技能考核"的业务数据,但它非常适合用来演示支持向量机的基本分类流程。
十一、Python 实操:用 SVM 完成一个三分类任务
下面直接使用 SVC() 来完成一个简单的支持向量机分类任务。
python
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
# 1. 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 3. 构建支持向量机模型
svm_model = SVC(kernel='linear')
# 4. 训练模型
svm_model.fit(X_train, y_train)
# 5. 查看模型效果
print("测试准确率:", svm_model.score(X_test, y_test))
十二、这段代码在做什么?
这段代码本身不复杂,但很适合把前面的概念真正落下来。
第一步:加载数据
这里加载的是鸢尾花数据集:
X是特征y是类别标签
第二步:划分训练集和测试集
和前面一样:
- 训练集用来让模型学习
- 测试集用来检验模型效果
第三步:构建 SVM 模型
这里最关键的一行是:
python
svm_model = SVC(kernel='linear')
这里的 kernel='linear' 表示:
先使用线性核,也就是先让模型按"线性分类边界"的思路来做分类。
这个写法很适合入门,因为它对应的就是最基本的"找线性分界面"的想法。
第四步:训练模型
fit() 会让支持向量机根据训练数据去学习分类边界。
第五步:输出准确率
score() 会返回模型在测试集上的准确率。
所以整段代码完成的事情就是:
用支持向量机模型,在鸢尾花数据集上完成一个三分类任务。
十三、如果把 kernel 换掉,会发生什么?
这里顺便提一句,SVM 里有一个非常重要的参数:
kernel
它就是前面提到的"核方法"在代码里的体现。
比如:
kernel='linear':线性核kernel='rbf':常用的非线性核kernel='poly':多项式核
如果你把代码改成:
python
svm_model = SVC(kernel='rbf')
那模型处理问题的方式就会更偏向非线性分类。
所以 kernel 这个参数,其实对应的就是:
你想让 SVM 用什么方式去寻找分类边界。
入门阶段先记住这一点就够了。
十四、支持向量机的优点是什么?
从整体上看,支持向量机之所以经典,是因为它在一些场景下确实很有优势。
1)适合处理小样本问题
支持向量机在小样本场景下往往表现不错。
2)既能处理线性分类,也能处理非线性分类
这一点非常重要。
前面我们已经看到,它并不局限于"画一条直线"。
3)强调泛化能力
它不是只追求把训练集分对,而是强调找到一个更稳的分类边界。
十五、支持向量机的理解难点在哪里?
SVM 的难点主要不在代码,而在概念。
比如这些词第一次看都会有点绕:
- 支持向量
- 超平面
- 线性可分
- 核方法
- 高维映射
所以学 SVM,最忌讳的就是一开始就掉进公式堆里。
更好的方法是先抓住它最本质的思路:
它就是在想办法找一个尽量分得好、分得稳的边界。
只要这个核心先理解了,后面的术语再一点点补,就不会那么乱。
十六、这一篇最该记住什么?
学完这一篇,建议至少记住下面几个关键点。
1)支持向量机到底在做什么?
寻找一个尽量分得开、分得稳的分类边界。
2)什么是最佳分离超平面?
能把不同类别分开,并且尽量离两边样本都远一点的边界。
3)为什么它叫支持向量机?
因为真正决定边界位置的,是那些最靠近边界的关键样本,也就是支持向量。
4)为什么会提到高维映射?
因为有些数据在原空间里不好分,映射到更高维后可能更容易分开。
5)核方法是干什么的?
帮助 SVM 处理非线性分类问题。
十七、结尾总结
这一篇文章,核心就是想把一个问题讲明白:
如果分类不是"看谁最像",也不是"一步步问问题",那还能怎么做?
支持向量机给出的答案是:
通过寻找一个尽量好的分类边界来做分类。
顺着这个思路,我们可以得到几个重要认识:
- SVM 是一种既能处理线性,也能处理非线性分类的方法
- 它的核心目标是寻找最佳分离超平面
- 它不只是想"分开",而是希望"分得更稳"
- 它通过高维映射和核方法来处理更复杂的分类问题
- 它和前面学过的 KNN、决策树、贝叶斯在思路上完全不同
如果前面几篇文章建立的是:
- 相似性分类思维
- 规则分类思维
- 概率分类思维
- 组合分类思维
那么这一篇真正建立起来的是:
边界分类思维。
而这也正是支持向量机最有代表性的地方。
十八、课后思考
可以试着回答下面几个问题:
- 支持向量机和决策树在分类思路上最大的区别是什么?
- 为什么 SVM 不是随便画一条线就行?
- 什么叫"最佳分离超平面"?
- 支持向量机为什么既能处理线性分类,也能处理非线性分类?
kernel这个参数在代码里代表什么?
如果这些问题你都能比较顺畅地说清楚,那支持向量机这一部分就已经真正入门了。
写在最后
支持向量机这部分内容,第一次学的时候确实比前面的 KNN、决策树更抽象一点。
但只要先抓住一个核心:
SVM 做的事情,就是尽量找到一条更好的分类边界。
后面的很多术语,其实都只是围绕这件事展开的。
所以如果你已经读到这里,那你对"分类问题到底能怎么做"这件事,理解其实已经比刚开始完整很多了。
因为你已经看到:
同样是分类,不同算法关心的根本不是同一个东西。