在机器学习中,支持向量机(Support Vector Machine, SVM) 是一种用于二元分类的常用算法。SVM 的核心思想是通过找到一个最优的分隔超平面,将样本分为两个不同的类别。与逻辑回归不同,SVM 强调的是“最大化两个类别之间的边界”,这使得它在高维空间中的表现尤其优异。
本篇文章将带你了解 SVM 的基本原理,并通过 C# 实现一个简化的二元分类模型。
什么是支持向量机(SVM)?
SVM 是一种基于几何边界的分类算法。给定一个带有标签的数据集,SVM 会尝试找到一个超平面(线性分类边界)来将数据分隔为不同的类别。为了保证分类效果,SVM 最大化了数据点到分类边界的距离,从而获得分类性能良好的模型。
核心思想
支持向量机的目标是找到一个最优超平面,它不仅能将不同类别的样本分开,还能最大化分类边界的宽度。这种宽度是通过支持向量,即离超平面最近的数据点来确定的。
SVM 的数学公式
对于线性可分数据,SVM 试图找到一个超平面,使得所有样本点满足:
其中:
-
( y_i ) 为样本 ( x_i ) 的标签(-1 或 +1)。
-
( \mathbf{w} ) 是超平面的法向量。
-
( b ) 是偏置。
SVM 的目标就是找到参数 ( \mathbf{w} ) 和 ( b ),使得数据点到超平面的最小距离最大化。
C#实现支持向量机(SVM)
在 C# 中,我们可以通过实现一个简单的线性 SVM 分类器,利用 梯度下降 来优化参数。以下是基于梯度下降的 SVM 实现代码。
C#代码实现
using System; class SVM { private double[] weights; private double bias; private double learningRate; private int iterations; private double lambda; // 正则化参数 // 构造函数 public SVM(double learningRate, int iterations, double lambda) { this.learningRate = learningRate; this.iterations = iterations; this.lambda = lambda; } // 训练 SVM 模型 public void Train(double[,] X, double[] y) { int m = X.GetLength(0); // 样本数量 int n = X.GetLength(1); // 特征数量 // 初始化权重和偏置 weights = new double[n]; bias = 0; // 梯度下降迭代 for (int iter = 0; iter < iterations; iter++) { for (int i = 0; i < m; i++) { double decision = DotProduct(X, weights, i) + bias; // 判断是否满足约束条件 if (y[i] * decision >= 1) { // 样本正确分类,更新权重 for (int j = 0; j < n; j++) { weights[j] -= learningRate * (2 * lambda * weights[j]); } } else { // 样本未正确分类,更新权重和偏置 for (int j = 0; j < n; j++) { weights[j] -= learningRate * (2 * lambda * weights[j] - y[i] * X[i, j]); } bias += learningRate * y[i]; } } } } // 预测函数 public double Predict(double[] X) { double decision = DotProduct(X, weights) + bias; return decision >= 0 ? 1 : -1; } // 计算向量点积 private double DotProduct(double[,] X, double[] weights, int rowIndex) { double sum = 0; int n = X.GetLength(1); for (int i = 0; i < n; i++) { sum += X[rowIndex, i] * weights[i]; } return sum; } // 计算向量点积(简化版) private double DotProduct(double[] X, double[] weights) { double sum = 0; for (int i = 0; i < X.Length; i++) { sum += X[i] * weights[i]; } return sum; } } class Program { static void Main() { // 训练数据(2个特征) double[,] X = { { 1.0, 2.0 }, { 2.0, 3.0 }, { 3.0, 4.0 }, { 4.0, 5.0 } }; // 标签(-1 或 1) double[] y = { -1, -1, 1, 1 }; // 创建 SVM 实例 SVM model = new SVM(learningRate: 0.001, iterations: 1000, lambda: 0.01); // 训练模型 model.Train(X, y); // 预测新样本 double[] newSample = { 2.5, 3.5 }; double prediction = model.Predict(newSample); Console.WriteLine($"预测结果: {(prediction == 1 ? "类别1" : "类别-1")}"); } }
代码解析
-
训练数据:
X
是一个二维数组,包含样本的特征,每行表示一个样本,每列表示一个特征。y
是标签数组,表示每个样本的类别(-1 或 1)。 -
SVM 模型:
-
使用
Train
方法训练 SVM 模型,通过梯度下降法更新权重和偏置参数。 -
Predict
方法用于预测新样本的类别。
-
-
参数解释:
-
learningRate
:学习率,用于控制权重更新的步长。 -
iterations
:训练的迭代次数。 -
lambda
:正则化参数,用于防止过拟合。
-
-
预测:
Predict
方法根据新样本的特征,计算该样本的分类结果。如果计算的决策值decision
大于等于 0,则返回类别1
,否则返回-1
。
运行结果
假设训练数据中的样本分为两类(-1 和 1),在完成训练后,我们对一个新样本 { 2.5, 3.5 }
进行预测。程序将输出:
预测结果: 类别1
总结
通过本文的 C# 实现,我们了解了如何使用支持向量机 (SVM) 进行二元分类。SVM 算法通过最大化边界间隔,提供了一个强大且稳健的分类方式。其应用场景十分广泛,尤其适用于高维数据的分类任务。在实际项目中,我们可以使用 C# 来实现 SVM 算法,进行各类数据的二元分类。
标签:SVM,分类,C#,double,样本,int,weights,向量 From: https://www.cnblogs.com/forges/p/18573848