⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svm.cs

📁 支持向量机程序,非常有用,可以供大家实验使用,改进.希望能多大家工作有帮助.
💻 CS
📖 第 1 页 / 共 5 页
字号:
				sign[k] = 1;
				sign[k + l] = - 1;
				index[k] = k;
				index[k + l] = k;
				//UPGRADE_WARNING: 在 C# 中,收缩转换可能产生意外的结果。 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1042"'
				QD[k] = (float) kernel_function(k, k);
				QD[k + l] = QD[k];
			}
			buffer = new float[2][];
			for (int i = 0; i < 2; i++)
			{
				buffer[i] = new float[2 * l];
			}
			next_buffer = 0;
		}
		
		//UPGRADE_NOTE: 方法“swap_index”的访问修饰符被更改为“internal”。 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1204"'
		internal override void  swap_index(int i, int j)
		{
			do 
			{
				sbyte _ = sign[i]; sign[i] = sign[j]; sign[j] = _;
			}
			while (false);
			do 
			{
				int _ = index[i]; index[i] = index[j]; index[j] = _;
			}
			while (false);
			do 
			{
				float _ = QD[i]; QD[i] = QD[j]; QD[j] = _;
			}
			while (false);
		}
		
		//UPGRADE_NOTE: 方法“get_Q”的访问修饰符被更改为“internal”。 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1204"'
		internal override float[] get_Q(int i, int len)
		{
			float[][] data = new float[1][];
			int real_i = index[i];
			if (cache.get_data(real_i, data, l) < l)
			{
				for (int j = 0; j < l; j++)
				{
					//UPGRADE_WARNING: 在 C# 中,收缩转换可能产生意外的结果。 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1042"'
					data[0][j] = (float) kernel_function(real_i, j);
				}
			}
			
			// reorder and copy
			float[] buf = buffer[next_buffer];
			next_buffer = 1 - next_buffer;
			sbyte si = sign[i];
			for (int j = 0; j < len; j++)
				buf[j] = si * sign[j] * data[0][index[j]];
			return buf;
		}
		
		//UPGRADE_NOTE: 方法“get_QD”的访问修饰符被更改为“internal”。 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1204"'
		internal override float[] get_QD()
		{
			return QD;
		}
	}
	
	public class svm
	{
		//
		// construct and solve various formulations
		//
		private static void  solve_c_svc(svm_problem prob, svm_parameter param, double[] alpha, Solver.SolutionInfo si, double Cp, double Cn)
		{
			int l = prob.l;
			double[] minus_ones = new double[l];
			sbyte[] y = new sbyte[l];
			
			int i;
			
			for (i = 0; i < l; i++)
			{
				alpha[i] = 0;
				minus_ones[i] = - 1;
				if (prob.y[i] > 0)
					y[i] = (sbyte) (+ 1);
				else
					y[i] = - 1;
			}
			
			Solver s = new Solver();
			s.Solve(l, new SVC_Q(prob, param, y), minus_ones, y, alpha, Cp, Cn, param.eps, si, param.shrinking);
			
			double sum_alpha = 0;
			for (i = 0; i < l; i++)
				sum_alpha += alpha[i];
			
			if (Cp == Cn)
				System.Console.Out.Write("nu = " + sum_alpha / (Cp * prob.l) + "\r\n");
			
			for (i = 0; i < l; i++)
				alpha[i] *= y[i];
		}
		
		private static void  solve_nu_svc(svm_problem prob, svm_parameter param, double[] alpha, Solver.SolutionInfo si)
		{
			int i;
			int l = prob.l;
			double nu = param.nu;
			
			sbyte[] y = new sbyte[l];
			
			for (i = 0; i < l; i++)
				if (prob.y[i] > 0)
					y[i] = (sbyte) (+ 1);
				else
					y[i] = - 1;
			
			double sum_pos = nu * l / 2;
			double sum_neg = nu * l / 2;
			
			for (i = 0; i < l; i++)
				if (y[i] == + 1)
				{
					alpha[i] = System.Math.Min(1.0, sum_pos);
					sum_pos -= alpha[i];
				}
				else
				{
					alpha[i] = System.Math.Min(1.0, sum_neg);
					sum_neg -= alpha[i];
				}
			
			double[] zeros = new double[l];
			
			for (i = 0; i < l; i++)
				zeros[i] = 0;
			
			Solver_NU s = new Solver_NU();
			s.Solve(l, new SVC_Q(prob, param, y), zeros, y, alpha, 1.0, 1.0, param.eps, si, param.shrinking);
			double r = si.r;
			
			System.Console.Out.Write("C = " + 1 / r + "\r\n");
			
			for (i = 0; i < l; i++)
				alpha[i] *= y[i] / r;
			
			si.rho /= r;
			si.obj /= (r * r);
			si.upper_bound_p = 1 / r;
			si.upper_bound_n = 1 / r;
		}
		
		private static void  solve_one_class(svm_problem prob, svm_parameter param, double[] alpha, Solver.SolutionInfo si)
		{
			int l = prob.l;
			double[] zeros = new double[l];
			sbyte[] ones = new sbyte[l];
			int i;
			
			//UPGRADE_WARNING: 在 C# 中,收缩转换可能产生意外的结果。 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1042"'
			int n = (int) (param.nu * prob.l); // # of alpha's at upper bound
			
			for (i = 0; i < n; i++)
				alpha[i] = 1;
			if (n < prob.l)
				alpha[n] = param.nu * prob.l - n;
			for (i = n + 1; i < l; i++)
				alpha[i] = 0;
			
			for (i = 0; i < l; i++)
			{
				zeros[i] = 0;
				ones[i] = 1;
			}
			
			Solver s = new Solver();
			s.Solve(l, new ONE_CLASS_Q(prob, param), zeros, ones, alpha, 1.0, 1.0, param.eps, si, param.shrinking);
		}
		
		private static void  solve_epsilon_svr(svm_problem prob, svm_parameter param, double[] alpha, Solver.SolutionInfo si)
		{
			int l = prob.l;
			double[] alpha2 = new double[2 * l];
			double[] linear_term = new double[2 * l];
			sbyte[] y = new sbyte[2 * l];
			int i;
			
			for (i = 0; i < l; i++)
			{
				alpha2[i] = 0;
				linear_term[i] = param.p - prob.y[i];
				y[i] = 1;
				
				alpha2[i + l] = 0;
				linear_term[i + l] = param.p + prob.y[i];
				y[i + l] = - 1;
			}
			
			Solver s = new Solver();
			s.Solve(2 * l, new SVR_Q(prob, param), linear_term, y, alpha2, param.C, param.C, param.eps, si, param.shrinking);
			
			double sum_alpha = 0;
			for (i = 0; i < l; i++)
			{
				alpha[i] = alpha2[i] - alpha2[i + l];
				sum_alpha += System.Math.Abs(alpha[i]);
			}
			System.Console.Out.Write("nu = " + sum_alpha / (param.C * l) + "\r\n");
		}
		
		private static void  solve_nu_svr(svm_problem prob, svm_parameter param, double[] alpha, Solver.SolutionInfo si)
		{
			int l = prob.l;
			double C = param.C;
			double[] alpha2 = new double[2 * l];
			double[] linear_term = new double[2 * l];
			sbyte[] y = new sbyte[2 * l];
			int i;
			
			double sum = C * param.nu * l / 2;
			for (i = 0; i < l; i++)
			{
				alpha2[i] = alpha2[i + l] = System.Math.Min(sum, C);
				sum -= alpha2[i];
				
				linear_term[i] = - prob.y[i];
				y[i] = 1;
				
				linear_term[i + l] = prob.y[i];
				y[i + l] = - 1;
			}
			
			Solver_NU s = new Solver_NU();
			s.Solve(2 * l, new SVR_Q(prob, param), linear_term, y, alpha2, C, C, param.eps, si, param.shrinking);
			
			System.Console.Out.Write("epsilon = " + (- si.r) + "\r\n");
			
			for (i = 0; i < l; i++)
				alpha[i] = alpha2[i] - alpha2[i + l];
		}
		
		//
		// decision_function
		//
		internal class decision_function
		{
			internal double[] alpha;
			internal double rho;
		}
		
		
		internal static decision_function svm_train_one(svm_problem prob, svm_parameter param, double Cp, double Cn)
		{
			double[] alpha = new double[prob.l];
			Solver.SolutionInfo si = new Solver.SolutionInfo();
			switch (param.svm_type)
			{
				
				case svm_parameter.C_SVC: 
					solve_c_svc(prob, param, alpha, si, Cp, Cn);
					break;
				
				case svm_parameter.NU_SVC: 
					solve_nu_svc(prob, param, alpha, si);
					break;
				
				case svm_parameter.ONE_CLASS: 
					solve_one_class(prob, param, alpha, si);
					break;
				
				case svm_parameter.EPSILON_SVR: 
					solve_epsilon_svr(prob, param, alpha, si);
					break;
				
				case svm_parameter.NU_SVR: 
					solve_nu_svr(prob, param, alpha, si);
					break;
				}
			
			System.Console.Out.Write("obj = " + si.obj + ", rho = " + si.rho + "\r\n");
			
			// output SVs
			
			int nSV = 0;
			int nBSV = 0;
			for (int i = 0; i < prob.l; i++)
			{
				if (System.Math.Abs(alpha[i]) > 0)
				{
					++nSV;
					if (prob.y[i] > 0)
					{
						if (System.Math.Abs(alpha[i]) >= si.upper_bound_p)
							++nBSV;
					}
					else
					{
						if (System.Math.Abs(alpha[i]) >= si.upper_bound_n)
							++nBSV;
					}
				}
			}
			
			System.Console.Out.Write("nSV = " + nSV + ", nBSV = " + nBSV + "\r\n");
			
			decision_function f = new decision_function();
			f.alpha = alpha;
			f.rho = si.rho;
			return f;
		}
		
		// Platt's binary SVM Probablistic Output: an improvement from Lin et al.
		private static void  sigmoid_train(int l, double[] dec_values, double[] labels, double[] probAB)
		{
			double A, B;
			double prior1 = 0, prior0 = 0;
			int i;
			
			for (i = 0; i < l; i++)
				if (labels[i] > 0)
					prior1 += 1;
				else
					prior0 += 1;
			
			int max_iter = 100; // Maximal number of iterations
			double min_step = 1e-10; // Minimal step taken in line search
			double sigma = 1e-3; // For numerically strict PD of Hessian
			double eps = 1e-5;
			double hiTarget = (prior1 + 1.0) / (prior1 + 2.0);
			double loTarget = 1 / (prior0 + 2.0);
			double[] t = new double[l];
			double fApB, p, q, h11, h22, h21, g1, g2, det, dA, dB, gd, stepsize;
			double newA, newB, newf, d1, d2;
			int iter;
			
			// Initial Point and Initial Fun Value
			A = 0.0; B = System.Math.Log((prior0 + 1.0) / (prior1 + 1.0));
			double fval = 0.0;
			
			for (i = 0; i < l; i++)
			{
				if (labels[i] > 0)
					t[i] = hiTarget;
				else
					t[i] = loTarget;
				fApB = dec_values[i] * A + B;
				if (fApB >= 0)
					fval += t[i] * fApB + System.Math.Log(1 + System.Math.Exp(- fApB));
				else
					fval += (t[i] - 1) * fApB + System.Math.Log(1 + System.Math.Exp(fApB));
			}
			for (iter = 0; iter < max_iter; iter++)
			{
				// Update Gradient and Hessian (use H' = H + sigma I)
				h11 = sigma; // numerically ensures strict PD
				h22 = sigma;
				h21 = 0.0; g1 = 0.0; g2 = 0.0;
				for (i = 0; i < l; i++)
				{
					fApB = dec_values[i] * A + B;
					if (fApB >= 0)
					{
						p = System.Math.Exp(- fApB) / (1.0 + System.Math.Exp(- fApB));
						q = 1.0 / (1.0 + System.Math.Exp(- fApB));
					}
					else
					{
						p = 1.0 / (1.0 + System.Math.Exp(fApB));
						q = System.Math.Exp(fApB) / (1.0 + System.Math.Exp(fApB));
					}
					d2 = p * q;
					h11 += dec_values[i] * dec_values[i] * d2;
					h22 += d2;
					h21 += dec_values[i] * d2;
					d1 = t[i] - p;
					g1 += dec_values[i] * d1;
					g2 += d1;
				}
				
				// Stopping Criteria
				if (System.Math.Abs(g1) < eps && System.Math.Abs(g2) < eps)
					break;
				
				// Finding Newton direction: -inv(H') * g
				det = h11 * h22 - h21 * h21;
				dA = (- (h22 * g1 - h21 * g2)) / det;
				dB = (- ((- h21) * g1 + h11 * g2)) / det;
				gd = g1 * dA + g2 * dB;
				
				
				stepsize = 1; // Line Search
				while (stepsize >= min_step)
				{
					newA = A + stepsize * dA;
					newB = B + stepsize * dB;
					
					// New function value
					newf = 0.0;
					for (i = 0; i < l; i++)
					{
						fApB = dec_values[i] * newA + newB;
						if (fApB >= 0)
							newf += t[i] * fApB + System.Math.Log(1 + System.Math.Exp(- fApB));
						else
							newf += (t[i] - 1) * fApB + System.Math.Log(1 + System.Math.Exp(fApB));
					}
					// Check sufficient decrease
					if (newf < fval + 0.0001 * stepsize * gd)
					{
						A = newA; B = newB; fval = newf;
						break;
					}
					else
						stepsize = stepsize / 2.0;
				}
				
				if (stepsize < min_step)
				{
					System.Console.Error.Write("Line search fails in two-class probability estimates\n");
					break;
				}
			}
			
			if (iter >= max_iter)
				System.Console.Error.Write("Reaching maximal iterations in two-class probability estimates\n");
			probAB[0] = A; probAB[1] = B;
		}
		
		private static double sigmoid_predict(double decision_value, double A, double B)
		{
			double fApB = decision_value * A + B;
			if (fApB >= 0)
				return System.Math.Exp(- fApB) / (1.0 + System.Math.Exp(- fApB));
			else
				return 1.0 / (1 + System.Math.Exp(fApB));
		}
		
		// Method 2 from the multiclass_prob paper by Wu, Lin, and Weng
		private static void  multiclass_probability(int k, double[][] r, double[] p)
		{
			int t, j;
			int iter = 0, max_iter = 100;
			double[][] Q = new double[k][];
			for (int i = 0; i < k; i++)
			{
				Q[i] = new double[k];
			}
			double[] Qp = new double[k];
			double pQp, eps = 0.005 / k;
			
			for (t = 0; t < k; t++)
			{
				p[t] = 1.0 / k; // Valid if k = 1
				Q[t][t] = 0;
				for (j = 0; j < t; j++)
				{
					Q[t][t] += r[j][t] * r[j][t];
					Q[t][j] = Q[j][t];
				}
				for (j = t + 1; j < k; j++)
				{
					Q[t][t] += r[j][t] * r[j][t];
					Q[t][j] = (- r[j][t]) * r[t][j];
				}
			}
			for (iter = 0; iter < max_iter; iter++)
			{
				// stopping condition, recalculate QP,pQP for numerical accuracy
				pQp = 0;
				for (t = 0; t < k; t++)
				{
					Qp[t] = 0;
					for (j = 0; j < k; j++)
						Qp[t] += Q[t][j] * p[j];
					pQp += p[t] * Qp[t];
				}
				double max_error = 0;
				for (t = 0; t < k; t++)
				{
					double error = System.Math.Abs(Qp[t] - pQp);
					if (error > max_error)
						max_error = error;
				}
				if (max_error < eps)
					break;
				
				for (t = 0; t < k; t++)
				{
					double diff = (- Qp[t] + pQp) / Q[t][t];
					p[t] += diff;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -