static RefineGroup RefineGroup(Trained[,] trained, List<TrainingData> refineData, float pct) { RefineGroup result = new RefineGroup(); result.group = new float[TrainingData.Levels][]; List<EvaluatedData>[] evaluations = Evaluations(trained, refineData); for (int have = 0; have < TrainingData.Levels; have++) { result.group[have] = Refined(evaluations[have], refineData, pct, result, have); } return result; }
static (float cost, float benefit) TestGroup(Trained[,] trained, RefineGroup g, List<TrainingData> testData) { List<EvaluatedData>[] evaluations = Evaluations(trained, testData); float cost = 0; float origCost = 0; float totOk = 0; float okCnt = 0; for (int have = 0; have < TrainingData.Levels; have++) { (float cost, float origCost, float totOk, float okCnt) v = Test(evaluations[have], testData, g.group[have], have); cost += v.cost; origCost += v.origCost; totOk += v.totOk; okCnt = v.okCnt; } return (cost / origCost, totOk / okCnt); }
/// <summary> /// Solver finds best threshold for each of the 6 stop points in order to have the lowest cost for a given pct threshold. /// </summary> /// <param name="trained"></param> /// <param name="refineData"></param> /// <param name="pct"></param> /// <param name="refined"></param> static float[] Refined(List<EvaluatedData> evaluations, List<TrainingData> refineData, float pct, RefineGroup result, int have) { float[] min = new float[TrainingData.Levels]; float[] max = new float[TrainingData.Levels]; for (int i = 0; i < TrainingData.Levels; i++) { min[i] = -10000; max[i] = 10000; } const int divisions = 3; float dist = ((float)max[0] - min[0]) / divisions; float[] best = new float[] { max[0], max[1], max[2], max[3], max[4], max[5] }; object lck = new Object(); float bestcost = float.MaxValue; List<Task> tasks = new List<Task>(); while (dist > .01) { Console.WriteLine($"Refining {have}:{dist}"); float[] current = new float[TrainingData.Levels]; for (current[0] = min[0]; current[0] <= max[0]; current[0] += dist) for (current[1] = min[1]; current[1] <= max[1]; current[1] += have >= 2 ? dist : dist * divisions) for (current[2] = min[2]; current[2] <= max[2]; current[2] += have >= 3 ? dist : dist * divisions) for (current[3] = min[3]; current[3] <= max[3]; current[3] += have >= 4 ? dist : dist * divisions) for (current[4] = min[4]; current[4] <= max[4]; current[4] += have >= 5 ? dist : dist * divisions) for (current[5] = min[5]; current[5] <= max[5]; current[5] += have >= 6 ? dist : dist * divisions) { #if Parallel Task task = Task.Run(() => { #endif float totcost = 0; float totOrigCost = 0; float totok = 0; float okCount = 0; foreach (var ev in evaluations) { bool ok = Score(ev, current, out float cost, out float origCost); totok += ok ? 1 : 0; totcost += cost; totOrigCost += origCost; okCount++; } if (totok / okCount >= pct) { float avecost = totcost / totOrigCost; lock (lck) { if (avecost < bestcost) { bestcost = avecost; best = current; } } } #if Parallel }); tasks.Add(task); if (tasks.Count() > 50) { tasks[0].Wait(); tasks.RemoveAt(0); } #endif } foreach (var t in tasks) t.Wait(); tasks.Clear(); dist = 2 * dist / (divisions); for (int i = 0; i < TrainingData.Levels; i++) { min[i] = current[i] - dist * divisions / 2; max[i] = current[i] + dist * divisions / 2; } } return best; }
static RefineGroupByPct RefineGroupsAll(Trained[,] trained, List<TrainingData> refineData) { RefineGroupByPct results = new RefineGroupByPct(); if (Program.debugState >= 2) { RefineGroup result = null; using (TextReader tr = new StreamReader("refined.csv")) { string line; while (null != (line = tr.ReadLine())) { string[] parts = line.Split(','); if (parts.Length == 1 && float.TryParse(parts[0], out float f)) { result = new RefineGroup(); for (int i = 0; i< TrainingData.Levels; i++) { result.group[i] = new float[TrainingData.Levels]; } results.dict[f] = result; } else { int have = int.Parse(parts[0]); for (int i = 1; i < parts.Length; i++) { float n = float.Parse(parts[i]); result.group[have][i - 1] = n; } } } } return results; } else { for (float f = .999F; f >= .99; f -= 1.001F) { results.dict[f] = RefineGroup(trained, refineData, f); } for (float f = .99F; f >= .90; f -= 1.01F) { results.dict[f] = RefineGroup(trained, refineData, f); } for (float f = .90F; f >= .0; f -= 1.1F) { results.dict[f] = RefineGroup(trained, refineData, f); } using (TextWriter tw = new StreamWriter("refined.csv")) { foreach (var f in results.dict.Keys) { tw.WriteLine($"{f}"); var result = results.dict[f]; for (int have = 0; have < TrainingData.Levels; have++) { tw.Write($"{have}"); var r = result.group[have]; foreach (var n in r) { tw.Write($",{n}"); } tw.WriteLine(); } } } return results; } }