Lucas带你手撕机器学习——SVM支持向量机

#1024程序员节|征文#

支持向量机(SVM)的详细讲解

什么是SVM?

支持向量机(Support Vector Machine,SVM)是一种用于分类和回归的监督学习算法。它的主要任务是从给定的数据中找到一个最佳的决策边界(超平面),将不同类别的数据分开。通过这个决策边界,SVM能够对新数据进行分类。

好的,让我们进一步深入探讨支持向量机(SVM)的各个方面,包括其工作原理、核函数的详细信息、调优技巧、以及在Sklearn和PyTorch中的更全面的实现示例。

SVM的详细工作原理

1. 数据准备与特征选择

在使用SVM之前,需要准备好数据。数据应该被整理为特征矩阵和目标标签:

  • 特征矩阵(X):每一行代表一个数据样本,每一列代表一个特征。
  • 目标标签(y):对应的标签,指明每个样本的类别。
2. 训练过程

在训练SVM模型时,算法会执行以下步骤:

  • 选择超平面:SVM会尝试不同的超平面,直到找到一个最佳超平面,使得支持向量的间隔最大化。

  • 优化问题:SVM的核心是一个优化问题,目的是最小化一个代价函数:

  • 这确保了所有数据点都被正确分类,并且在超平面与数据点之间保持一定的间隔。

3. 核函数的深入理解

核函数使得SVM能够处理非线性问题。通过使用核函数,SVM可以在低维空间中寻找线性超平面,从而在高维空间中实现非线性分离。常见的核函数包括:

  • 线性核 :简单而高效,适用于线性可分的数据。公式为:

  • 多项式核 :用于多项式关系的数据。公式为:

    其中 (c) 是常数,(d) 是多项式的度数。

  • 径向基函数(RBF)核 :非常流行,适合大多数非线性数据。公式为:

    其中 (\gamma) 控制了高斯分布的宽度。

调优SVM模型

在使用SVM时,有几个关键参数需要调整以获得最佳性能:

  1. C参数

    • C是一个正则化参数,控制着分类器的复杂性。较小的C会导致一个较宽的间隔,可能会在某些训练数据上产生更多的错误分类;而较大的C会尽量减少分类错误,从而可能导致过拟合。
  2. 核函数选择

    • 根据数据的特性选择合适的核函数。对于线性可分数据,使用线性核;对于复杂的非线性数据,考虑使用RBF核。
  3. gamma参数(适用于RBF核)

    • gamma参数控制了单个训练样本的影响范围。较小的gamma会导致决策边界变得平滑,而较大的gamma则会导致决策边界变得复杂。

SVM在Sklearn中的实现

接下来是一个更全面的Sklearn SVM实现示例,包括参数调优的部分:

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn import svm
from sklearn.metrics import classification_report, confusion_matrix

# 加载鸢尾花数据集
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)

# 使用网格搜索进行参数调优
param_grid = {
    'C': [0.1, 1, 10],
    'kernel': ['linear', 'rbf'],  # 使用线性核和RBF核进行比较
    'gamma': [0.1, 1, 10]  # 仅在使用RBF核时考虑
}
grid_search = GridSearchCV(svm.SVC(), param_grid, cv=5)  # 5折交叉验证
grid_search.fit(X_train, y_train)

# 输出最佳参数
print("Best parameters found: ", grid_search.best_params_)

# 使用最佳参数训练模型
best_clf = grid_search.best_estimator_
y_pred = best_clf.predict(X_test)

# 评估模型
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
print("\nClassification Report:")
print(classification_report(y_test, y_pred))

# 绘制结果
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred, s=50, cmap='coolwarm', edgecolor='k')
plt.title('SVM Classification Result with Grid Search')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()

SVM在PyTorch中的实现

在PyTorch中实现SVM通常涉及更底层的操作,下面是一个完整的示例,包括数据加载、模型定义、训练、以及评估:

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 定义SVM模型
class SVM(nn.Module):
    def __init__(self, input_size):
        super(SVM, self).__init__()
        self.linear = nn.Linear(input_size, 1)

    def forward(self, x):
        return self.linear(x)

# 加载数据集
iris = datasets.load_iris()
X = iris.data[:, :2]  # 只取前两个特征
y = iris.target
y[y == 2] = 1  # 将三分类问题简化为二分类问题

# 标准化数据
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 转换为PyTorch张量
X_train_tensor = torch.FloatTensor(X_train)
y_train_tensor = torch.FloatTensor(y_train).view(-1, 1)
X_test_tensor = torch.FloatTensor(X_test)

# 初始化模型、损失函数和优化器
model = SVM(input_size=2)
criterion = nn.MarginRankingLoss(margin=1.0)  # 使用边际排名损失
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
for epoch in range(100):
    model.train()
    optimizer.zero_grad()
    outputs = model(X_train_tensor)
    
    # SVM要求的标签格式
    targets = torch.FloatTensor([[1 if label == 1 else -1] for label in y_train])
    loss = criterion(outputs, torch.zeros_like(outputs), targets)
    loss.backward()
    optimizer.step()

# 预测
model.eval()
with torch.no_grad():
    predictions = model(X_test_tensor)
    y_pred = (predictions.numpy() > 0).astype(int)

# 绘制结果
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred, s=50, cmap='coolwarm', edgecolor='k')
plt.title('SVM Classification Result in PyTorch')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()

# 计算准确率
accuracy = np.mean(y_pred.flatten() == y_test)
print(f'Accuracy: {accuracy * 100:.2f}%')

总结

支持向量机(SVM)是一种非常强大且灵活的分类算法,适用于线性和非线性数据。通过选择适当的核函数、调节参数(如C和gamma),SVM可以在各种应用中表现出色。使用Sklearn提供的简单接口可以快速实现和评估SVM模型,而在PyTorch中,我们能够更细致地控制模型的结构和训练过程。无论是进行简单的分类任务,还是复杂的非线性数据分析,SVM都是一个值得考虑的选择。

相关推荐
Wx120不知道取啥名16 分钟前
C语言之长整型有符号数与短整型有符号数转换
c语言·开发语言·单片机·mcu·算法·1024程序员节
Iareges44 分钟前
美团2025校招 广告算法工程师 面经
算法·面试·求职招聘·笔试·秋招
堇舟2 小时前
斯皮尔曼相关(Spearman correlation)系数
人工智能·算法·机器学习
西几3 小时前
代码训练营 day48|LeetCode 300,LeetCode 674,LeetCode 718
c++·算法·leetcode
liuyang-neu3 小时前
力扣第420周赛 中等 3324. 出现在屏幕上的字符串序列
java·算法·leetcode
yyfhq3 小时前
dcgan
深度学习·机器学习·生成对抗网络
想做白天梦4 小时前
双向链表(数据结构与算法)
java·前端·算法
小卡皮巴拉4 小时前
【力扣刷题实战】相同的树
c语言·算法·leetcode·二叉树·递归
放松吃羊肉4 小时前
【约束优化】一次搞定拉格朗日,对偶问题,弱对偶定理,Slater条件和KKT条件
人工智能·机器学习·支持向量机·对偶问题·约束优化·拉格朗日·kkt
zyhomepage4 小时前
科技的成就(六十四)
开发语言·人工智能·科技·算法·内容运营