Exemplo n.º 1
0
        public static PCAResults PCA(String csvPath, int numberOfFactors)
        {
            try
            {
                REngine engine;
                //init the R engine
                engine = getInststance();

                csvPath = csvPath.Replace('\\', '/');

                //executing script
                if (numberOfFactors > 0)
                {
                    engine.Evaluate("library(psych)\n" +
                                    "data <- read.csv('" + csvPath + "', sep = ';')\n" +
                                    "pca <- principal(data, " + numberOfFactors + ", rotate='varimax')\n" +
                                    "pcaTable <- as.data.frame.matrix(rbind(pca$values, pca$values/sum(pca$values)*100, cumsum(pca$values), cumsum(pca$values/sum(pca$values)*100)))\n" +
                                    "loadings <- as.data.frame.matrix(t(pca$loadings))");
                }
                else
                {
                    engine.Evaluate("library(psych)\n" +
                                    "data <- read.csv('" + csvPath + "', sep = ';')\n" +
                                    "pca <- principal(data, rotate='varimax')\n" +
                                    "pcaTable <- as.data.frame.matrix(rbind(pca$values, pca$values/sum(pca$values)*100, cumsum(pca$values), cumsum(pca$values/sum(pca$values)*100)))\n" +
                                    "loadings <- as.data.frame.matrix(t(pca$loadings))");
                }

                PCAResults pCAResults = new PCAResults();
                pCAResults.pcaTable = engine.GetSymbol("pcaTable").AsDataFrame();
                pCAResults.loadings = engine.GetSymbol("loadings").AsDataFrame();

                Clear();
                return(pCAResults);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
                return(null);
            }
        }
Exemplo n.º 2
0
 private void buttonRunACP_Click(object sender, EventArgs e)
 {
     using (var form = new ACPForm(viewModel.getNumberOfQuestions()))
     {
         form.PropertyChanged += this.viewModel.Parallel;
         var result = form.ShowDialog();
         if (result == DialogResult.OK)
         {
             PCAResults results = this.viewModel.ACP(form.viewModel.factorNumber);
             if (results != null)
             {
                 dataGridPrincipalComponents.DataSource = DataTableManager.PCATableToDataTable(results.pcaTable);
                 dataGridPCALoadings.DataSource         = DataTableManager.PCALoadingstoDataTable(results.loadings);
             }
             else
             {
                 MessageBox.Show("An error has been occured or number of chosen factors is more than the number of questions", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
             }
             factorisationResults.Visible = true;
         }
     }
 }
        /// <summary>
        /// Calculates a matrix which transforms a set of signals to a the principal components of those signals.
        /// </summary>
        /// <param name="channels"></param>
        /// <param name="length"></param>
        /// <returns>Returns a matrix which transforms the channels (after being normalized) into the principal components</returns>
        public static PCAResults CalculateMatrix(double[][] channels, int length)
        {
            var result = new PCAResults();

            // Initilize Matrix and copy channels.
            double[][] matrix    = new double[channels.Length][];
            double[][] channels2 = new double[channels.Length][];

            for (int i = 0; i < channels.Length; i++)
            {
                matrix[i]    = new double[channels.Length];
                channels2[i] = channels[i].ToArray();
            }

            double[] sdSumByComponent = new double[channels.Length + 1]; // We add an extra "null component" to make our following code easier.

            // Iterate to calculate it.
            for (int componentIndex = 0; componentIndex < channels.Length; componentIndex++)
            {
                var p = InternalCalculateP(channels2, length);
                matrix[componentIndex] = p.ToArray();

                // Subtract the current component from the data.

                double[] channelMeans = (from currentChannel in channels2 select currentChannel.Average()).ToArray();
                double[] channelSDs   = new double[channels.Length];

                for (int channelIndex = 0; channelIndex < channels.Length; channelIndex++)
                {
                    channelSDs[channelIndex] = Math.Pow((from sample in channels2[channelIndex] select Math.Pow((sample - channelMeans[channelIndex]), 2.0)).Average(), 0.5);
                }

                sdSumByComponent[componentIndex] = (from x in channelSDs select x * x).Sum();

                result.MeansByStage.Add(channelMeans.ToArray());
                result.StandardDeviationByStage.Add(channelSDs.ToArray());

                for (int sampleIndex = 0; sampleIndex < length; sampleIndex++)
                {
                    double dotProduct = 0.0;

                    for (int channelIndex = 0; channelIndex < channels.Length; channelIndex++)
                    {
                        var channel = channels2[channelIndex];

                        double sample = channel[sampleIndex];

                        // Normalize sample.
                        var sample_n = (sample - channelMeans[channelIndex]) / channelSDs[channelIndex];

                        dotProduct += sample_n * p[channelIndex];

                        channel[sampleIndex] = sample;
                    }

                    for (int channelIndex = 0; channelIndex < channels.Length; channelIndex++)
                    {
                        var channel = channels2[channelIndex];

                        double sample   = channel[sampleIndex];
                        double sample_n = (sample - channelMeans[channelIndex]) / channelSDs[channelIndex];

                        // Subtract x*p.
                        sample_n -= p[channelIndex] * dotProduct;

                        double sample_p = (sample_n * channelSDs[channelIndex]) + channelMeans[channelIndex];

                        channel[sampleIndex] = sample_p;
                    }
                }
            }

            double[] varExplainedByComponent = new double[channels.Length];

            //Calculate the portion of variance explained by component.
            for (int componentIndex = 0; componentIndex < channels.Length; componentIndex++)
            {
                varExplainedByComponent[componentIndex] = (sdSumByComponent[componentIndex] - sdSumByComponent[componentIndex + 1]) / sdSumByComponent[0];
            }

            result.Matrix = matrix;
            result.VarianceExplainedByComponent = varExplainedByComponent;

            return(result);
        }