/// <summary>Generate Logistic Regression model based on a set of examples.</summary>
        /// <param name="x">The Matrix to process.</param>
        /// <param name="y">The Vector to process.</param>
        /// <returns>Model.</returns>
        public override IModel Generate(Matrix x, Vector y)
        {
            // create initial theta
            var copy = x.Copy();

            copy = FeatureDimensions.IncreaseDimensions(copy, this.PolynomialFeatures);

            // add intercept term
            copy = copy.Insert(Vector.Ones(copy.Rows), 0, VectorType.Col);

            var theta = Vector.Ones(copy.Cols);

            var run = GradientDescent.Run(
                theta,
                copy,
                y,
                this.MaxIterations,
                this.LearningRate,
                new LogisticCostFunction(),
                this.Lambda,
                new Regularization());

            var model = new LogisticRegressionModel()
            {
                Descriptor         = this.Descriptor, Theta = run.Item2, LogisticFunction = new Logistic(),
                PolynomialFeatures = this.PolynomialFeatures
            };

            return(model);
        }
        /// <summary>
        ///     Create a prediction based on the learned Theta values and the supplied test item.
        /// </summary>
        /// <param name="y">Training record</param>
        /// <returns></returns>
        public override double Predict(Vector y)
        {
            var tempy = this.PolynomialFeatures > 0
                            ? FeatureDimensions.IncreaseDimensions(y, this.PolynomialFeatures)
                            : y;

            tempy = tempy.Insert(0, 1.0);
            return(this.LogisticFunction.Compute((tempy * this.Theta).ToDouble()) >= 0.5 ? 1d : 0d);
        }