public void Compute(int components)
        {
            NumberOfOutputs = components;

            // First, the data should be centered by subtracting
            //  the mean of each column in the source data matrix.
            double[][] matrix = Adjust(sourceMatrix.ToJagged(), overwriteSourceMatrix);

            // Pre-process the centered data matrix to have unit variance
            double[][] whiten = Statistics.Tools.Whitening(matrix, out whiteningMatrix);

            // Generate a new unitary initial guess for the de-mixing matrix
            double[][] initial = Jagged.Random(components, matrix.Columns());


            // Compute the demixing matrix using the selected algorithm
            if (algorithm == IndependentComponentAlgorithm.Deflation)
            {
                revertMatrix = deflation(whiten, components, initial);
            }
            else // if (algorithm == IndependentComponentAlgorithm.Parallel)
            {
                revertMatrix = parallel(whiten, components, initial);
            }

            // Combine the rotation and demixing matrices
            revertMatrix = whiteningMatrix.DotWithTransposed(revertMatrix);
            revertMatrix.Divide(revertMatrix.Sum(), result: revertMatrix);

            // Compute the original source mixing matrix
            mixingMatrix = Matrix.PseudoInverse(revertMatrix);
            mixingMatrix.Divide(mixingMatrix.Sum(), result: mixingMatrix);

            // Demix the data into independent components
            resultMatrix = Matrix.Dot(matrix, revertMatrix).ToMatrix();

            this.demix = createRegression(revertMatrix, columnMeans, columnStdDev, analysisMethod);
            this.mix   = demix.Inverse();

            // Creates the object-oriented structure to hold the principal components
            var array = new IndependentComponent[components];

            for (int i = 0; i < array.Length; i++)
            {
                array[i] = new IndependentComponent(this, i);
            }
            this.componentCollection = new IndependentComponentCollection(array);
        }
Exemplo n.º 2
0
        public void learn_test()
        {
            Accord.Math.Random.Generator.Seed = 0;
            #region doc_learn
            // Let's create a random dataset containing
            // 5000 samples of two dimensional samples.
            //
            double[][] source = Jagged.Random(5000, 2);

            // Now, we will mix the samples the dimensions of the samples.
            // A small amount of the second column will be applied to the
            // first, and vice-versa.
            //
            double[][] mix =
            {
                new double[] {  0.25, 0.25 },
                new double[] { -0.25, 0.75 },
            };

            // mix the source data
            double[][] input = source.Dot(mix);

            // Now, we can use ICA to identify any linear mixing between the variables, such
            // as the matrix multiplication we did above. After it has identified it, we will
            // be able to revert the process, retrieving our original samples again

            // Create a new Independent Component Analysis
            var ica = new IndependentComponentAnalysis()
            {
                Algorithm = IndependentComponentAlgorithm.Parallel,
                Contrast  = new Logcosh()
            };

            // Learn the demixing transformation from the data
            MultivariateLinearRegression demix = ica.Learn(input);

            // Now, we can retrieve the mixing and demixing matrices that were
            // used to alter the data. Note that the analysis was able to detect
            // this information automatically:

            double[][] mixingMatrix = ica.MixingMatrix;   // same as the 'mix' matrix
            double[][] revertMatrix = ica.DemixingMatrix; // inverse of the 'mix' matrix

            // We can use the regression to recover the separate sources
            double[][] result = demix.Transform(input);
            #endregion


            // Verify mixing matrix
            mixingMatrix = mixingMatrix.Divide(mixingMatrix.Sum());
            Assert.IsTrue(mix.IsEqual(mixingMatrix, atol: 0.008));

            Assert.IsTrue(revertMatrix.IsEqual(demix.Weights, atol: 0.008));
            var dm = demix.Inverse().Weights;
            dm = dm.Divide(dm.Sum());
            Assert.IsTrue(mixingMatrix.IsEqual(dm, atol: 0.008));


            // Verify demixing matrix
            double[,] expected =
            {
                { 0.75, -0.25 },
                { 0.25,  0.25 },
            };

            Assert.AreEqual(IndependentComponentAlgorithm.Parallel, ica.Algorithm);
            Assert.AreEqual(ica.Contrast.GetType(), typeof(Logcosh));

            revertMatrix = revertMatrix.Divide(revertMatrix.Sum());
            Assert.IsTrue(expected.IsEqual(revertMatrix, atol: 0.008));
        }