| 129 | } |
| 130 | |
| 131 | public void trainC(ClassificationDataSet dataSet, ExecutorService threadPool) |
| 132 | { |
| 133 | /* |
| 134 | * Implementation note: We want all weights to be >= 1, so we will scale all weight values by the smallest weight value |
| 135 | */ |
| 136 | predicting = dataSet.getPredicting(); |
| 137 | hypWeights = new DoubleList(maxIterations); |
| 138 | hypoths = new ArrayList<Classifier>(maxIterations); |
| 139 | |
| 140 | List<DataPointPair<Integer>> dataPoints = dataSet.getAsDPPList(); |
| 141 | //Initialization step, set up the weights so they are all 1 / size of dataset |
| 142 | for(DataPointPair<Integer> dpp : dataPoints) |
| 143 | dpp.getDataPoint().setWeight(1.0);//Scaled, they are all 1 |
| 144 | double scaledBy = dataPoints.size(); |
| 145 | |
| 146 | |
| 147 | //Rather then reclasify points, we just save this list |
| 148 | boolean[] wasCorrect = new boolean[dataPoints.size()]; |
| 149 | |
| 150 | for(int t = 0; t < maxIterations; t++) |
| 151 | { |
| 152 | if(threadPool != null) |
| 153 | weakLearner.trainC(new ClassificationDataSet(dataPoints, predicting), threadPool); |
| 154 | else |
| 155 | weakLearner.trainC(new ClassificationDataSet(dataPoints, predicting)); |
| 156 | |
| 157 | double error = 0.0; |
| 158 | for(int i = 0; i < dataPoints.size(); i++) |
| 159 | if( !(wasCorrect[i] = weakLearner.classify(dataPoints.get(i).getDataPoint()).mostLikely() == dataPoints.get(i).getPair()) ) |
| 160 | error += dataPoints.get(i).getDataPoint().getWeight(); |
| 161 | error /= scaledBy; |
| 162 | if(error > 0.5 || error == 0.0) |
| 163 | return; |
| 164 | |
| 165 | double bt = error /( 1.0 - error ); |
| 166 | |
| 167 | //Update Distribution weights |
| 168 | double Zt = 0.0; |
| 169 | double newScale = scaledBy;//Not scaled |
| 170 | for(int i = 0; i < wasCorrect.length; i++) |
| 171 | { |
| 172 | DataPoint dp = dataPoints.get(i).getDataPoint(); |
| 173 | if(wasCorrect[i])//Put less weight on the points we got correct |
| 174 | { |
| 175 | double w = dp.getWeight()*bt; |
| 176 | dp.setWeight(w); |
| 177 | } |
| 178 | double trueWeight = dp.getWeight()/scaledBy; |
| 179 | if(1.0/trueWeight > newScale) |
| 180 | newScale = 1.0/trueWeight; |
| 181 | Zt += dp.getWeight()/scaledBy;//Sum the values |
| 182 | } |
| 183 | |
| 184 | for(DataPointPair dpp : dataPoints)//Normalize so the weights make a distribution |
| 185 | dpp.getDataPoint().setWeight(dpp.getDataPoint().getWeight()/scaledBy*newScale/Zt); |
| 186 | scaledBy = newScale; |
| 187 | |
| 188 | hypoths.add(weakLearner.clone()); |