/// <summary>
        ///   Learns a model that can map the given inputs to the desired outputs.
        /// </summary>
        ///
        /// <param name="x">The model inputs.</param>
        /// <param name="weights">The weight of importance for each input sample.</param>
        ///
        /// <returns>
        ///   A model that has learned how to produce suitable outputs
        ///   given the input data <paramref name="x" />.
        /// </returns>
        ///
        public MultivariateLinearRegression Learn(double[][] x, double[] weights = null)
        {
            this.NumberOfInputs = x.Columns();

            if (Method == PrincipalComponentMethod.Center || Method == PrincipalComponentMethod.Standardize)
            {
                this.Means = x.Mean(dimension: 0);

                double[][] matrix = Overwrite ? x : Jagged.CreateAs(x);
                x.Subtract(Means, dimension: 0, result: matrix);

                if (Method == PrincipalComponentMethod.Standardize)
                {
                    this.StandardDeviations = x.StandardDeviation(Means);
                    matrix.Divide(StandardDeviations, dimension: 0, result: matrix);
                }

                //  The principal components of 'Source' are the eigenvectors of Cov(Source). Thus if we
                //  calculate the SVD of 'matrix' (which is Source standardized), the columns of matrix V
                //  (right side of SVD) will be the principal components of Source.

                // Perform the Singular Value Decomposition (SVD) of the matrix
                var svd = new JaggedSingularValueDecomposition(matrix,
                                                               computeLeftSingularVectors: false,
                                                               computeRightSingularVectors: true,
                                                               autoTranspose: true, inPlace: true);

                SingularValues = svd.Diagonal;
                Eigenvalues    = SingularValues.Pow(2);
                Eigenvalues.Divide(x.Rows() - 1, result: Eigenvalues);
                ComponentVectors = svd.RightSingularVectors.Transpose();
            }
            else if (Method == PrincipalComponentMethod.CovarianceMatrix ||
                     Method == PrincipalComponentMethod.CorrelationMatrix)
            {
                // We only have the covariance matrix. Compute the Eigenvalue decomposition
                var evd = new JaggedEigenvalueDecomposition(x,
                                                            assumeSymmetric: true, sort: true);

                // Gets the Eigenvalues and corresponding Eigenvectors
                Eigenvalues      = evd.RealEigenvalues;
                SingularValues   = Eigenvalues.Sqrt();
                ComponentVectors = evd.Eigenvectors.Transpose();
            }
            else
            {
                // The method type should have been validated before we even entered this section
                throw new InvalidOperationException("Invalid method, this should never happen: {0}".Format(Method));
            }

            if (Whiten)
            {
                ComponentVectors.Divide(SingularValues, dimension: 1, result: ComponentVectors);
            }

            // Computes additional information about the analysis and creates the
            //  object-oriented structure to hold the principal components found.
            CreateComponents();

            return(CreateRegression());
        }
Esempio n. 2
0
        public MultivariateLinearRegression Learn(double[][] x, double[] weights = null)
        {
            this.NumberOfInputs = x.Columns();

            if (Method == PrincipalComponentMethod.Center || Method == PrincipalComponentMethod.Standardize)
            {
                if (weights == null)
                {
                    this.Means = x.Mean(dimension: 0);

                    double[][] matrix = Overwrite ? x : Jagged.CreateAs(x);
                    x.Subtract(Means, dimension: (VectorType)0, result: matrix);

                    if (Method == PrincipalComponentMethod.Standardize)
                    {
                        this.StandardDeviations = x.StandardDeviation(Means);
                        matrix.Divide(StandardDeviations, dimension: (VectorType)0, result: matrix);
                    }


                    var svd = new JaggedSingularValueDecomposition(matrix,
                                                                   computeLeftSingularVectors: false,
                                                                   computeRightSingularVectors: true,
                                                                   autoTranspose: true, inPlace: true);

                    SingularValues = svd.Diagonal;
                    Eigenvalues    = SingularValues.Pow(2);
                    Eigenvalues.Divide(x.Rows() - 1, result: Eigenvalues);
                    ComponentVectors = svd.RightSingularVectors.Transpose();
                }
                else
                {
                    this.Means = x.WeightedMean(weights: weights);

                    double[][] matrix = Overwrite ? x : Jagged.CreateAs(x);
                    x.Subtract(Means, dimension: (VectorType)0, result: matrix);

                    if (Method == PrincipalComponentMethod.Standardize)
                    {
                        this.StandardDeviations = x.WeightedStandardDeviation(weights, Means);
                        matrix.Divide(StandardDeviations, dimension: (VectorType)0, result: matrix);
                    }

                    double[,] cov = x.WeightedCovariance(weights, Means);


                    var evd = new EigenvalueDecomposition(cov,
                                                          assumeSymmetric: true, sort: true);


                    Eigenvalues      = evd.RealEigenvalues;
                    SingularValues   = Eigenvalues.Sqrt();
                    ComponentVectors = Jagged.Transpose(evd.Eigenvectors);
                }
            }
            else if (Method == PrincipalComponentMethod.CovarianceMatrix ||
                     Method == PrincipalComponentMethod.CorrelationMatrix)
            {
                if (weights != null)
                {
                    throw new Exception();
                }

                var evd = new JaggedEigenvalueDecomposition(x,
                                                            assumeSymmetric: true, sort: true);

                Eigenvalues      = evd.RealEigenvalues;
                SingularValues   = Eigenvalues.Sqrt();
                ComponentVectors = evd.Eigenvectors.Transpose();
            }
            else
            {
                throw new InvalidOperationException("Invalid method, this should never happen: {0}".Format(Method));
            }

            if (Whiten)
            {
                ComponentVectors.Divide(SingularValues, dimension: (VectorType)1, result: ComponentVectors);
            }

            CreateComponents();

            return(CreateRegression());
        }