| 84 | } |
| 85 | |
| 86 | @Override |
| 87 | public void trainC(ClassificationDataSet dataSet, ExecutorService threadPool) |
| 88 | { |
| 89 | predicting = dataSet.getPredicting(); |
| 90 | hypWeights = new DoubleList(maxIterations); |
| 91 | hypoths = new ArrayList<Classifier>(); |
| 92 | /** |
| 93 | * The number of classes we are predicting |
| 94 | */ |
| 95 | int K = predicting.getNumOfCategories(); |
| 96 | double logK = Math.log(K-1.0)/Math.log(2); |
| 97 | |
| 98 | List<DataPointPair<Integer>> dataPoints = dataSet.getAsDPPList(); |
| 99 | //Initialization step, set up the weights so they are all 1 / size of dataset |
| 100 | for(DataPointPair<Integer> dpp : dataPoints) |
| 101 | dpp.getDataPoint().setWeight(1.0);//Scaled, they are all 1 |
| 102 | double sumOfWeights = dataPoints.size(); |
| 103 | |
| 104 | |
| 105 | //Rather then reclasify points, we just save this list |
| 106 | boolean[] wasCorrect = new boolean[dataPoints.size()]; |
| 107 | |
| 108 | for(int t = 0; t < maxIterations; t++) |
| 109 | { |
| 110 | if(threadPool == null || threadPool instanceof FakeExecutor) |
| 111 | weakLearner.trainC(new ClassificationDataSet(dataPoints, predicting)); |
| 112 | else |
| 113 | weakLearner.trainC(new ClassificationDataSet(dataPoints, predicting), threadPool); |
| 114 | |
| 115 | //Error is the same as in AdaBoost.M1 |
| 116 | double error = 0.0; |
| 117 | for(int i = 0; i < dataPoints.size(); i++) |
| 118 | if( !(wasCorrect[i] = weakLearner.classify(dataPoints.get(i).getDataPoint()).mostLikely() == dataPoints.get(i).getPair()) ) |
| 119 | error += dataPoints.get(i).getDataPoint().getWeight(); |
| 120 | error /= sumOfWeights; |
| 121 | if(error >= (1.0-1.0/K) || error == 0.0)///Diference, we only need to be better then random guessing classes |
| 122 | return; |
| 123 | //The main difference - a different error term |
| 124 | double am = Math.log((1.0-error)/error)/Math.log(2) +logK; |
| 125 | |
| 126 | //Update Distribution weights |
| 127 | for(int i = 0; i < wasCorrect.length; i++) |
| 128 | { |
| 129 | DataPoint dp = dataPoints.get(i).getDataPoint(); |
| 130 | if(!wasCorrect[i]) |
| 131 | { |
| 132 | double w = dp.getWeight(); |
| 133 | double newW = w*Math.exp(am); |
| 134 | sumOfWeights += (newW-w); |
| 135 | dp.setWeight(newW); |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | hypoths.add(weakLearner.clone()); |
| 140 | hypWeights.add(am); |
| 141 | } |
| 142 | } |
| 143 | |