VS2015运环境下SVM的C++实现以及wine.data--txt的处理分析-以及函数方程的求解过程

本文详细介绍了在VS2015环境中使用C++实现SVM的过程,包括SVM的数学原理、wine.data数据集的处理分析,以及函数方程的求解步骤。通过引入拉格朗日函数、SMO算法等,解析了SVM的优化过程,并提供了数据维度和限制的注意事项。
摘要由CSDN通过智能技术生成

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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海宝7号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值