SVM看过很多次了,但是每一次都有收获。
用python实现SVM可以调用很多的包,所以对于SVM的内部实现很多都忽略了,但是用C++来实现SVM就要对SVM有足够的了解,如果希望更加理解SVM,我觉得用C++来实现一下SVM是一个很好的方法。
SVM的原理这里就不多解释了,很多博文都已经解释的很详细了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include<string>
#include<fstream>
#include<sstream>
using std::sort;
using std::fabs;
using namespace std;
const int MAX_DIMENSION = 3;
const int MAX_SAMPLES = 306;
double x[MAX_SAMPLES][MAX_DIMENSION];
double y[MAX_SAMPLES];
double alpha[MAX_SAMPLES];
double w[MAX_DIMENSION];
double b;
double c;
double eps = 1e-6;
int num_samples = 306;
int num_dimension = 3;
struct _E {
double val;
int index;
}E[MAX_SAMPLES];
bool cmp(const _E & a, const _E & b)
{
return a.val < b.val;
}
double max(double a, double b)
{
return a > b ? a : b;
}
double min(double a, double b)
{
return a > b ? b : a;
}
double kernal(double x1[], double x2[], double dimension)
{
double ans = 0;
for (int i = 0; i < dimension; i++)
{
ans += x1[i] * x2[i];
}
return ans;
}
double target_function()
{
double ans = 0;
for (int i = 0; i < num_samples; i++)
{
for (int j = 0; j < num_samples; j++)
{
ans += alpha[i] * alpha[j] * y[i] * y[j] * kernal(x[i], x[j], num_dimension);
}
}
for (int i = 0; i < num_samples; i++)
{
ans -= alpha[i];
}
return ans;
}
double g(double _x[], int dimension)
{
double ans = b;
for (int i = 0; i < num_samples; i++)
{
ans += alpha[i] * y[i] * kernal(x[i], _x, dimension);
}
return ans;
}
bool satisfy_constrains(int i, int dimension)
{
if (alpha[i] == 0)
{
if (y[i] * g(x[i], dimension) >= 1)
return true;
else
return false;
}
else if (alpha[i] > 0 && alpha[i] < c)
{
if (y[i] * g(x[i], dimension) == 1)
return true;
else
return false;
}
else
{
if (y[i] * g(x[i], dimension) <= 1)
return true;
else
return false;
}
}
double calE(int i, int dimension)
{
return g(x[i], dimension) - y[i];
}
void calW()
{
for (int i = 0; i < num_dimension; i++)
{
w[i] = 0;
for (int j = 0; j < num_samples; j++)
{
w[i] += alpha[j] * y[j] * x[j][i];
}
}
return;
}
void calB()
{
double ans = y[0];
for (int i = 0; i < num_samples; i++)
{
ans -= y[i] * alpha[i] * kernal(x[i], x[0], num_dimension);
}
b = ans;
return;
}
void recalB(int alpha1index, int alpha2index, int dimension, double alpha1old, double alpha2old)
{
double alpha1new = alpha[alpha1index];
double alpha2new = alpha[alpha2index];
al