C# PLS2 Scores And Loadings Example

[TOC]

using System;
using System.IO;

using CenterSpace.NMath.Core;
using CenterSpace.NMath.Stats;

namespace CenterSpace.NMath.Stats.Examples.CSharp
{
  /// <summary>
  /// This is a .NET example in C# showing Partial Least Squares (PLS) scores
  /// and loadings.
  /// In chemometrics one often wishes to know the chemical composition of a
  /// sample of, say, a gas or liquid. One common technique is to study the 
  /// absorption spectrum of light passing through the sample. Partial Least 
  /// Squares (PLS) is often used to construct a predictive model in this 
  /// situation. Suppose we  wish to measure the concentration of m different 
  /// constituents in the substance and that we look at n different 
  /// absorption spectra (an absorption spectra measures the amount of light 
  /// absorbed at each wavelength). Pick p different wavelengths in the 
  /// absorption spectra and let A = {aij} be the be the nxp matrix where aij 
  /// is the absorption measurement at the jth wavelength in the ith sample. 
  /// And let C = {cij} be the nxm matrix where cij is the concentration of 
  /// the jth constituent in the ith sample. This example constructs a 
  /// predictive model for C given A using PLS. In particular the scores and 
  /// loadings for the response variable, C, and the predictor variable, A, 
  /// are examined.
  /// </summary>
  class PLS2ScoresAndLoadingsExample
  {

    static void Main(string[] args)
    {
      // Read in some chemometric data.
      string yDatafilename = "..\\..\\chemometricY.dat";
      string xDatafilename = "..\\..\\chemometricX.dat";
      string x1Datafilename = "..\\..\\chemometricX1.dat";
      StreamReader xDataStream;
      StreamReader x1DataStream;
      StreamReader yDataStream;
      try
      {
        xDataStream = new StreamReader(xDatafilename);
        x1DataStream = new StreamReader(x1Datafilename);
        yDataStream = new StreamReader(yDatafilename);
      }
      catch (FileNotFoundException e)
      {
        string msg = string.Format("Could not find data file {0}, {1}, {2}.", xDatafilename,
          x1Datafilename, yDatafilename);
        msg += Environment.NewLine;
        msg += e.Message;
        Console.WriteLine(msg);
        return;
      }

      // Read in absorption data matrices. We'll use A to calculate the
      // PLS model and predict concentrations using the absorption data
      // in A1
      DoubleMatrix A = new DoubleMatrix(xDataStream);
      DoubleMatrix A1 = new DoubleMatrix(x1DataStream);
      DoubleMatrix C = new DoubleMatrix(yDataStream);

      int numComponents = 3;
      PLS2 pls = new PLS2();
      Console.WriteLine("\nCalculating...");
      pls.Calculate(A, C, numComponents);

      // Check that the PLS computation succeeded.
      Console.WriteLine("Is it good? " + pls.IsGood);

      // The scores and loadings availability and access are specific
      // the particular PLS algorithm used. We used the NIPALS algorithm,
      // which is the default, so we must retrieve the algorithm object
      // from the PLS object and extract the scores and loadings from it.
      PLS2NipalsAlgorithm alg = (PLS2NipalsAlgorithm)pls.Calculator;

      // Get the spectral scores
      DoubleMatrix S = alg.PredictorScores;
      Console.WriteLine("\nSpectral Scores ------------------------------\n");
      for (int i = 0; i < numComponents; ++i)
      {
        Console.WriteLine("spectral score {0} \n{1} \n", i, S.Col(i));
      }
      Console.WriteLine();

      // Get spectral loadings
      DoubleMatrix Bx = alg.PredictorLoadings;
      Console.WriteLine("\nSpectral Loadings ------------------------------\n");
      for (int i = 0; i < numComponents; ++i)
      {
        Console.WriteLine("spectral loading {0} \n{1} \n", i, Bx.Col(i));
      }
      Console.WriteLine();

      // Get concentration weighted scores
      DoubleMatrix U = alg.ResponseScores;
      Console.WriteLine("\nConcentration Weighted Scores ------------------\n");
      for (int i = 0; i < numComponents; ++i)
      {
        Console.WriteLine("concentration score {0} \n{1} \n", i, U.Col(i));
      }
      Console.WriteLine();

      // Get concentration loadings
      DoubleMatrix By = alg.ResponseLoadings;
      Console.WriteLine("\nConcentration Loadings ------------------------------\n");
      for (int i = 0; i < numComponents; ++i)
      {
        Console.WriteLine("concentration loading {0} \n{1} \n", i, By.Col(i));
      }
      Console.WriteLine();

      // Prediction using the coefficients matrix. Predict the constituent 
      // concentrations from a vector of spectral responses.
      // The coeffient matrix, B, can be used for prediction as follows:
      // Let Cu be the predicted concentrations for the spectral response
      // vector Au, let Abar the mean of the spectral data and Cbar be the mean
      // of the concentrations data used to create the model. Then
      // Cu = Cbar + (Au - Abar)B.
      DoubleVector Cbar = alg.ResponseMean;
      DoubleVector Abar = alg.PredictorMean;
      DoubleMatrix B = alg.Coefficients;

      DoubleVector Au = A1.Row(0);
      DoubleVector Cu = Cbar + NMathFunctions.TransposeProduct(B, (Au - Abar));
      Console.WriteLine("Prediction Using Coefficient Matrix ------------------\n");
      Console.WriteLine("Predicted concentrations for spectral response \n\n{0} \n\nis \n\n{1}", Au, Cu);

      Console.WriteLine();
      Console.WriteLine("Press Enter Key");
      Console.Read();
    }
  }
}

[TOC]