c语言实现svm算法
时间: 2023-07-24 15:58:23 浏览: 498
在C语言中实现SVM算法需要使用线性代数、数值优化等数学基础知识。以下是一个简单的SVM算法的C语言实现示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_ITER 1000 // 最大迭代次数
#define EPS 0.001 // 精度
// 计算内积
double dot(double *x, double *y, int n)
{
double sum = 0;
for (int i = 0; i < n; i++) {
sum += x[i] * y[i];
}
return sum;
}
// 计算向量的2范数
double norm2(double *x, int n)
{
double sum = 0;
for (int i = 0; i < n; i++) {
sum += x[i] * x[i];
}
return sqrt(sum);
}
// 计算Hinge损失函数
double hinge_loss(double y, double f)
{
double loss = 1 - y * f;
return loss > 0 ? loss : 0;
}
// 计算SVM的梯度
void svm_gradient(double **X, double *y, double *w, double *gradient, int n, int m, double C)
{
for (int i = 0; i < m; i++) {
double f = dot(X[i], w, n);
double loss = hinge_loss(y[i], f);
for (int j = 0; j < n; j++) {
gradient[j] += C * y[i] * X[i][j] * (loss > 0 ? -1 : 0);
}
}
}
// 计算SVM的目标函数值
double svm_objective(double **X, double *y, double *w, int n, int m, double C)
{
double obj = 0;
for (int i = 0; i < m; i++) {
double f = dot(X[i], w, n);
obj += hinge_loss(y[i], f);
}
obj = C * obj / m;
for (int i = 0; i < n; i++) {
obj += w[i] * w[i] / 2;
}
return obj;
}
// 训练SVM模型
void svm_train(double **X, double *y, double *w, int n, int m, double C)
{
double *gradient = (double*)calloc(n, sizeof(double));
for (int iter = 0; iter < MAX_ITER; iter++) {
svm_gradient(X, y, w, gradient, n, m, C);
double step_size = 1.0 / (C * (iter + 1));
for (int i = 0; i < n; i++) {
w[i] -= step_size * gradient[i];
}
double obj = svm_objective(X, y, w, n, m, C);
if (obj < EPS) {
break;
}
}
free(gradient);
}
int main()
{
// 生成样本数据
int m = 100; // 样本数
int n = 10; // 特征数
double **X = (double**)calloc(m, sizeof(double*));
for (int i = 0; i < m; i++) {
X[i] = (double*)calloc(n, sizeof(double));
for (int j = 0; j < n; j++) {
X[i][j] = (double)rand() / RAND_MAX * 2 - 1;
}
}
double *y = (double*)calloc(m, sizeof(double));
for (int i = 0; i < m; i++) {
y[i] = (dot(X[i], X[i], n) < 0.5) ? -1 : 1;
}
// 训练SVM模型
double *w = (double*)calloc(n, sizeof(double));
double C = 1.0;
svm_train(X, y, w, n, m, C);
// 输出模型参数
printf("w: [ ");
for (int i = 0; i < n; i++) {
printf("%lf ", w[i]);
}
printf("]\n");
// 释放内存
for (int i = 0; i < m; i++) {
free(X[i]);
}
free(X);
free(y);
free(w);
return 0;
}
```
在这个示例中,我们使用随机生成的样本数据进行训练,特征数为10,样本数为100。我们采用线性核函数,设置C参数为1。在训练过程中,我们使用梯度下降法来最小化SVM的目标函数。最终输出训练得到的模型参数w。