//---------------------------------------------


        #region Public Methods

        /// <summary>Computes the Principal Component Analysis algorithm.</summary>
        public void Compute()
        {
            // Create a copy of the original matrix to work upon
            Matrix matrix = this.m_sourceMatrix.Clone();

            // Calculate common measures to speedup other calculations
            this.m_mean   = Tools.Mean(matrix);
            this.m_stdDev = Tools.StandardDeviation(matrix, m_mean);


            // Normalize the data
            if (this.Center)
            {
                Statistics.Tools.Center(matrix, m_mean);
            }
            if (this.Standardize)
            {
                Statistics.Tools.Standardize(matrix, m_stdDev);
            }


            if (Method == AnalysisMethod.SingularDefault || Method == AnalysisMethod.SingularStandard)
            {
                // Perform the Singular Value Decomposition (SVD) of the standardized matrix
                SingularValueDecomposition singularDecomposition = new SingularValueDecomposition(matrix);
                this.m_singularValues = new Vector(singularDecomposition.Diagonal);


                // Eigen values are the square of the singular values
                this.m_eigenValues = Vector.Pow(this.m_singularValues, 2);


                /* The principal components of 'sourceMatrix' are the eigenvectors of Cov(sourceMatrix). If we
                 * calculate the SVD of 'matrix' (which is sourceMatrix standardized), the columns of matrix V
                 * (right side of SVD) are the principal components of sourceMatrix.  */

                // The right singular vectors contains the principal components of the data matrix
                this.m_eigenVectors = singularDecomposition.RightSingularVectors;

                // The left singulare vectors contains the scores of the principal components
            }
            else
            {
                // Generate covariance matrix
                //  (if data has already been standardized, this will be the correlation matrix)
                Matrix covarianceMatrix = Statistics.Tools.Covariance(matrix, m_mean);

                // Perform the Eigen Value Decomposition (EVD) of the covariance (or correlation) matrix
                EigenValueDecomposition eigenDecomposition = new EigenValueDecomposition(covarianceMatrix);
                this.m_eigenValues  = eigenDecomposition.RealEigenValues;
                this.m_eigenVectors = eigenDecomposition.EigenVectors;

                // Now we have to sort EigenValues and EigenVectors in descending order of Eigen Values,
                //  from left to right. (Higher eigenvalues <----> Lower eigenvalues).

                // EigenValueDecomposition already returned its vectors and values in reverse
                //  order, so we just have to reverse our arrays.
                this.m_eigenValues.Reverse();
                this.m_eigenVectors.ReverseColumns();

                // Because Sigular Values have not been computed, create a empty vector
                //  to avoid Null reference exceptions.
                this.m_singularValues = new Vector(m_eigenValues.Length);
            }



            // Calculate proportions and cumulative proportions
            this.m_proportions = this.m_eigenValues * (1.0 / this.m_eigenValues.Sum);

            this.m_cumulativeProportions    = new Vector(this.m_sourceMatrix.Columns);
            this.m_cumulativeProportions[0] = this.m_proportions[0];
            for (int i = 1; i < this.m_cumulativeProportions.Length; i++)
            {
                this.m_cumulativeProportions[i] = this.m_cumulativeProportions[i - 1] + this.m_proportions[i];
            }


            // Creates the object-oriented structure to hold the principal components
            PrincipalComponent[] components = new PrincipalComponent[m_singularValues.Length];
            for (int i = 0; i < components.Length; i++)
            {
                components[i] = new PrincipalComponent(this, i);
            }
            this.m_componentCollection = new PrincipalComponentCollection(components);


            // Calculate the orthogonal projected data matrix (using all available components)
            this.m_resultMatrix = matrix * this.m_eigenVectors;
        }
示例#2
0
        //---------------------------------------------


        #region Public Methods
        /// <summary>Computes the Kernel Principal Component Analysis algorithm.</summary>
        public override void Compute()
        {
            int rows = Source.GetLength(0);
            int cols = Source.GetLength(1);

            // Center (adjust) the source matrix
            sourceCentered = adjust(Source);


            // Create the Gram (Kernel) Matrix
            double[,] K = new double[rows, rows];
            for (int i = 0; i < rows; i++)
            {
                for (int j = i; j < rows; j++)
                {
                    double k = kernel.Kernel(sourceCentered.GetRow(i), sourceCentered.GetRow(j));
                    K[i, j] = k; // Kernel matrix is symmetric
                    K[j, i] = k;
                }
            }


            // Center the Gram (Kernel) Matrix
            if (centerFeatureSpace)
            {
                K = centerKernel(K);
            }


            // Perform the Eigen Value Decomposition (EVD) of the Kernel matrix
            EigenValueDecomposition evd = new EigenValueDecomposition(K);

            // Gets the eigenvalues and corresponding eigenvectors
            double[] evals = evd.RealEigenValues;
            double[,] eigs = evd.EigenVectors;

            // Sort eigen values and vectors in ascending order
            int[] indices = new int[rows];
            for (int i = 0; i < rows; i++)
            {
                indices[i] = i;
            }
            Array.Sort(evals, indices, new AbsoluteComparer(true));
            eigs = eigs.Submatrix(0, rows - 1, indices);


            // Normalize eigenvectors
            if (centerFeatureSpace)
            {
                for (int j = 0; j < rows; j++)
                {
                    double eig = System.Math.Sqrt(System.Math.Abs(evals[j]));
                    for (int i = 0; i < rows; i++)
                    {
                        eigs[i, j] = eigs[i, j] / eig;
                    }
                }
            }


            // Set analysis properties
            this.SingularValues  = new double[rows];
            this.EigenValues     = evals;
            this.ComponentMatrix = eigs;


            // Project the original data into principal component space
            double[,] result = new double[rows, rows];
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    for (int k = 0; k < rows; k++)
                    {
                        result[i, j] += K[i, k] * eigs[k, j];
                    }
                }
            }

            this.Result = result;


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