SVM的C++实现以及wine.data–txt的处理分析-以及函数方程的求解过程
资源来自网络,整理不易。咳咳。。
比如入门的了解有:
1、决策面方程
2、函数间隔和几何间隔
3、不等式约束条件
4、SVM最优化模型的数学描述(凸二次规划)
5、引入拉格朗日函数
6、KKT条件的描述
7、目标函数的等高线与约束条件的最优值分析
8、分类讨论约束条件和拉格朗日乘子的组合
9、求解对偶问题
10、引入松弛变量
11、讨论拉格朗乘子的取值意义和其值域
12、SMO算法的思想
13、多元函数推导为二元函数
14、二元函数推导为一元函数
15、求解一元函数的偏导数,推导出第一个拉格朗乘子的递推关系
16、由约束条件,推导出第二个拉格朗乘子的递推关系
17、由支持向量方程,推导出偏置项的递推关系
18、 优化SMO算法—启发式规则下选择两个拉格朗乘子
19、编程实现SMO算法的步骤
20、非线性数据下的数据维度讨论分析
21、核技巧与核函数
22、几个常用的核函数
作者:PrivateEye_zzy
链接:https://www.jianshu.com/p/2716f4028152 来源:简书…
需要注意点是:Wine葡萄酒数据集
Wine葡萄酒数据集是来自UCI上面的公开数据集,这些数据是对意大利同一地区种植的葡萄酒进行化学分析的结果,这些葡萄酒来自三个不同的品种。该分析确定了三种葡萄酒中每种葡萄酒中含有的13种成分的数量。
在wine数据集中,这些数据包括了三种酒中13种不同成分的数量。文件中,每行代表一种酒的样本,共有178个样本;一共有14列,其中,第一个属性是类标识符,分别是1/2/3来表示,代表葡萄酒的三个分类。后面的13列为每个样本的对应属性的样本值。剩余的13个属性是,酒精、苹果酸、灰、灰分的碱度、镁、总酚、黄酮类化合物、非黄烷类酚类、原花色素、颜色强度、色调、稀释葡萄酒的OD280/OD315、脯氨酸。其中第1类有59个样本,第2类有71个样本,第3类有48个样本。
原理不多说。
完整代码如下:
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
SVM的C++实现
#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;
--vital--vital --vital--// --vital-- // --vital--// --vital--// --vital--
int num_samples = 178;
int num_dimension = 32;
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];
alpha[alpha1index] = alpha1old;
alpha[alpha2index] = alpha2old;
double e1 = calE(alpha1index, num_dimension);
double e2 = calE(alpha2index, num_dimension);
alpha[alpha1index] = alpha1new;
alpha[alpha2index] = alpha2new;
double b1new = -e1 - y[alpha1index] * kernal(x[alpha1index], x[alpha1index], dimension)*(alpha1new - alpha1old);
b1new -= y[alpha2index] * kernal(x[alpha2index], x[alpha1index], dimension)*(alpha2new - alpha2old) + b;
double b2new = -e2 - y[alpha1index] * kernal(x[alpha1index], x[alpha2index], dimension)*(alpha1new - alpha1old);
b1new -= y[alpha2index] * kernal(x[alpha2index], x[alpha2index], dimension)*(alpha2new - alpha2old) + b;
b = (b1new + b2new) / 2;
}
bool optimizehelp(int alpha1index, int alpha2index)
{
double alpha1new = alpha[alpha1index];
double alpha2new = alpha[alpha2index];
double alpha1old = alpha[alpha1index];
double alpha2old = alpha[alpha2index];
double H, L;
if (fabs(y[alpha1index] - y[alpha2index]) > eps)
{
L = max(0, alpha2old - alpha1old);
H = min(c, c + alpha2old - alpha1old);
}
else
{
L = max(0, alpha2old + alpha1old - c);
H = min(c, alpha2old + alpha1old);
}
//cal new
double lena = kernal(x[alpha1index], x[alpha1index], num_dimension) + kernal(x[alpha2index], x[alpha2index], num_dimension) - 2 * kernal(x[alpha1index], x[alpha2index], num_dimension);
alpha2new = alpha2old + y[alpha2index] * (calE(alpha1index, num_dimension) - calE(alpha2index, num_dimension)) / lena;
if (alpha2new > H)
{
alpha2new = H;
}
else if (alpha2new < L)
{
alpha2new = L;
}
alpha1new = alpha1old + y[alpha1index] * y[alpha2index] * (alpha2old - alpha2new);
double energyold = target_function();
alpha[alpha1index] = alpha1new;
alpha[alpha2index] = alpha2new;
double gap = 0.001;
recalB(alpha1index, alpha2index, num_dimension, alpha1old, alpha2old);
return true;
}
bool optimize()
{
int alpha1index = -1;
int alpha2index = -1;
double alpha2new = 0;
double alpha1new = 0;
//cal E[]
for (int i = 0; i < num_samples; i++)
{
E[i].val = calE(i, num_dimension);
E[i].index = i;
}
//traverse the alpha1index with 0 < && < c
for (int i = 0; i < num_samples; i++)
{
alpha1new = alpha[i];
if (alpha1new > 0 && alpha1new < c)
{
if (satisfy_constrains(i, num_dimension))
continue;
sort(E, E + num_samples, cmp);
//simply find the maximum or minimun;
if (alpha1new > 0)
{
if (E[0].index == i)
{
;
}
else
{
alpha1index = i;
alpha2index = E[0].index;
if (optimizehelp(alpha1index, alpha2index))
{
return true;
}
}
}
else
{
if (E[num_samples - 1].index == i)
{
;
}
else
{
alpha1index = i;
alpha2index = E[num_samples - 1].index;
if (optimizehelp(alpha1index, alpha2index))
{
return true;
}
}
}
//find the alpha2 > 0 && < c
for (int j = 0; j < num_samples; j++)
{
alpha2new = alpha[j];
if (alpha2new > 0 && alpha2new < c)
{
alpha1index = i;
alpha2index = j;
if (optimizehelp(alpha1index, alpha2index))
{
return true;
}
}
}
//find other alpha2
for (int j = 0; j < num_samples; j++)
{
alpha2new = alpha[j];
if (!(alpha2new > 0 && alpha2new < c))
{
alpha1index = i;
alpha2index = j;
if (optimizehelp(alpha1index, alpha2index))
{
return true;
}
}
}
}
}
//find all alpha1
for (int i = 0; i < num_samples; i++)
{
alpha1new = alpha[i];
if (!(alpha1new > 0 && alpha1new < c))
{
if (satisfy_constrains(i, num_dimension))
continue;
sort(E, E + num_samples, cmp);
//simply find the maximum or minimun;
if (alpha1new > 0)
{
if (E[0].index == i)
{
;
}
else
{
alpha1index = i;
alpha2index = E[0]