/// <summary>
        ///   Runs a single pass of the gradient descent algorithm.
        /// </summary>
        ///
        public double Run(double[] input, double output)
        {
            // Initial definitions and memory allocations
            double[] coefficients = regression.Coefficients;
            this.previous = (double[])coefficients.Clone();


            // 1. Compute local gradient estimate
            double actual = regression.Compute(input);
            double error  = output - actual;

            gradient[0] = error;
            for (int i = 0; i < input.Length; i++)
            {
                gradient[i + 1] = input[i] * error;
            }

            // 2. Update using the local estimate
            for (int i = 0; i < coefficients.Length; i++)
            {
                coefficients[i] += rate * gradient[i];
            }

            // 3. Return maximum parameter change
            for (int i = 0; i < previous.Length; i++)
            {
                deltas[i] = Math.Abs(coefficients[i] - previous[i]) / Math.Abs(previous[i]);
            }

            return(Matrix.Max(deltas));
        }
        private void computeInformation(double[][] inputData, double[] outputData, double[] weights)
        {
            // Store model information
#pragma warning disable 612, 618
            result = regression.Compute(inputData);
#pragma warning restore 612, 618

            if (weights == null)
            {
                this.deviance      = regression.GetDeviance(inputData, outputData);
                this.logLikelihood = regression.GetLogLikelihood(inputData, outputData);
                this.chiSquare     = regression.ChiSquare(inputData, outputData);
            }
            else
            {
                this.deviance      = regression.GetDeviance(inputData, outputData, weights);
                this.logLikelihood = regression.GetLogLikelihood(inputData, outputData, weights);
                this.chiSquare     = regression.ChiSquare(inputData, outputData, weights);
            }

            // Store coefficient information
            for (int i = 0; i < regression.Coefficients.Length; i++)
            {
                this.standardErrors[i] = regression.StandardErrors[i];

                this.waldTests[i]    = regression.GetWaldTest(i);
                this.coefficients[i] = regression.Coefficients[i];
                this.confidences[i]  = regression.GetConfidenceInterval(i);
                this.oddsRatios[i]   = regression.GetOddsRatio(i);
            }
        }
        public void OneVariableLogisticRegressionRegularizedTest(double lambda)
        {
            var revenuePerPopulationFilePath = FileManagerTest.GetTestDataByName("ResultExamsAdmission.txt");
            var reader = new CsvReader <ResultExamsAdmission>();
            var revenuePerPopulationRows = reader.GetData(revenuePerPopulationFilePath, ",");

            var dataMatrix = new Matrix(revenuePerPopulationRows.Select(x => new ResultExamsAdmissionRow(x)));
            var dataY      = dataMatrix.Columns[0].ToMatrix();
            var dataX      = dataMatrix.ToMatrix(new int[2] {
                1, 2
            });

            var logisticRegression           = new LogisticRegression();
            var logisticRegressionParameters = new LogisticRegressionParameters
            {
                IterationCount = 100,
                ThetaInit      = new Matrix(new double[3, 1] {
                    { 0 }, { 0 }, { 0 }
                }),
                X      = dataX,
                Y      = dataY,
                Lambda = lambda
            };

            var output = logisticRegression.Compute(logisticRegressionParameters);

            var expectedOutput = new Matrix(new double[3, 1] {
                { -25.052148050018360 }, { 0.205354461994741 }, { 0.200583555605940 }
            });

            AssertMatrixAreEqual(expectedOutput, output.Theta);
        }
        public void OneVariableLogisticRegressionTest()
        {
            var revenuePerPopulationFilePath = FileManagerTest.GetTestDataByName("ResultExamsAdmission.txt");
            var reader = new CsvReader <ResultExamsAdmission>();
            var revenuePerPopulationRows = reader.GetData(revenuePerPopulationFilePath, ",");

            var dataMatrix = new Matrix(revenuePerPopulationRows.Select(x => new ResultExamsAdmissionRow(x)));
            var dataY      = dataMatrix.Columns[0].ToMatrix();
            var dataX      = dataMatrix.ToMatrix(new int[2] {
                1, 2
            });

            var logisticRegression           = new LogisticRegression();
            var logisticRegressionParameters = new LogisticRegressionParameters
            {
                IterationCount = 100,
                ThetaInit      = new Matrix(new double[3, 1] {
                    { 0 }, { 0 }, { 0 }
                }),
                X = dataX,
                Y = dataY
            };

            var output = logisticRegression.Compute(logisticRegressionParameters);

            var expectedOutput = new Matrix(new double[3, 1] {
                { -25.161333566639530 }, { 0.206231713293983 }, { 0.201471600441963 }
            });

            AssertMatrixAreEqual(expectedOutput, output.Theta);
        }
예제 #5
0
        /// <summary>
        ///   Computes the Logistic Regression Analysis.
        /// </summary>
        /// <remarks>The likelihood surface for the
        ///   logistic regression learning is convex, so there will be only one
        ///   peak. Any local maxima will be also a global maxima.
        /// </remarks>
        /// <param name="limit">
        ///   The difference between two iterations of the regression algorithm
        ///   when the algorithm should stop. If not specified, the value of
        ///   10e-4 will be used. The difference is calculated based on the largest
        ///   absolute parameter change of the regression.
        /// </param>
        /// <param name="maxIterations">
        ///   The maximum number of iterations to be performed by the regression
        ///   algorithm.
        /// </param>
        /// <returns>
        ///   True if the model converged, false otherwise.
        /// </returns>
        ///
        public bool Compute(double limit, int maxIterations)
        {
            double delta;
            int    iteration = 0;

            do // learning iterations until convergence
            {
                delta = regression.Regress(inputData, outputData);
                iteration++;
            } while (delta > limit && iteration < maxIterations);

            // Check if the full model has converged
            bool converged = iteration <= maxIterations;


            // Store model information
            this.result        = regression.Compute(inputData);
            this.deviance      = regression.GetDeviance(inputData, outputData);
            this.logLikelihood = regression.GetLogLikelihood(inputData, outputData);
            this.chiSquare     = regression.ChiSquare(inputData, outputData);

            // Store coefficient information
            for (int i = 0; i < regression.Coefficients.Length; i++)
            {
                this.waldTests[i]      = regression.GetWaldTest(i);
                this.standardErrors[i] = regression.GetStandardError(i);
                this.coefficients[i]   = regression.Coefficients[i];
                this.confidences[i]    = regression.GetConfidenceInterval(i);
                this.oddsRatios[i]     = regression.GetOddsRatio(i);
            }


            // Perform likelihood-ratio tests against diminished nested models
            for (int i = 0; i < inputCount; i++)
            {
                // Create a diminished inner model without the current variable
                double[][]         data  = inputData.RemoveColumn(i);
                LogisticRegression inner = new LogisticRegression(inputCount - 1);

                iteration = 0;

                do // learning iterations until convergence
                {
                    delta = inner.Regress(data, outputData);
                    iteration++;
                } while (delta > limit && iteration < maxIterations);

                double ratio = 2.0 * (logLikelihood - inner.GetLogLikelihood(data, outputData));
                ratioTests[i + 1] = new ChiSquareTest(ratio, 1);
            }



            // Returns true if the full model has converged, false otherwise.
            return(converged);
        }
예제 #6
0
        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("TestLogisticRegression [train corpus file name] [test corpus file name]");
                return;
            }

            double[][] inputs;
            double[]   outputs;

            Console.WriteLine("Loading train corpus...");
            //Load training corpus
            LoadCorpusFromFile(args[0], out inputs, out outputs);

            //Try to normalize output value
            Normalize(outputs);

            Console.WriteLine("Logistic regression...");
            LogisticRegression lr    = new LogisticRegression(inputs[0].Length);
            double             error = lr.Regress(inputs, outputs);

            Console.WriteLine("Parameter list:");
            for (int i = 0; i < lr.Coefficients.Length; i++)
            {
                Console.WriteLine("Coefficient {0}: {1}", i, lr.Coefficients[i]);
            }
            Console.WriteLine("Delta: {0}", error);
            Console.WriteLine();

            //Load test corpus
            Console.WriteLine("Testing regress result:");
            LoadCorpusFromFile(args[1], out inputs, out outputs);
            //Try to normalize output value
            Normalize(outputs);

            for (int i = 0; i < outputs.Length; i++)
            {
                StringBuilder sb     = new StringBuilder();
                double        output = lr.Compute(inputs[i]);
                for (int j = 0; j < inputs[i].Length; j++)
                {
                    sb.Append(inputs[i][j].ToString() + " ");
                }
                sb.Append(outputs[i] + " RV:" + output);
                sb.Append(" Err:" + (output - outputs[i]).ToString());

                Console.WriteLine(sb.ToString());
            }
        }
예제 #7
0
        private void computeInformation()
        {
            // Store model information
            this.result        = regression.Compute(inputData);
            this.deviance      = regression.GetDeviance(inputData, outputData);
            this.logLikelihood = regression.GetLogLikelihood(inputData, outputData);
            this.chiSquare     = regression.ChiSquare(inputData, outputData);

            // Store coefficient information
            for (int i = 0; i < regression.Coefficients.Length; i++)
            {
                this.standardErrors[i] = regression.StandardErrors[i];

                this.waldTests[i]    = regression.GetWaldTest(i);
                this.coefficients[i] = regression.Coefficients[i];
                this.confidences[i]  = regression.GetConfidenceInterval(i);
                this.oddsRatios[i]   = regression.GetOddsRatio(i);
            }
        }
        public void When_Compute_Logistic_Regression()
        {
            double[][] inputs =
            {
                new double[] { 55, 0 },
                new double[] { 28, 0 },
                new double[] { 65, 1 },
                new double[] { 46, 0 },
                new double[] { 86, 1 },
                new double[] { 56, 1 },
                new double[] { 85, 0 },
                new double[] { 33, 0 },
                new double[] { 21, 1 },
                new double[] { 42, 1 }
            };
            double[] outputs =
            {
                0, 0, 0, 1, 1, 1, 0, 0, 0, 1
            };
            var logisticRegression = new LogisticRegression();

            logisticRegression.Regress(inputs, outputs);
            var result         = logisticRegression.Compute(new double[] { 87, 1 });
            var oddsRatio      = logisticRegression.GetOddsRatio();
            var standardErrors = logisticRegression.GetStandardErrors();

            Assert.Equal(0.75143272858390264, result);

            Assert.Equal(0.085627701183141239, oddsRatio[0]);
            Assert.Equal(1.0208597029292656, oddsRatio[1]);
            Assert.Equal(5.8584748981778869, oddsRatio[2]);

            Assert.Equal(2.1590686019476122, standardErrors[0]);
            Assert.Equal(0.0337904223210436, standardErrors[1]);
            Assert.Equal(1.4729903935788495, standardErrors[2]);
        }
예제 #9
0
        public void LargeCoefficientsTest()
        {
            double[,] data =
            {
                { 48, 1, 4.40, 0 },
                { 60, 0, 7.89, 1 },
                { 51, 0, 3.48, 0 },
                { 66, 0, 8.41, 1 },
                { 40, 1, 3.05, 0 },
                { 44, 1, 4.56, 0 },
                { 80, 0, 6.91, 1 },
                { 52, 0, 5.69, 0 },
                { 58, 0, 4.01, 0 },
                { 58, 0, 4.48, 0 },
                { 72, 1, 5.97, 0 },
                { 57, 0, 6.71, 1 },
                { 55, 1, 5.36, 0 },
                { 71, 0, 5.68, 0 },
                { 44, 1, 4.61, 0 },
                { 65, 1, 4.80, 0 },
                { 38, 0, 5.06, 0 },
                { 50, 0, 6.40, 0 },
                { 80, 0, 6.67, 1 },
                { 69, 1, 5.79, 0 },
                { 39, 0, 5.42, 0 },
                { 68, 0, 7.61, 1 },
                { 47, 1, 3.24, 0 },
                { 45, 1, 4.29, 0 },
                { 79, 1, 7.44, 1 },
                { 41, 1, 4.60, 0 },
                { 45, 0, 5.91, 0 },
                { 54, 0, 4.77, 0 },
                { 43, 1, 5.62, 0 },
                { 62, 1, 7.92, 1 },
                { 72, 1, 7.92, 1 },
                { 57, 1, 6.19, 0 },
                { 39, 1, 2.37, 0 },
                { 51, 0, 5.84, 0 },
                { 73, 1, 5.94, 0 },
                { 41, 1, 3.82, 0 },
                { 35, 0, 2.35, 0 },
                { 69, 0, 6.57, 1 },
                { 75, 1, 7.96, 1 },
                { 51, 1, 3.96, 0 },
                { 61, 1, 4.36, 0 },
                { 55, 0, 3.84, 0 },
                { 45, 1, 3.02, 0 },
                { 48, 0, 4.65, 0 },
                { 77, 0, 7.93, 1 },
                { 40, 1, 2.46, 0 },
                { 37, 1, 2.32, 0 },
                { 78, 0, 7.88, 1 },
                { 39, 1, 4.55, 0 },
                { 41, 0, 2.45, 0 },
                { 54, 1, 5.62, 0 },
                { 59, 1, 5.03, 0 },
                { 78, 0, 8.08, 1 },
                { 56, 1, 6.96, 1 },
                { 49, 1, 3.07, 0 },
                { 48, 0, 4.75, 0 },
                { 63, 1, 5.64, 0 },
                { 50, 0, 3.35, 0 },
                { 59, 1, 5.08, 0 },
                { 60, 0, 6.58, 1 },
                { 64, 0, 5.19, 0 },
                { 76, 1, 6.69, 1 },
                { 58, 0, 5.18, 0 },
                { 48, 1, 4.47, 0 },
                { 72, 0, 8.70, 1 },
                { 40, 1, 5.14, 0 },
                { 53, 0, 3.40, 0 },
                { 79, 0, 9.77, 1 },
                { 61, 1, 7.79, 1 },
                { 59, 0, 7.42, 1 },
                { 44, 0, 2.55, 0 },
                { 52, 1, 3.71, 0 },
                { 80, 1, 7.56, 1 },
                { 76, 0, 7.80, 1 },
                { 51, 0, 5.94, 0 },
                { 46, 1, 5.52, 0 },
                { 48, 0, 3.25, 0 },
                { 58, 1, 4.71, 0 },
                { 44, 1, 2.52, 0 },
                { 68, 0, 8.38, 1 },
            };

            double[][] input  = data.Submatrix(null, 0, 2).ToJagged();
            double[]   output = data.GetColumn(3);

            var regression = new LogisticRegression(3);

            var teacher = new IterativeReweightedLeastSquares(regression);

            teacher.Regularization = 1e-10;

            var errors = new List <double>();

            for (int i = 0; i < 1000; i++)
            {
                errors.Add(teacher.Run(input, output));
            }

            double error = 0;

            for (int i = 0; i < output.Length; i++)
            {
                double expected = output[i];
                double actual   = System.Math.Round(regression.Compute(input[i]));

                if (expected != actual)
                {
                    error++;
                }
            }

            error /= output.Length;

            Assert.AreEqual(error, 0);
            Assert.AreEqual(-490.30977151704076, regression.Coefficients[0], 1e-7);
            Assert.AreEqual(1.7763049293456503, regression.Coefficients[1], 1e-7);
            Assert.AreEqual(-14.882619671822592, regression.Coefficients[2], 1e-7);
            Assert.AreEqual(60.5066623676452, regression.Coefficients[3], 1e-7);
        }
예제 #10
0
        public void ComputeTest()
        {
            // Suppose we have the following data about some patients.
            // The first variable is continuous and represent patient
            // age. The second variable is dichotomic and give whether
            // they smoke or not (This is completely fictional data).
            double[][] input =
            {
                new double[] { 55, 0 }, // 0 - no cancer
                new double[] { 28, 0 }, // 0
                new double[] { 65, 1 }, // 0
                new double[] { 46, 0 }, // 1 - have cancer
                new double[] { 86, 1 }, // 1
                new double[] { 56, 1 }, // 1
                new double[] { 85, 0 }, // 0
                new double[] { 33, 0 }, // 0
                new double[] { 21, 1 }, // 0
                new double[] { 42, 1 }, // 1
            };

            // We also know if they have had lung cancer or not, and
            // we would like to know whether smoking has any connection
            // with lung cancer (This is completely fictional data).
            double[] output =
            {
                0, 0, 0, 1, 1, 1, 0, 0, 0, 1
            };



            // To verify this hypothesis, we are going to create a logistic
            // regression model for those two inputs (age and smoking).
            LogisticRegression regression = new LogisticRegression(inputs: 2);

            // Next, we are going to estimate this model. For this, we
            // will use the Iteratively Reweighted Least Squares method.
            var teacher = new IterativeReweightedLeastSquares(regression);

            teacher.Regularization = 0;

            // Now, we will iteratively estimate our model. The Run method returns
            // the maximum relative change in the model parameters and we will use
            // it as the convergence criteria.

            double delta = 0;

            do
            {
                // Perform an iteration
                delta = teacher.Run(input, output);
            } while (delta > 0.001);

            // At this point, we can compute the odds ratio of our variables.
            // In the model, the variable at 0 is always the intercept term,
            // with the other following in the sequence. Index 1 is the age
            // and index 2 is whether the patient smokes or not.

            // For the age variable, we have that individuals with
            //   higher age have 1.021 greater odds of getting lung
            //   cancer controlling for cigarette smoking.
            double ageOdds = regression.GetOddsRatio(1); // 1.0208597028836701

            // For the smoking/non smoking category variable, however, we
            //   have that individuals who smoke have 5.858 greater odds
            //   of developing lung cancer compared to those who do not
            //   smoke, controlling for age (remember, this is completely
            //   fictional and for demonstration purposes only).
            double smokeOdds = regression.GetOddsRatio(2); // 5.8584748789881331

            double[] actual = new double[output.Length];
            for (int i = 0; i < input.Length; i++)
            {
                actual[i] = regression.Compute(input[i]);
            }

            double[] expected =
            {
                0.21044171560168326,
                0.13242527535212373,
                0.65747803433771812,
                0.18122484822324372,
                0.74755661773156912,
                0.61450041841477232,
                0.33116705418194975,
                0.14474110902457912,
                0.43627109657399382,
                0.54419383282533118
            };

            for (int i = 0; i < actual.Length; i++)
            {
                Assert.AreEqual(expected[i], actual[i]);
            }

            Assert.AreEqual(1.0208597028836701, ageOdds, 1e-10);
            Assert.AreEqual(5.8584748789881331, smokeOdds, 1e-8);

            Assert.AreEqual(-2.4577464307294092, regression.Intercept, 1e-8);
            Assert.AreEqual(-2.4577464307294092, regression.Coefficients[0], 1e-8);
            Assert.AreEqual(0.020645118265359252, regression.Coefficients[1], 1e-10);
            Assert.AreEqual(1.7678893101571855, regression.Coefficients[2], 1e-8);

            bool[] actualOutput = regression.Decide(input);
            Assert.IsFalse(actualOutput[0]);
            Assert.IsFalse(actualOutput[1]);
            Assert.IsTrue(actualOutput[2]);
            Assert.IsFalse(actualOutput[3]);
            Assert.IsTrue(actualOutput[4]);
            Assert.IsTrue(actualOutput[5]);
            Assert.IsFalse(actualOutput[6]);
            Assert.IsFalse(actualOutput[7]);
            Assert.IsFalse(actualOutput[8]);
            Assert.IsTrue(actualOutput[9]);
        }
예제 #11
0
 public StrategySignal getPrediction(double[] input)
 {
     return(new StrategySignal(logisticBuy.Compute(input), logisticSell.Compute(input)));
 }
예제 #12
0
        public void LargeCoefficientsTest()
        {
            double[,] data =
            {
                { 48, 1, 4.40, 0 },
                { 60, 0, 7.89, 1 },
                { 51, 0, 3.48, 0 },
                { 66, 0, 8.41, 1 },
                { 40, 1, 3.05, 0 },
                { 44, 1, 4.56, 0 },
                { 80, 0, 6.91, 1 },
                { 52, 0, 5.69, 0 },
                { 58, 0, 4.01, 0 },
                { 58, 0, 4.48, 0 },
                { 72, 1, 5.97, 0 },
                { 57, 0, 6.71, 1 },
                { 55, 1, 5.36, 0 },
                { 71, 0, 5.68, 0 },
                { 44, 1, 4.61, 0 },
                { 65, 1, 4.80, 0 },
                { 38, 0, 5.06, 0 },
                { 50, 0, 6.40, 0 },
                { 80, 0, 6.67, 1 },
                { 69, 1, 5.79, 0 },
                { 39, 0, 5.42, 0 },
                { 68, 0, 7.61, 1 },
                { 47, 1, 3.24, 0 },
                { 45, 1, 4.29, 0 },
                { 79, 1, 7.44, 1 },
                { 41, 1, 4.60, 0 },
                { 45, 0, 5.91, 0 },
                { 54, 0, 4.77, 0 },
                { 43, 1, 5.62, 0 },
                { 62, 1, 7.92, 1 },
                { 72, 1, 7.92, 1 },
                { 57, 1, 6.19, 0 },
                { 39, 1, 2.37, 0 },
                { 51, 0, 5.84, 0 },
                { 73, 1, 5.94, 0 },
                { 41, 1, 3.82, 0 },
                { 35, 0, 2.35, 0 },
                { 69, 0, 6.57, 1 },
                { 75, 1, 7.96, 1 },
                { 51, 1, 3.96, 0 },
                { 61, 1, 4.36, 0 },
                { 55, 0, 3.84, 0 },
                { 45, 1, 3.02, 0 },
                { 48, 0, 4.65, 0 },
                { 77, 0, 7.93, 1 },
                { 40, 1, 2.46, 0 },
                { 37, 1, 2.32, 0 },
                { 78, 0, 7.88, 1 },
                { 39, 1, 4.55, 0 },
                { 41, 0, 2.45, 0 },
                { 54, 1, 5.62, 0 },
                { 59, 1, 5.03, 0 },
                { 78, 0, 8.08, 1 },
                { 56, 1, 6.96, 1 },
                { 49, 1, 3.07, 0 },
                { 48, 0, 4.75, 0 },
                { 63, 1, 5.64, 0 },
                { 50, 0, 3.35, 0 },
                { 59, 1, 5.08, 0 },
                { 60, 0, 6.58, 1 },
                { 64, 0, 5.19, 0 },
                { 76, 1, 6.69, 1 },
                { 58, 0, 5.18, 0 },
                { 48, 1, 4.47, 0 },
                { 72, 0, 8.70, 1 },
                { 40, 1, 5.14, 0 },
                { 53, 0, 3.40, 0 },
                { 79, 0, 9.77, 1 },
                { 61, 1, 7.79, 1 },
                { 59, 0, 7.42, 1 },
                { 44, 0, 2.55, 0 },
                { 52, 1, 3.71, 0 },
                { 80, 1, 7.56, 1 },
                { 76, 0, 7.80, 1 },
                { 51, 0, 5.94, 0 },
                { 46, 1, 5.52, 0 },
                { 48, 0, 3.25, 0 },
                { 58, 1, 4.71, 0 },
                { 44, 1, 2.52, 0 },
                { 68, 0, 8.38, 1 },
            };

            double[][] input  = data.Submatrix(null, 0, 2).ToArray();
            double[]   output = data.GetColumn(3);

            LogisticRegression regression = new LogisticRegression(3);

            var teacher = new IterativeReweightedLeastSquares(regression);

            teacher.Regularization = 1e-5;

            var errors = new List <double>();

            for (int i = 0; i < 1000; i++)
            {
                errors.Add(teacher.Run(input, output));
            }

            double error = 0;

            for (int i = 0; i < output.Length; i++)
            {
                double expected = output[i];
                double actual   = System.Math.Round(regression.Compute(input[i]));

                if (expected != actual)
                {
                    error++;
                }
            }

            error /= output.Length;

            Assert.AreEqual(error, 0);
            Assert.AreEqual(-58.817944701474687, regression.Coefficients[0]);
            Assert.AreEqual(0.13783960821658245, regression.Coefficients[1]);
            Assert.AreEqual(-1.532885090757945, regression.Coefficients[2]);
            Assert.AreEqual(7.9460105648631973, regression.Coefficients[3]);
        }
예제 #13
0
        /// <summary>
        ///   Runs one iteration of the Reweighted Least Squares algorithm.
        /// </summary>
        /// <param name="inputs">The input data.</param>
        /// <param name="outputs">The outputs associated with each input vector.</param>
        /// <returns>The maximum relative change in the parameters after the iteration.</returns>
        ///
        public double Run(double[][] inputs, double[] outputs)
        {
            // Regress using Iteratively Reweighted Least Squares estimation.

            // References:
            //  - Bishop, Christopher M.; Pattern Recognition
            //    and Machine Learning. Springer; 1st ed. 2006.


            // Initial definitions and memory allocations
            int N = inputs.Length;

            double[][] design       = new double[N][];
            double[]   errors       = new double[N];
            double[]   weights      = new double[N];
            double[]   coefficients = this.regression.Coefficients;
            double[]   deltas;

            // Compute the regression matrix
            for (int i = 0; i < inputs.Length; i++)
            {
                double[] row = design[i] = new double[parameterCount];

                row[0] = 1; // for intercept
                for (int j = 0; j < inputs[i].Length; j++)
                {
                    row[j + 1] = inputs[i][j];
                }
            }


            // Compute errors and weighing matrix
            for (int i = 0; i < inputs.Length; i++)
            {
                double y = regression.Compute(inputs[i]);

                // Calculate error vector
                errors[i] = y - outputs[i];

                // Calculate weighting matrix
                weights[i] = y * (1.0 - y);
            }


            // Reset Hessian matrix and gradient
            for (int i = 0; i < gradient.Length; i++)
            {
                gradient[i] = 0;
                for (int j = 0; j < gradient.Length; j++)
                {
                    hessian[i, j] = 0;
                }
            }


            // (Re-) Compute error gradient
            for (int j = 0; j < design.Length; j++)
            {
                for (int i = 0; i < gradient.Length; i++)
                {
                    gradient[i] += design[j][i] * errors[j];
                }
            }

            // (Re-) Compute weighted "Hessian" matrix
            for (int k = 0; k < weights.Length; k++)
            {
                double[] rk = design[k];

                for (int j = 0; j < rk.Length; j++)
                {
                    for (int i = 0; i < rk.Length; i++)
                    {
                        hessian[j, i] += rk[i] * rk[j] * weights[k];
                    }
                }
            }


            // Decompose to solve the linear system. Usually the hessian will
            // be invertible and LU will succeed. However, sometimes the hessian
            // may be singular and a Singular Value Decomposition may be needed.

            LuDecomposition lu = new LuDecomposition(hessian);

            // The SVD is very stable, but is quite expensive, being on average
            // about 10-15 times more expensive than LU decomposition. There are
            // other ways to avoid a singular Hessian. For a very interesting
            // reading on the subject, please see:
            //
            //  - Jeff Gill & Gary King, "What to Do When Your Hessian Is Not Invertible",
            //    Sociological Methods & Research, Vol 33, No. 1, August 2004, 54-87.
            //    Available in: http://gking.harvard.edu/files/help.pdf
            //

            // Moreover, the computation of the inverse is optional, as it will
            // be used only to compute the standard errors of the regression.

            if (lu.Nonsingular)
            {
                // Solve using LU decomposition
                deltas        = lu.Solve(gradient);
                decomposition = lu;
            }
            else
            {
                // Hessian Matrix is singular, try pseudo-inverse solution
                decomposition = new SingularValueDecomposition(hessian);
                deltas        = decomposition.Solve(gradient);
            }

            previous = (double[])coefficients.Clone();

            // Update coefficients using the calculated deltas
            for (int i = 0; i < coefficients.Length; i++)
            {
                coefficients[i] -= deltas[i];
            }


            if (computeStandardErrors)
            {
                // Grab the regression information matrix
                double[,] inverse = decomposition.Inverse();

                // Calculate coefficients' standard errors
                double[] standardErrors = regression.StandardErrors;
                for (int i = 0; i < standardErrors.Length; i++)
                {
                    standardErrors[i] = Math.Sqrt(inverse[i, i]);
                }
            }


            // Return the relative maximum parameter change
            for (int i = 0; i < deltas.Length; i++)
            {
                deltas[i] = Math.Abs(deltas[i]) / Math.Abs(previous[i]);
            }

            return(Matrix.Max(deltas));
        }
예제 #14
0
        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("TestLogisticRegression [train corpus file name] [test corpus file name]");
                return;
            }

            double[][] inputs;
            double[] outputs;

            Console.WriteLine("Loading train corpus...");
            //Load training corpus
            LoadCorpusFromFile(args[0], out inputs, out outputs);

            //Try to normalize output value
            Normalize(outputs);

            Console.WriteLine("Logistic regression...");
            LogisticRegression lr = new LogisticRegression(inputs[0].Length);
            double error = lr.Regress(inputs, outputs);

            Console.WriteLine("Parameter list:");
            for (int i = 0; i < lr.Coefficients.Length; i++)
            {
                Console.WriteLine("Coefficient {0}: {1}", i, lr.Coefficients[i]);
            }
            Console.WriteLine("Delta: {0}", error);
            Console.WriteLine();

            //Load test corpus
            Console.WriteLine("Testing regress result:");
            LoadCorpusFromFile(args[1], out inputs, out outputs);
            //Try to normalize output value
            Normalize(outputs);

            for (int i = 0; i < outputs.Length; i++)
            {
                StringBuilder sb = new StringBuilder();
                double output = lr.Compute(inputs[i]);
                for (int j = 0; j < inputs[i].Length; j++)
                {
                    sb.Append(inputs[i][j].ToString() + " ");
                }
                sb.Append(outputs[i] + " RV:" + output);
                sb.Append(" Err:" + (output - outputs[i]).ToString());

                Console.WriteLine(sb.ToString());
            }
        }
예제 #15
0
 public double[] getPrediction(double[] input)
 {
     return(new double[] { logisticBuy.Compute(input), logisticSell.Compute(input) });
 }