private static SplitInfo GetSplitInfo(double[][] dataX, int[] dataY, List <int> rows, int numClasses) { //учитывая набор родительских строк, найдите столбец и значение, а также меньшие и большие строки раздела, //который дает наименьшее результирующее среднее значение примеси или энтропии int nCols = dataX[0].Length; SplitInfo result = new SplitInfo(); int bestSplitCol = 0; double bestSplitVal = 0.0; double bestImpurity = double.MaxValue; List <int> bestLessRows = new List <int>(); List <int> bestGreaterRows = new List <int>(); // actually >= foreach (int i in rows) // traverse the specified rows of the ref data { for (int j = 0; j < nCols; ++j) { double splitVal = dataX[i][j]; // curr value to evaluate as possible best split value List <int> lessRows = new List <int>(); List <int> greaterRows = new List <int>(); foreach (int ii in rows) // walk down curr column { if (dataX[ii][j] < splitVal) { lessRows.Add(ii); } else { greaterRows.Add(ii); } } // ii double meanImp = MeanImpurity(dataY, lessRows, greaterRows, numClasses); if (meanImp < bestImpurity) { bestImpurity = meanImp; bestSplitCol = j; bestSplitVal = splitVal; bestLessRows = new List <int>(lessRows); // could use a CopyOf() helper bestGreaterRows = new List <int>(greaterRows); } } // j } // i result.SplitCol = bestSplitCol; result.SplitVal = bestSplitVal; result.LessRows = new List <int>(bestLessRows); result.GreaterRows = new List <int>(bestGreaterRows); return(result); }
public void BuildTree(double[][] dataX, int[] dataY) { // prep the list and the root node int n = dataX.Length; List <int> allRows = new List <int>(); for (int i = 0; i < n; ++i) { allRows.Add(i); } Nodes[0].Rows = new List <int>(allRows); //асайним к нулевому узлу все исходные строки for (int i = 0; i < NumNodes; ++i) // проходимся по каждому узлу { Nodes[i].NodeID = i; //генерим узел SplitInfo si = GetSplitInfo(dataX, dataY, Nodes[i].Rows, NumClasses); // ??? Nodes[i].SplitCol = si.SplitCol; Nodes[i].SplitVal = si.SplitVal; Nodes[i].ClassCounts = ComputeClassCts(dataY, Nodes[i].Rows, NumClasses); // ??? Nodes[i].PredictedClass = ArgMax(Nodes[i].ClassCounts); // ??? int leftChild = (2 * i) + 1; //установка левого и правого узлов int rightChild = (2 * i) + 2; if (leftChild < NumNodes) { Nodes[leftChild].Rows = new List <int>(si.LessRows); } if (rightChild < NumNodes) { Nodes[rightChild].Rows = new List <int>(si.GreaterRows); } } }