private double S1(double x) { var result = 0.0; var h = FindH(x); for (var i = 0; i < _elementsNumber; ++i) { result += 1 / h * _kernel.Calculate((_u[i] - x) / h); } return(result / _elementsNumber); }
/// <summary> /// 計画行列の識別を行う /// </summary> /// <param name="Label_Y"></param> /// <param name="design_Matrix_without_constant"></param> /// <param name="iKernel"></param> /// <param name="variance_Covariance_Matrix"></param> /// <param name="Coefficient_A"></param> /// <param name="design_Matrix_for_Classification"></param> /// <returns></returns> public static double[,] Classification_Design_Matrix(double[,] Label_Y, double[,] design_Matrix_without_constant, IKernel iKernel, double[,] variance_Covariance_Matrix, double[,] Coefficient_A, double[,] design_Matrix_for_Classification) { double[,] classified = new double[design_Matrix_for_Classification.GetLength(0), 1]; //カーネルのセット iKernel.Set_Variance_Covariance_Matrix(variance_Covariance_Matrix); //カーネル用の行列 double[,] Kernel_Matrix = new double[design_Matrix_without_constant.GetLength(0), 1]; //識別したい計画行列を1行ずつ計算する double[,] row_vector; for (int n = 0; n < classified.GetLength(0); n++) { row_vector = Matrix.Pick_Up_Row_Vector(design_Matrix_for_Classification, n); //カーネルを計算する double[,] r_j = new double[1, 1]; for (int j = 0; j < design_Matrix_without_constant.GetLength(0); j++) { r_j = Matrix.Pick_Up_Row_Vector(design_Matrix_without_constant, j); Kernel_Matrix[j, 0] = iKernel.Calculate(row_vector, r_j); } //予測値の計算 //予測値の符号 = Σ( for j ) 教師ラベル[Y]j * 係数[A]j * カーネル K( x , [X]j ) double[,] Hadamard = Matrix.Hadamard_product(Label_Y, Coefficient_A); Hadamard = Matrix.Hadamard_product(Hadamard, Kernel_Matrix); //Σ( for j ) double sum = 0; foreach (double h in Hadamard) { sum += h; } classified[n, 0] = sum; } return(classified); }
private double V1(double x) { var result = 0.0; for (var j = 0; j < _elementsNumber; ++j) { var s1 = 0.0; var s2 = 0.0; foreach (var element in _u) { s1 += 1 / _h * _kernel.Calculate((element - x) / _h); s2 += 1 / _h * _kernel.Calculate((element - _u[j]) / _h); } if (s2 != 0.0) { result += 1 / _h * _kernel.Calculate((_u[j] - x) / _h) * s1 / s2; } } return(result / _elementsNumber); }
/// <summary> /// 行ベクトルの識別を行う . /// Perform row vector identification . /// </summary> /// <param name="labelY"></param> /// <param name="design_Matrix_without_Constant"></param> /// <param name="iKernel"></param> /// <param name="variance_Covariance_Matrix"></param> /// <param name="CoefficientA"></param> /// <param name="rowVector"></param> /// <returns></returns> public static double Classify(double[,] labelY, double[,] design_Matrix_without_Constant, IKernel iKernel, double[,] CoefficientA, double[,] rowVector) { if (rowVector.GetLength(0) > 1) { throw new FormatException(nameof(rowVector) + "(" + rowVector.GetLength(0) + ")" + " must be 1 ."); } //カーネルのセット iKernel.Set_Variance_Covariance_Matrix(DesignMatrix.Variance_Covariance_Matrix(design_Matrix_without_Constant)); //カーネル用の行列 double[,] kernelMatrix = new double[design_Matrix_without_Constant.GetLength(0), 1]; //カーネルを計算する double[,] r_j = new double[1, 1]; for (int j = 0; j < design_Matrix_without_Constant.GetLength(0); j++) { r_j = Matrix.Pick_Up_Row_Vector(design_Matrix_without_Constant, j); kernelMatrix[j, 0] = iKernel.Calculate(rowVector, r_j); } //予測値の計算 //予測値の符号 = Σ( for j ) 教師ラベル[Y]j * 係数[A]j * カーネル K( x , [X]j ) double[,] hadamard = Matrix.Hadamard_product(labelY, CoefficientA); hadamard = Matrix.Hadamard_product(hadamard, kernelMatrix); //Σ( for j ) double sum = 0; foreach (double h in hadamard) { sum += h; } return(sum); }
/// <summary> /// 係数Aを学習する . /// Learn coefficient A . /// </summary> /// <param name="labelY"></param> /// <param name="design_Matrix_without_Constant"></param> /// <param name="iKernel"></param> /// <param name="variance_Covariance_Matrix"></param> /// <returns></returns> public static double[,] Learn(double[,] labelY, double[,] design_Matrix_without_Constant, IKernel iKernel) { //カーネルのセット iKernel.Set_Variance_Covariance_Matrix(DesignMatrix.Variance_Covariance_Matrix(design_Matrix_without_Constant)); //係数の最大値 double Hyper_Parameter_C = 1.0;// Math.Min(1.0, 1.0 / design_Matrix.GetLength(0)); //カーネル行列 double[,] kernel_Matrix = new double[design_Matrix_without_Constant.GetLength(0), design_Matrix_without_Constant.GetLength(0)]; //行ベクトル double[,] r_j = new double[1, design_Matrix_without_Constant.GetLength(1)]; double[,] r_k = new double[1, design_Matrix_without_Constant.GetLength(1)]; //カーネルを計算しておく double k_jk = 0; for (int j = 0; j < design_Matrix_without_Constant.GetLength(0); j++) { r_j = Matrix.Pick_Up_Row_Vector(design_Matrix_without_Constant, j); for (int k = j; k < design_Matrix_without_Constant.GetLength(0); k++) { r_k = Matrix.Pick_Up_Row_Vector(design_Matrix_without_Constant, k); k_jk = iKernel.Calculate(r_j, r_k); kernel_Matrix[j, k] = k_jk; kernel_Matrix[k, j] = k_jk; } } //係数の初期化 double[,] coefficient_Matrix_A = new double[design_Matrix_without_Constant.GetLength(0), 1]; double initial_a = 0.0;// 1.0 / design_Matrix.GetLength(0) / design_Matrix.GetLength(0); for (int j = 0; j < coefficient_Matrix_A.GetLength(0); j++) { coefficient_Matrix_A[j, 0] = initial_a; } //更新用の小数のインスタンス double a_j = 0; double a_k = 0; double predict_j = 0; double predict_k = 0; double min = 0; double max = 0; //学習 //2点のデータを選択する for (int j = 0; j < design_Matrix_without_Constant.GetLength(0); j++) { //計画行列からj行目のベクトルを取り出す r_j = Matrix.Pick_Up_Row_Vector(design_Matrix_without_Constant, j); for (int k = j + 1; k < design_Matrix_without_Constant.GetLength(0); k++) { //計画行列からk行目のベクトルを取り出す r_k = Matrix.Pick_Up_Row_Vector(design_Matrix_without_Constant, k); //ベクトルr_j r_kの予測計算を行う predict_j = 0; for (int j2 = 0; j2 < kernel_Matrix.GetLength(1); j2++) { predict_j += coefficient_Matrix_A[j2, 0] * labelY[j2, 0] * kernel_Matrix[j, j2]; } predict_k = 0; for (int k2 = 0; k2 < kernel_Matrix.GetLength(1); k2++) { predict_k += coefficient_Matrix_A[k2, 0] * labelY[k2, 0] * kernel_Matrix[k, k2]; } //ベクトルk の係数(仮)を計算する a_k = coefficient_Matrix_A[k, 0] + labelY[k, 0] * ( (predict_j - labelY[j, 0]) - (predict_k - labelY[k, 0]) ) / (kernel_Matrix[j, j] + kernel_Matrix[k, k] - 2 * kernel_Matrix[j, k]); //場合分け if (labelY[j, 0] * labelY[k, 0] > 0) { min = Math.Min(Hyper_Parameter_C , coefficient_Matrix_A[j, 0] + coefficient_Matrix_A[k, 0]); max = Math.Max(0 , coefficient_Matrix_A[j, 0] + coefficient_Matrix_A[k, 0] - Hyper_Parameter_C); if (min < coefficient_Matrix_A[k, 0]) { a_k = min; } else if (max < a_k && a_k < min) { //a_k = a_k; } else { a_k = max; } } else { min = Math.Min(Hyper_Parameter_C , Hyper_Parameter_C - coefficient_Matrix_A[j, 0] + coefficient_Matrix_A[k, 0]); max = Math.Max(0 , -coefficient_Matrix_A[j, 0] + coefficient_Matrix_A[k, 0]); if (min < a_k) { a_k = min; } else if (max < a_k && a_k < min) { //a_k = a_k; } else { a_k = max; } } a_j = coefficient_Matrix_A[j, 0] + labelY[j, 0] * labelY[k, 0] * (coefficient_Matrix_A[k, 0] - a_k); //係数の更新 coefficient_Matrix_A[j, 0] = a_j; coefficient_Matrix_A[k, 0] = a_k; } } //学習終わり return(coefficient_Matrix_A); }