/// <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()); }
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()); }