示例#1
0
        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);
        }