机器学习 支持向量机(SVM)
一、SVM的介绍
支持向量机(support vector machines,SVM)是一种二分类模型,它将实例的特征向量映射为空间中的一些点,SVM 的目的就是想要画出一条线,以 “最好地” 区分这两类点,以至如果以后有了新的点,这条线也能做出很好的分类。SVM 适合中小型数据样本、非线性、高维的分类问题。
SVM 最早是由 Vladimir N. Vapnik 和 Alexey Ya. Chervonenkis 在1963年提出,目前的版本(soft margin)是由 Corinna Cortes 和 Vapnik 在1993年提出,并在1995年发表。深度学习(2012)出现之前,SVM 被认为机器学习中近十几年来最成功,表现最好的算法。
二、算法原理
-
超平面(Hyperplane)
- 在二维空间中,超平面是一条直线;在三维空间中是一个平面;在更高维空间中,则是一个维度比特征空间少一维的线性子空间。
- 超平面的数学表达式为:

其中,w 是超平面的法向量,决定了超平面的方向;b 是截距,决定了超平面的位置
2. 支持向量(Support Vectors)
- 距离超平面最近的那些数据点,决定了超平面的位置,被称为 “支持向量”。
- 超平面与支持向量之间的距离称为间隔(Margin),间隔越大,分类器的泛化能力越强。
3. 最大间隔超平面
支持向量机的目标是找到一个超平面,使得两个类别之间的间隔最大化。这个间隔被称为“间隔”,它是两个类别中距离超平面最近的数据点到超平面的距离之和。
4.硬间隔分类和软间隔分类
若严格地规定所有的样本点都不在“缓冲区”,都正确的在两边,称为硬间隔分类; 但是在一般情况下,不易实现,这里有两个问题:
第一,它只对线性可分的数据起作用。第二,有异常值的干扰。
为了避免这些问题,可使用软间隔分类:在保持“缓冲区”尽可能大和避免间隔违规之间找到一个良好的平衡,在sklearn中的SVM类,可以使用超参数 C(惩罚系数),控制了模型的复杂度和容错能力。较小的C值会导致容错能力较高(即更宽的缓冲区),可能会产生更多的错误分类(即间隔违规);较大的C值会导致容错能力较低,可能会产生更少的错误分类。
5.核函数
核函数是特征转换函数,它可以将数据映射到高维特征空间中,从而更好地处理非线性关系。
核函数的作用是通过计算两个样本之间的相似度(内积)来替代显式地进行特征映射,从而避免了高维空间的计算开销。
在SVM中,核函数的选择非常重要,它决定了模型能够学习的函数空间。常见的核函数包括:
线性核函数(Linear Kernel):最简单的核函数,它在原始特征空间中直接计算内积,适用于线性可分的情况。K(X,y) = (X^T) * y
多项式核函数(Polynomial Kernel):通过多项式函数将数据映射到高维空间,可以处理一定程度的非线性关系。(可拟合出复杂的分割超平面,但可选参数太多,阶数高后计算困难,不稳定) K(X,y) = ( (X^T) * y + c ) ^ d , 其中 c 为常数,d 为多项式的阶数。
高斯核函数(Gaussian Kernel):也称为径向基函数(Radial Basis Function,RBF),通过高斯分布将数据映射到无穷维的特征空间,可以处理更复杂的非线性关系。形式为 K(x,y) = exp( -|| x-y || ^2 / (2 σ ^2) ) 。
|| x - y || 表示向量 x 和 y 之间的欧氏距离,即它们各个维度差值的平方和的平方根。
σ 是高斯核函数的参数,控制了样本之间相似度的衰减速度。σ 越小,样本之间的相似度下降得越快;σ 越大,样本之间的相似度下降得越慢。
sigmoid核函数(Sigmoid Kernel):通过sigmoid函数将数据映射到高维空间,适用于二分类问题。 σ(x) = 1 / (1 + exp(-x))
6.算法与核函数的选择
假设特征数为N,训练数据集的样本个数为W,可按如下规则选择算法:
若N相对W较大,使用逻辑回归或线性核函数的SVM算法
若N较小,W中等大小(W为N的十倍左右),可使用高斯核函数的SVM算法
若N较小,W较大(W为N的五十倍以上),可以使用多项式核函数、高斯核函数的SVM算法
总之 ,数据大的问题,选择复杂一些的模型,反之,选择简单模型。
7.分类与回归的选择
通常情况下,当标签值是离散型变量时,我们将问题视为分类问题,而当标签值是连续性变量时,我们将问题视为回归问题。在支持向量机(SVM)算法中,SVC用于分类,SVR用来做回归
8.算法步骤
-
数据预处理:将数据集划分为训练集和测试集,并进行特征缩放(对数据进行标准化)。
-
构建模型:选择合适的核函数和惩罚系数,构建SVM模型。
-
训练模型:使用训练集对模型进行训练,通过最大化间隔来找到最优的超平面。
-
预测:使用训练好的模型对测试集进行预测。
三、支持向量机的算法实现
使用SVMs建立自己的垃圾邮件过滤器。首先需要将每个邮件x变成一个n维的特征向量,并训练一个分类器来分类给定的电子邮件x是否属于垃圾邮件(y=1)或者非垃圾邮件(y=0)。
数据集:emailSample1.txt, vocab.txt, spamTrain.mat, spamTest.mat
源代码:
email_features.py
import numpy as np
def email_features(word_indices, vocab_size=1899):
features = np.zeros(vocab_size)
for idx in word_indices:
if 1 <= idx <= vocab_size:
features[idx - 1] = 1
return features
process_email.py
(将一封邮件的原始文本内容,处理成一个词索引列表(用于后续特征向量构建))
import re
from nltk.stem import PorterStemmer
def read_file(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return f.read()
def load_vocab(vocab_path='vocab.txt'):
vocab = {}
with open(vocab_path, 'r') as f:
for line in f:
index, word = line.strip().split()
vocab[word] = int(index)
return vocab
def process_email(file_path):
content = read_file(file_path)
content = content.lower()
content = re.sub(r'<[^<>]+>', ' ', content)
content = re.sub(r'[0-9]+', 'number', content)
content = re.sub(r'(http|https)://[^\s]*', 'httpaddr', content)
content = re.sub(r'[^\s]+@[^\s]+', 'emailaddr', content)
content = re.sub(r'[$]+', 'dollar', content)
content = re.sub(r'[^a-zA-Z0-9]', ' ', content)
words = content.split()
stemmer = PorterStemmer()
vocab = load_vocab()
word_indices = []
for word in words:
word = stemmer.stem(word)
if word in vocab:
word_indices.append(vocab[word])
return word_indicesm
main.py
import scipy.io
from sklearn import svm
from sklearn.metrics import accuracy_score
from process_email import process_email
from email_features import email_features
# 加载训练数据
data = scipy.io.loadmat('spamTrain.mat')
X = data['X']
y = data['y'].ravel()
# 训练线性SVM
clf = svm.SVC(C=0.1, kernel='linear')
clf.fit(X, y)
# 在测试集上评估性能
test_data = scipy.io.loadmat('spamTest.mat')
Xtest = test_data['Xtest']
ytest = test_data['ytest'].ravel()
preds = clf.predict(Xtest)
print(f"Test Accuracy: {accuracy_score(ytest, preds) * 100:.2f}%")
# 示例邮件预测
word_indices = process_email('emailSample1.txt')
features = email_features(word_indices)
prediction = clf.predict([features])
print("Prediction for emailSample1.txt:")
print("Spam" if prediction[0] == 1 else "Not Spam")c
测试结果

四、总结
支持向量机是一种监督学习算法,广泛应用于分类和回归任务。SVM的核心思想是寻找一个超平面,使得两个类别之间的间隔最大化,从而实现良好的分类效果。SVM有分类效果好,鲁棒性较好,泛化能力强,可解释性强,同时也有对大规模训练样本难以实施,核函数选择重要,对非线性问题处理能力有限的局限性。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)