C++ 语言 实现支持向量机库

C++阿木 发布于 2025-06-14 11 次阅读


C++ 实现支持向量机(SVM)库:原理与代码解析

支持向量机(Support Vector Machine,SVM)是一种强大的机器学习算法,广泛应用于分类和回归问题。SVM通过寻找最优的超平面来最大化分类间隔,从而实现数据的分类。本文将围绕C++语言,实现一个简单的SVM库,并对其原理和代码进行详细解析。

SVM原理

SVM的核心思想是寻找一个最优的超平面,使得所有正类样本和负类样本都尽可能远离这个超平面。具体来说,SVM的目标函数如下:

[ min_{mathbf{w}, b} frac{1}{2} ||mathbf{w}||^2 + C sum_{i=1}^{n} xi_i ]

其中,(mathbf{w})是超平面的法向量,(b)是偏置项,(C)是惩罚参数,(xi_i)是松弛变量。

为了求解上述优化问题,SVM引入了拉格朗日乘子法,将原始问题转化为对偶问题。对偶问题如下:

[ max_{alpha} sum_{i=1}^{n} alpha_i - frac{1}{2} sum_{i,j=1}^{n} alpha_i alpha_j y_i y_j cdot x_i^T x_j ]

其中,(alpha_i)是拉格朗日乘子。

通过求解对偶问题,可以得到最优的(alpha),进而得到最优的(mathbf{w})和(b)。具体求解方法包括:

1. 线性可分情况:使用SMO(Sequential Minimal Optimization)算法求解。
2. 线性不可分情况:使用核技巧将数据映射到高维空间,然后使用线性SVM进行分类。

C++ SVM库实现

以下是一个简单的C++ SVM库实现,包括线性SVM和核SVM。

1. 线性SVM

cpp
include
include
include

class LinearSVM {
private:
std::vector w; // 法向量
double b; // 偏置项
double C; // 惩罚参数

public:
LinearSVM(const std::vector<#std::vector>& X, const std::vector& y, double C)
: C(C) {
// 初始化参数
int n = X.size();
w.resize(n, 0.0);
b = 0.0;

// 使用SMO算法求解
for (int i = 0; i 0) {
// 更新参数
for (int j = 0; j < n; ++j) {
w[j] += y[i] y[j] X[i][j];
}
b += y[i];
}
}
}

// 计算预测值
double predict(const std::vector& x) const {
return dotProduct(x, w) + b;
}

private:
// 计算两个向量的点积
double dotProduct(const std::vector& x, const std::vector& y) const {
double result = 0.0;
for (size_t i = 0; i < x.size(); ++i) {
result += x[i] y[i];
}
return result;
}
};

2. 核SVM

cpp
include
include
include

class KernelSVM {
private:
std::vector w; // 法向量
double b; // 偏置项
double C; // 惩罚参数
double kernel(const std::vector& x1, const std::vector& x2) const {
// 使用高斯核函数
return std::exp(-std::pow(2 std::pow(x1 - x2, 2), 0.5));
}

public:
KernelSVM(const std::vector<#std::vector>& X, const std::vector& y, double C)
: C(C) {
// 初始化参数
int n = X.size();
w.resize(n, 0.0);
b = 0.0;

// 使用SMO算法求解
for (int i = 0; i 0) {
// 更新参数
for (int j = 0; j < n; ++j) {
w[j] += y[i] y[j] kernel(X[i], X[j]);
}
b += y[i];
}
}
}

// 计算预测值
double predict(const std::vector& x) const {
return dotProduct(x, w) + b;
}

private:
// 计算两个向量的点积
double dotProduct(const std::vector& x, const std::vector& y) const {
double result = 0.0;
for (size_t i = 0; i < x.size(); ++i) {
result += x[i] y[i];
}
return result;
}
};

总结

本文介绍了C++语言实现支持向量机(SVM)库的方法。通过实现线性SVM和核SVM,展示了SVM的基本原理和代码实现。在实际应用中,可以根据具体问题选择合适的SVM模型和核函数,以达到最佳的分类效果。