/// <summary> /// Pegesos算法执行器 /// </summary> /// <param name="lambda"></param> /// <param name="T">迭代次数</param> /// <param name="Subgradiant">次梯度函数</param> public void GeneratePegesos(double lambda, int T, SubgradiantFunction Subgradiant) { //随机数相关初始化 arrTrainingSet = trainingSet.ToArray(); random = new UniRandomGenerator(trainingSet.Count); listW = new Vector[10]; //初始化w=0向量 W = new Vector(cntFeatures); //开始迭代 int cntT = 0; for (int t = 1; t <= T; t++) { double eta = 1 / (double)(lambda * t); int randNum = random.GetNext(); Vector X = arrTrainingSet[randNum].Features; Vector v = Subgradiant(W * X, X, arrTrainingSet[randNum].TrueLabel); W = (1 - eta * lambda) * W - eta * v; //记录W的中间值 if (t>=((double)(cntT+1)/(double)10)*T) { listW[cntT] = new Vector(W); cntT++; } } }
/// <summary> /// 读入测试数据 /// </summary> /// <param name="filepath">测试数据文件路径</param> public void ReadTestData(string filepath) { StreamReader sr = new StreamReader(filepath); string line; while ((line = sr.ReadLine()) != null) { /* * 数据格式 * a1,a2,a3,...an,label * 表示一组数据 x=(a1,a2,a3...an) 类标label */ int[] data = line.Split(',').Select<string, int>(x => Convert.ToInt32(x)).ToArray(); Vector features = new Vector(data.Take(data.Length - 1).ToArray<int>()); testSet.Add(new BinaryClassData(features, (int)data[data.Length - 1])); } sr.Close(); }
/// <summary> /// 应用分类器 /// </summary> /// <param name="test">测试数据</param> /// <param name="w"></param> /// <returns>1或-1</returns> public int ApplyClassifier(BinaryClassData test, Vector w) { if (w * test.Features >= 0) return 1; else return -1; }
/// <summary> /// 构造函数 /// </summary> /// <param name="_features">特征</param> /// <param name="_trueLabel">类标</param> public BinaryClassData(Vector _features, int _trueLabel) { features = _features; trueLabel = _trueLabel; }
/// <summary> /// 构造函数 /// </summary> /// <param name="v">向量</param> public Vector(Vector v) { this.value = new double[v.value.Length]; for (int i = 0; i < value.Length; i++) value[i] = v.value[i]; }
/// <summary> /// 向量减法 /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <returns></returns> public static Vector operator -(Vector v1, Vector v2) { Vector result = new Vector(v1); try { for (int i = 0; i < result.value.Length; i++) result.value[i] -= v2.value[i]; } catch { Console.WriteLine("Error at minus"); } return result; }