支持向量机(Support Vector Machine,SVM)是一种用于分类和回归分析的机器学习算法。
假设现在有一个二维平面上散落着一些点,这些点分为两类,一类是红色的圆形点,另一类是蓝色的方形点。我们的任务就是找到一条直线,能够把这两类点尽可能准确地分开。支持向量机算法做的事情就和这个类似。
它不是随便找一条能分开两类数据的直线(在高维空间可能是超平面),而是要找到一条特殊的直线。这条直线需要满足离它两边最近的那些点(这些点就叫做支持向量)的距离尽可能远。打个比方,这条直线就像一个 “缓冲带” 的中线,离两边支持向量越远,这个 “缓冲带” 就越宽,这样做的好处是能更好地对数据进行分类,即使有一些新的、之前没看过的数据点出现,也能有较高的分类准确率。
不过现实中的数据往往不是这么简单地分布在二维或三维空间里,很多都是在高维空间中。这时候支持向量机就会利用一些数学技巧,把低维的数据映射到高维空间,在高维空间里找到那个能很好分隔数据的超平面。这就好比我们把一个很难用直线在二维平面上分开的东西,通过一些方式 “升维” 到三维空间,在三维空间里找到一个平面(超平面在三维空间就是平面,在更高维空间就更难直观理解了)来把它们分开。
垃圾邮件分类
手写体识别
情感分析
生物信息学中的蛋白质分类
这个代码示例模拟了一个水果分类系统,使用支持向量机(SVM)根据水果的重量和甜度来区分苹果和橙子。关键部分解释:
这个示例展示了SVM在二分类问题中的应用,通过调整特征和参数可以应用于更复杂的场景。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 模拟生成水果数据集
def generate_fruit_data(n_samples=100, random_state=42):
"""
生成水果分类数据集,特征为重量(克)和甜度(0-10)
参数:
n_samples: 样本数量
random_state: 随机种子,保证结果可重现
返回:
X: 特征矩阵 (重量, 甜度)
y: 标签 (0=苹果, 1=橙子)
"""
np.random.seed(random_state)
# 生成苹果数据 (重量轻,甜度高)
apples_weight = np.random.normal(loc=150, scale=20, size=n_samples // 2)
apples_sweetness = np.random.normal(loc=8, scale=1, size=n_samples // 2)
# 生成橙子数据 (重量重,甜度中等)
oranges_weight = np.random.normal(loc=200, scale=25, size=n_samples // 2)
oranges_sweetness = np.random.normal(loc=6, scale=1.5, size=n_samples // 2)
# 合并数据
X_apples = np.column_stack((apples_weight, apples_sweetness))
X_oranges = np.column_stack((oranges_weight, oranges_sweetness))
X = np.vstack((X_apples, X_oranges))
# 创建标签 (0=苹果, 1=橙子)
y = np.hstack((np.zeros(n_samples // 2), np.ones(n_samples // 2)))
return X, y
# 生成数据集
X, y = generate_fruit_data(n_samples=100)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建SVM分类器
# 使用径向基函数(RBF)作为核函数
# C参数控制正则化强度,值越大对误分类的惩罚越大
clf = svm.SVC(kernel='rbf', C=1.0, gamma='scale')
# 训练模型
clf.fit(X_train, y_train)
# 在测试集上进行预测
y_pred = clf.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率: {
accuracy:.2f}")
# 可视化决策边界和数据点
def plot_decision_boundary(X, y, clf, title):
"""
绘制SVM的决策边界和数据点
参数:
X: 特征矩阵
y: 标签
clf: 训练好的SVM分类器
title: 图表标题
"""
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(10, 6))
# 绘制数据点
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], c='red', marker='o', label='苹果', s=50)
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], c='orange', marker='^', label='橙子', s=50)
# 创建网格来绘制决策边界
h = 0.2 # 网格步长
x_min, x_max = X[:, 0].min() - 10, X[:, 0].max() + 10
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# 预测网格点的类别
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制决策边界和间隔边界
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors='k')
# 标记支持向量
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='k', label='支持向量')
plt.xlabel('重量(克)')
plt.ylabel('甜度(0-10)')
plt.title(title)
plt.legend(loc='upper left')
plt.grid(True)
plt.show()
# 可视化训练集上的决策边界
plot_decision_boundary