public void WeightedRandomSampler_Sample_Weight_10() { var sut = new WeightedRandomSampler(); var indices = Enumerable.Range(0, 10).ToArray(); var weights = new double[] { 1, 1, 1, 1, 1, 10, 10, 10, 10, 10 }; var actual = new int[indices.Length]; sut.Sample(indices, weights, actual); var expected = new int[] { 2, 5, 6, 7, 7, 8, 8, 8, 9, 9 }; CollectionAssert.AreEqual(expected, actual); }
bool Boost(F64Matrix observations, double[] targets, int[] indices, int iteration) { m_sampler.Sample(indices, m_sampleWeights, m_sampleIndices); var model = m_modelLearner.Learn(observations, targets, m_sampleIndices); // weighted sampling is used instead of weights in training var predictions = model.Predict(observations, indices); for (int i = 0; i < predictions.Length; i++) { var index = indices[i]; m_workErrors[index] = Math.Abs(m_indexedTargets[i] - predictions[i]); } var maxError = m_workErrors.Max(); for (int i = 0; i < m_workErrors.Length; i++) { var error = m_workErrors[i]; if (maxError != 0.0) { error = error / maxError; } switch (m_loss) { case AdaBoostRegressionLoss.Linear: break; case AdaBoostRegressionLoss.Squared: error = error * error; break; case AdaBoostRegressionLoss.Exponential: error = 1.0 - Math.Exp(-error); break; default: throw new ArgumentException("Unsupported loss type"); } m_workErrors[i] = error; } var modelError = m_workErrors.WeightedMean(m_sampleWeights, indices); if (modelError <= 0.0) { m_modelErrors.Add(0.0); m_modelWeights.Add(1.0); m_models.Add(model); return(true); } else if (modelError >= 0.5) { return(false); } var beta = modelError / (1.0 - modelError); var modelWeight = m_learningRate * Math.Log(1.0 / beta); // Only boost if not last iteration if (iteration != m_iterations - 1) { for (int i = 0; i < indices.Length; i++) { var index = indices[i]; var sampleWeight = m_sampleWeights[index]; var error = m_workErrors[index]; m_sampleWeights[index] = sampleWeight * Math.Pow(beta, (1.0 - error) * m_learningRate); } } m_modelErrors.Add(modelError); m_modelWeights.Add(modelWeight); m_models.Add(model); return(true); }