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都是一个值得考虑的选择。

相关推荐
江畔柳前堤7 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore9 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考10 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX11 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面11 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号12 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽12 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI12 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者14 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者14 小时前
【征程6】校准量化中HistogramObserver解析
算法