// Budujemy drzewo public TreeNode MountTree(List <List <int> > aSystem, List <Atrybut> aAtrybuty) { int decision; if (AllDecisionOne(aSystem, out decision)) { return(new TreeNode("decision: " + Convert.ToString(decision))); } if (aAtrybuty.Count == 0) { return(new TreeNode("decision: " + Convert.ToString(getMostCommonValue(aSystem)))); } this.nNegatives = CountTotalNegatives(aSystem); this.nPositives = aSystem.Count() - this.nNegatives; this.dEntropy = GetEntropy(this.nPositives, this.nNegatives); Atrybut oBestAtri = GetBestAtribute(aSystem, aAtrybuty); TreeNode root = new TreeNode(oBestAtri.ToString()); foreach (int value in oBestAtri.aValues) { TreeNode subroot = root.AddTreeNode(new TreeNode("value: " + Convert.ToString(value))); List <List <int> > aSystemC = new List <List <int> >(); List <Atrybut> aAtrybutyC = new List <Atrybut>(); //zbior obiektow zawierajacy atrybut - bez klonowania ! foreach (List <int> Obj in aSystem) { if (Obj[oBestAtri.nNumerKol] == value) { aSystemC.Add(Obj); } } //atrybuty bez wybranego foreach (Atrybut item in aAtrybuty) { if (item != oBestAtri) { aAtrybutyC.Add(item); } } if (aSystemC.Count == 0) { return(new TreeNode("decision: " + Convert.ToString(getMostCommonValue(aSystemC)))); } else { DecisionTree id3 = new DecisionTree(); TreeNode subtree = id3.MountTree(aSystemC, aAtrybutyC); subroot.AddTreeNode(subtree); } } return(root); }
// Najlepszy atrybut z najlepsza metryka private Atrybut GetBestAtribute(List <List <int> > aSystem, List <Atrybut> aAtrybuty) { double MaxGain = -999.9; // brak Atrybut oBestAtr = null; foreach (Atrybut atrybut in aAtrybuty) { double tmp = GetGain(aSystem, atrybut); if (tmp > MaxGain) { MaxGain = tmp; oBestAtr = atrybut; } } return(oBestAtr); }
private double GetGain(List <List <int> > aSystem, Atrybut atrybut) { double sum = 0.0; int positives, negatives; foreach (int value in atrybut.aValues) { positives = negatives = 0; CountDecAtAtrByVal(aSystem, atrybut, value, out positives, out negatives); double entropy = GetEntropy(positives, negatives); double total = this.nPositives + this.nNegatives; sum += -(double)(positives + negatives) / total * entropy; } return(this.dEntropy + sum); }
// Zwracamy ile jest decyzji pozytywnych ile negatywnych dla obiektu o podanym atrybucie i wartosci private void CountDecAtAtrByVal(List <List <int> > aSystem, Atrybut oAtrybut, int value, out int positives, out int negatives) { positives = negatives = 0; foreach (List <int> Obj in aSystem) { if (Obj[oAtrybut.nNumerKol] == value) { if (Obj.Last() == 0) { negatives++; } else { positives++; } } } return; }