/// <summary> /// 对偶形式的学习 /// </summary> /// <param name="data"></param> public void Learn_(PData data) { w = new double[data.J]; // 截距 b 作为 w的第一项 var N = data.matrix.GetLength(0); // 数据量 var gram = PUtil.GetGram(data.matrix); // 数据点输入的对偶内积矩阵 var n = new int[N]; // 每个数据点参与优化的次数 double a = 1; // 步长,hardcode 设置为 1 bool flag = true; while (flag) { flag = false; // 遍历数据点 for (int i = 0; i < N; i++) { var check = PUtil.Check_(data.matrix, i, gram, n, a); while (check < 0) { flag = true; // 本轮进行了优化 n[i] += 1; // 第 i 个数据点参与优化次数增 1 check = PUtil.Check_(data.matrix, i, gram, n, a); } } } // 设置 w 的值 for (int j = 0; j < data.J; j++) { for (int k = 0; k < N; k++) { if (j == 0) { w[j] += n[k] * a * data.matrix[k][data.J - 1]; } else { w[j] += n[k] * a * data.matrix[k][data.J - 1] * data.matrix[k][j - 1]; } } } }
/// <summary> /// 学习 /// </summary> /// <param name="data"></param> public void Learn(PData data) { w = new double[data.J]; var a = 1; // 这里简单起见,hardcode步长 bool flag = true; // 优化标志位,初始化为true while (flag) { flag = false; // 标志位复位 for (int i = 0; i < data.matrix.GetLength(0); i++) { var row = data.matrix[i]; // 一行表示一条数据 var dist = PUtil.CalcDistance(row, w); while (dist <= 0) { flag = true; // 表示进行过优化 PUtil.Calibrate(w, row, a); dist = PUtil.CalcDistance(row, w); } } } }