PartialLeastSquares (version 1.0.4, 2020-October-3)

PartialLeastSquares.py
 
Version: 1.0.4
   
Author: Avinash Kak (kak@purdue.edu)
 
Date: 2020-October-3
 
 
Download Version 1.0.4:  gztar

 
     Total number of downloads (all versions): 1089
     This count is automatically updated at every rotation of
     the weblogs (normally once every two to four days)
     Last updated: Sun Apr 21 06:04:02 EDT 2024
View version 1.0.4 code in browser  
 
 
 
CHANGES:

  Version 1.0.4
 
    The module code needed a couple of changes to comply with the Python
    3.8 syntax rules.  Also fixed the documentation errors present in the
    previous version of the module.
 
  Version 1.0.3
 
    This is a quick release that fixes the problem with the relative imports                       
    in the previous version. Python3 does not like relative imports.  
 
  Version 1.0.2        
 
    This version fixes the module packaging errors that had crept into the
    previous version.
 
  Version 1.0.1
 
    This version includes a couple of CSV data files in the Examples
    directory that were inadvertently left out of Version 1.0 packaging of
    the module.  The module code remains unchanged.
 
 
INTRODUCTION:
 
    You may need this module if (1) you are trying to make multidimensional
    predictions from multidimensional observations; (2) the dimensionality
    of the observation space is high; and (3) the data you have available
    for constructing a prediction model is rather limited.  The more
    traditional multiple linear regression (MLR) algorithms are likely to
    become numerically unstable under these conditions.  When the
    dimensionality of the space defined by the predictor variables is high
    and the number of observations available for constructing a prediction
    model is small, the traditional regression algorithms are likely to
    suffer from the "multicollinearity problem" caused by strong
    correlations between the different predictor variables. (We think of
    each dimension of the observation space as corresponding to one
    predictor variable.)  In the rest of this Introduction, I'll denote the
    predictor variables by x1, x2, ..., xN and the predicted variables by
    y1, y2, y3, ..., yM.  So N is the dimensionality of the space defined
    by the predictor variables and M the dimensionality of the space
    defined by the predicted variables.
 
    With the traditional multiple linear regression algorithms, one
    typically deals with the multicollinearity problem by first reducing
    the dimensionality N of the space of the predictor variables through
    the application of Principal Components Analysis (PCA) to the values
    spanned by these variables. Another way of dealing with the
    multicollinearity problem is by using the method of Partial Least
    Squares (PLS) that this module implements.  PCA focuses solely on the
    space defined by the predictor variables and gives you a small
    orthogonal set of directions in that space that explain the most
    significant variations in just the space defined by x1, x2, ...., xN.
    Subsequently, you can use the principal directions (these will be
    linear combinations of the original predictor variables) for making
    predictions.  PLS also gives you a small set of principal directions
    (also called principal components) in the space defined by the original
    predictor variables.  However, the directions yielded by PLS also take
    into account the observed variations in the space defined by the
    predicted variables y1, y2, ...., yM.  So if a principal component
    cannot explain the variations in the space defined by the predicted
    variables y1, y2, ..., yM, it will be ignored by PLS.
 
    Another way of saying the same thing is that whereas the principal
    components returned by PCA explain the largest variances in the
    space of the predictor variables, the principal components in the
    same space that are returned by PLS depend on their power to
    predict the variances in the space defined by the predicted
    variables.  Therefore, if it should happen that a principal
    component in the space of the predictor variables cannot be used to
    explain the the observed variability in the space defined by the
    predicted variables, PLS will ignore that principal component.  In
    the context of PLS, the principal components are more commonly
    referred to as latent vectors.
 
    If you have previously used multiple linear regression for data
    prediction and this happens to be your first exposure to PLS for making
    multidimensional predictions, you are likely to ask the following
    question: Why not consider each predicted variable separately in its
    dependence on the predictor variables? (In the context of linear
    regression, the predicted variables are frequently called the dependent
    or the response variables and the predictor variables as the
    explanatory variables.)  To answer this question, yes, you can
    certainly do that if the data you are using does not suffer from the
    problems listed at the beginning of this Introduction.  However, if
    those problems exist, you'll have no choice but to apply PCA to the
    explanatory variables in order to reduce the dimensionality of the
    space defined by those variables.  And, once you have taken the leap to
    dimensionality reduction, you might as well go all the way and use PLS
    for reasons already mentioned.
 
 
SOME EXAMPLE PROBLEM DOMAINS FOR PLS:
 
    Consider the problem of head pose estimation in computer vision.  Let's
    say you want to associate three pose parameters --- roll, pitch, and
    yaw --- with the pose of the face seen in a mostly frontal image of an
    individual as captured by a surveillance camera.  In a regression based
    approach to solving this problem, you'll first create a dataset of the
    images of the face for different value for the three pose
    parameters. [These days, such a dataset can be created by the computer
    itself from a single RGBD image of of the individual as recorded by the
    Microsoft Kinect sensor.  On account of the depth information that is
    also captured by this sensor, the computer can apply pose
    transformations to the recorded RGBD image and generate 2D images for
    the different values of roll, pitch, and yaw.]  Let's say each 2D face
    image is represented by a 40x40 array of pixels. If you represent each
    image as a vector of 1600 pixel values, you'll have 1600 predictor
    variables for the pixels values and 3 predicted variables for the roll,
    pitch, and the yaw parameters of the head pose.  The PLS algorithm when
    applied to this dataset will return a matrix of regression
    coefficients.  Subsequently, by applying this matrix to any vectorized
    representation of a face image, you will be able estimate the head pose
    associated with the face in that image.  The Examples directory of this
    module includes a script for doing exactly this.
 
    For another example, let's say you want to predict the chemical
    composition of a compound through spectroscopy. Each observation here
    would consist of the values shown by a spectrograph at, say, N
    different frequencies and the predicted output would be the proportion
    of the more elemental types in the compound.  If you expect to see M
    elemental types in a compound, we are talking about N predictor
    variables and M predicted variables.
 
    For yet another example, let's say that our assessment of the physical
    health of an individual depends on a number of parameters such as
    blood-pressure, cholesterol, blood glucose, triglycerides, etc.  And
    let's further say that we want to predict these parameters
    simultaneously from a multidimensional input consisting of average
    daily fat intake, the amount of sleep, the length of time exercising,
    etc.
 
 
THE NOTATION OF PLS:
 
    In the context of PLS, the matrix formed by the recorded values for the
    predictor variables x1, x2, ..., xN is typically denoted X.  Each row
    of X is one observation record and each column of X stands for one
    predictor variable.  The values for the predicted variables y1, y2,
    ..., yM are also placed in a matrix that is typically denoted Y.  Each
    column of Y stands for one predicted variable and each row of Y for the
    values for all the predicted variables using the corresponding row of X
    for prediction.
 
    So if we have I observation records available to us, X is a matrix of
    size IxN and Y is a matrix of size IxM.
 
    Each principal component of X, usually referred to as a latent vector
    of X, is represented by t and the matrix whose columns are the latent
    vectors t is typically denoted T. If the p is the number of latent
    vectors discovered for X, then T is of size Ixp.  Along the same lines,
    each latent vector of Y is typically denoted u and the matrix formed by
    these latent vectors is denoted U. In most variants of the PLS
    algorithm, the latent vectors for X and Y are discovered conjointly.
    In such cases, U will also be of size Ixp.
 
    Each latent vector t is a weighted linear combination of the columns of
    X and each latent vector u is a weighted linear combination of the
    columns of Y.  The weights that go into these combinations can also be
    thought of as vectors. These weights are referred to as loadings. The
    loading vectors for X are represented by p and those for Y by q.  The
    matrix formed by the p vectors represented by P and by the q vectors by
    Q.
 
    Two more matrices important to the discovery of the latent vectors for
    X and Y are W and C.  As mentioned earlier, a latent vector t is merely
    a weighted linear combination of the columns of X. For a calculated t,
    we represent these weights in the form of a vector w, and all the w
    vectors (for the different t vectors) taken together constitute the
    matrix W.  By the same token, a latent vector u is is a weighted linear
    combination of the columns of Y and, for a given u, we represent these
    weights in the form of a vector c.  All the different vectors c (for
    the different u vectors) constitute the matrix C.
 
    Finally, we need a matrix B of regression coefficients.  In fact,
    figuring out what B should be is the main purpose of the PLS algorithm.
    Once we have B, given a test data matrix Xtest, we can make the
    prediction Ytest = (Xtest * B).  For a given pair of latent vectors
    discovered simultaneously, t from X and u from Y, the product (t' * u)
    tells as to what extent the t portion of X can predict the u portion of
    Y.  We denote this product by the scalar variable b.
 
ALGORITHMIC DETAILS:
 
    The PLS algorithm was developed originally by Hermon Wold in 1966 and,
    over the years, there have come into existence several variants of the
    original algorithm. The different versions of the algorithm differ in
    the following ways: (1) As each pair of latent vectors, t from X and u
    from Y, is discovered, the different versions of PLS differ with regard
    to the deflation step.  By deflation we mean how we subtract the
    influence of t from X and of u of Y before starting search for the next
    pair (t,u) of latent vectors. (2) The different versions are different
    with regard to the normalization of the latent vectors. And (3) the
    different versions differ with regard to how the matrix B of the
    regression coefficients is calculated.
 
    See the review paper "Overview and Recent Advances in Partial Least
    Squares" by Roman Rosipal and Nicole Kramer, LNCS, 2006, for additional
    information related to the different variants of PLS and for citations
    to more recent work related to the algorithm.
 
    This module implements three variants of the PLS algorithm.  We refer
    to them as PLS(), PLS1(), and PLS2().  The implementation of PLS() is
    based on the description of the algorithm by Herve Abdi in the article
    "Partial Least Squares Regression and Projection on Latent Structure
    Regression," Computational Statistics, 2010.  From my experiments with
    the different variants of PLS, this particular version generates the
    best regression results.  The Examples directory contains a script that
    carries out head-pose estimation using this version of PLS.
 
    The variants PLS1() and PLS2() are based on the description of the
    algorithm in the previously cited paper by Roman Rosipal and Nicole
    Kramer.  The PLS1() algorithm has a special role amongst all of the
    variants of the partial least squares method --- it is meant
    specifically for the case when the matrix Y consists of only one column
    vector.  That is, we use PLS1() when there is just one dependent
    (which, as mentioned earlier, is the same thing as 'predicted')
    variable.  As you will see from the code in the Examples directory,
    this makes PLS1() particularly appropriate for solving recognition
    problems in computer vision.
 
    The rest of this section presents the main steps of the PLS algorithm.
    Our main goal is to find the latent vector t in the column space of X
    and the latent vector u in the column space of Y so that the covariance
    (t' * u)/I is maximized.  As mentioned earlier, t' is the transpose of
    t and I is the number of rows in X (and in Y).  Starting with a random
    guess for u, we iterate through the following eights steps until
    achieving the termination condition that is stated in the last step:
 
     1)  w = X' * u
 
              where X' is the transpose of X and u is the current value of
              the latent vector for Y.  We will use the elements of the
              vector w thus obtained as weights for creating a linear
              combination of the columns of X as a new candidate for t.
 
     2)  w =  w / ||w||
 
              where ||w|| is the norm of the vector w.  That is, ||w|| =
              sqrt(w' * w).  This step normalizes the magnitude of w to 1.
 
     3)  t = X * w
 
              Now we have a new approximation to t.  For PLS, we also
              normalize t as we normalized w in the previous step.
 
     4)  c = Y' * t
 
              We will use the elements of the vector c thus obtained as
              weights for creating a linear combination of the columns of Y
              for a new candidate as Y's latent vector u.
 
     5)  c = c / ||c||
 
              We normalize c just as we normalized w.
 
 
     6)  u_old  =  u
 
              We store away the currently used value for u
 
     7)  u = Y * c
 
              Now we have a new candidate for the latent vector for Y.
 
     8)  terminate the iterations if 
 
                       ||u - u_old||  <  epsilon
   
         where epsilon is a user-specified value.
 
    Once we have a vector t from the column space of X and a vector u from
    the column space of Y, we need to figure out what weighted linear
    combination of the columns of X would result in t and what weighted
    linear combination of the column vectors of Y would result in u.
    Referring to these weights by the vectors p and q, we calculate
 
         p  =  (X' * t) / ||t||
 
         q  =  (Y' * u) / ||u||
 
    If this is our first pair (t,u) of latent vectors, we initialize the
    matrices T and U by setting them to the column vectors t and u,
    respectively.  If this is not the first pair (t,u), we augment T and U
    by the additional column vectors t and u, respectively.  The same goes
    for the vectors p and q vis-a-vis the matrices P and Q.
 
    After the calculation of each pair (t,u) of latent vectors, it's time
    to subtract out from X the contribution made to it by t, and to
    subtract out from Y the contribution made to it by u. This step, called
    deflation as mentioned previously, is implemented as follows for PLS1()
    and PLS2():
 
         X  =  X - (t * p')
 
         Y  =  Y - (t * t' * Y) / ||t||
 
    For PLS(), the deflation is carried out by
 
         X  =  X - (t * p')
 
         Y  =  Y - b * t * c'
 
    where b = t' * u. 
 
    This process of first finding the covariance maximizing latent vectors
    t and u from the column spaces of X and Y, respectively, and
    subsequently deflating X and Y as shown above is continued until there
    is not much left of the matrices X and Y.  What is left of X and Y
    after each such deflation can be measured by taking the Frobenius norm
    of the matrices, which is simply the square-root of the sum of the
    squares of all the matrix elements.
 
    After the latent vectors of X and Y have been extracted, the last step
    is the calculation of the matrix B of regression coefficients. For the
    PLS() implementation, this calculation involves
 
                 _                  
        B =  (P')   *  diag[b1, b2, ...., bp] * C'
              _
    where (P')  is the pseudo-inverse of the transpose of P. The second term
    above is the diagonal matrix formed by the b values computed after the
    calculation of each pair (t,u) as mentioned earlier. C' is the
    transpose of the C matrix.
 
    For PLS1() and PLS2(), the B matrix is calculated through the following
    formula:
 
        B = W * (P' * W)^-1 * C'
 
    where (P' * W)^-1 is the matrix inverse of the product of the two
    matrices P' and W.  Note that P' is the transpose of P.
 
    After you have calculated the B matrix, you are ready to make
    predictions in the future as new row vectors for the X matrix come
    along.  Let's use the notation Xtest to denote the new data consisting
    of the observed values for the predictor variables.  Your prediction
    would now consist of
 
        Ytest =  Xtest * B
 
    for the case of zero-mean training data. In general, though, you will
    need to take into account the column-wise means of the X and the Y
    matrices.  That is,
 
        Ytest =  (Xtest -  X.mean(0)) * B   +   Y.mean(0)
 
    where "X.mean(0)" means a vector obtained by averaging each column of
    the training matrix X.  Similarly, the "Y.mean(0)" means the vector
    obtained by averaging each column of the training matrix Y.
 
 
USAGE:
 
    Let's say that you have the observed data for the X and the Y matrices
    in the form of CSV records in disk files. Your goal is to calculate the
    matrix B of regression coefficients with this module.  All you have to
    do is make the following calls:
 
        import PartialLeastSquares as PLS
 
        XMatrix_file = "X_data.csv"
        YMatrix_file = "Y_data.csv"
 
        pls = PLS.PartialLeastSquares(
                XMatrix_file =  XMatrix_file,
                YMatrix_file =  YMatrix_file,
                epsilon      = 0.0001,
              )
       pls.get_XMatrix_from_csv()
       pls.get_YMatrix_from_csv()
       B = pls.PLS()
 
    The object B returned by the last call will be a numpy matrix
    consisting of the calculated regression coefficients.  Let's say that
    you have a matrix Xtest of data for the predictor variables.  All you
    have to do to calculate the values for the predicted variables is
 
        Ytest =  (Xtest -  X.mean(0)) * B   +   Y.mean(0)
 
    Obviously, Xtest may contain just a single row --- meaning that it may
    contain a single observation consisting of the values for all the
    predictor variables.  In that case, the computed Ytest will also be
    just a one-row matrix.  The quantities "X.mean(0)" and "Y.mean(0)"
    shown above are constant vectors, the number of elements in the former
    equal to the number of columns in the X matrix and the number of
    elements in the latter equal to the number of columns in the Y matrix.
    These are just column-wise averages of the X and the Y matrices.
 
    The module can also work directly off the image data.  Going back to
    the problem of head-pose estimation on the basis of near-frontal image
    of a human head, let's say that your training data consisting of 2D
    face images with known values for the roll, pitch, and yaw parameters
    of the individual's head is in a directory called `head_pose_images'.
    The following calls will create a PLS based regression framework for
    this case:
 
        import PartialLeastSquares as PLS
 
        image_directory = 'head_pose_images'
 
        pls = PLS.PartialLeastSquares(
                    epsilon      = 0.001,
                    image_directory = image_directory,
                    image_type = 'jpg',
                    image_size_for_computations = (40,40),
              )
        pls.vectorize_images_and_construct_X_and_Y_matrices_for_PLS2()
        B = pls.PLS()
        pls.run_evaluation_of_PLS_regression_with_test_data(B)
 
    where the object B returned by the next to the last call is the matrix
    of regression coefficients.  The module expects the image directory to
    consist of two sub-directories called `training' and `testing'.  The
    PLS() is applied only to the image data in the `training'
    subdirectory. The method
 
         run_evaluation_of_PLS_regression_with_test_data(B)
 
    in the last call applies the matrix B of regression coefficients to the
    Xtest matrix constructed from the 2D face images stored in the
    `testing' subdirectory of the image directory.  The README in the
    Examples directory has further information on how we evaluate the
    accuracy of PLS based regression.
 
    If your goal is to carry out image recognition, as in face recognition,
    with PLS, you'd want to use the PLS1() implementation.  Assuming that
    your training face images are in a directory called `face_images', your
    call to the module will look like:
    
        import PartialLeastSquares as PLS
 
        image_directory = 'face_images'
 
        pls = PLS.PartialLeastSquares(
                    epsilon      = 0.001,
                    image_directory = image_directory,
                    image_type = 'jpg',
                    image_size_for_computations = (40,40),
              )
 
        pls.vectorize_images_and_construct_X_and_Y_matrices_for_PLS1()
        pls.PLS1()
        pls.run_evaluation_with_positive_and_negative_test_image_data()
 
    When called for image recognition as shown above, the module expects
    the image_directory to contain two subdirectories called `training' and
    `testing'.  The module also expects that each of these two
    subdirectories will contain two subdirectories called `positives' and
    `negatives'. The module constructs the X matrix from vectorized
    representation of the images in the `training/positives' and
    `training/negatives' subdirectories.  For the images in the former, it
    places a +1 label in the corresponding row of a one-column Y matrix.
    And for each image in the latter, it enters a -1 in the same Y matrix.
    The regression matrix B constructed from X and Y constructed in this
    manner is is applies to the Xtest matrix constructed from the images in
    the 'testing/positives' and `testing/negatives' subdirectories.
 
 
CONSTRUCTOR PARAMETERS:
 
    XMatrix_file :       The name of a CSV file that contains the X matrix.  Each
                         line of this file should contain the entries for
                         one row of the X matrix.
 
    YMatrix_file :       The name of a CSV file that contains the Y matrix.
                         Each line of this file should contain the entries
                         for one row of the Y matrix.
 
    epsilon:             Required for the testing the termination condition
                         for PLS iterations.  Search for latent vectors is
                         stopped when the Frobenius norm of what is left
                         of the X matrix is less than the value of epsilon.
                         If left unspecified, it defaults to 0.0001.
 
    image_directory:     This is the name of the directory that has the images for
                         experimenting with PLS regression for head-pose
                         estimation and face recognition. How the images are
                         distributed between the training and the testing 
                         subdirectories depends on whether they are meant to
                         be used for head-pose estimation or for binary 
                         recognition.
 
    image_type:          Specify the image type (such as jpg, png, etc.) 
                         in the image_directory
 
    image_size_for_computations: Specify the array size to be used for
                                  image computations.  If the actual images
                                  are larger, the module will reduce them
                                  to the size specified by this constructor
                                  parameter.  On the other hand, if the
                                  actual images are smaller along either or
                                  both dimensions, the module will zero-pad
                                  them appropriately to bring the size up
                                  to the values specified by this parameter.
 
 
METHODS:
 
    (1) get_XMatrix_from_csv()
 
        If you wish to use your own X and Y matrices for PLS regression, you'd
        need to supply them in the form of CSV files.  This method extracts the X matrix
        from the file named for this purpose by the constructor option XMatrix_file.
 
    (2) get_YMatrix_from_csv()
 
        The comment made above applies here also. This method extracts the Y matrix
        from the file named for this purpose by the constructor option YMatrix_file.
 
    (3) vectorize_images_and_construct_X_and_Y_matrices_for_head_pose_estimation_with_PLS()
 
        Assuming that you supplied the constructor with the `image_directory'
        option, this method further assumes that the images to be used for PLS
        regression are in two subdirectories named `training' and `testing'. The
        method also assumes that the values of the predicted variables for each
        image file are encoded into the names of the files themselves.  See the
        docstring associated with this method for more information.
 
    (4) vectorize_images_and_construct_X_and_Y_matrices_for_face_recognition_with_PLS1()
 
        This method assumes the directory structure shown below for the images to be
        used for face recognition:
 
                                                            -------  positives
                                                           |
                                   ------  training ------ |
                                  |                        |
                                  |                         -------  negatives
           image_directory  ------|                        
                                  |                         -------  positives
                                  |                        |
                                   ------  testing  -------|
                                                           |
                                                            ------- negatives
 
        The method constructs the X and Y matrices needed for PLS regression
        from the vectorized representation of the images in the
        `training/positives' and `training/negatives' directories. See the
        docstring for this method for additional information.
 
 
    (5) run_evaluation_of_PLS_regression_for_head_pose_estimation()
 
        The method here uses the Xtest and Yest matrices constructed by the
        vectorize_images_and_construct_X_and_Y_matrices_for_head_pose_estimation_with_PLS()
        method from the images in the `testing' subdirectory of the
        image_directory option supplied to the constructor.  The Xtest and Ytest
        matrices are then used for evaluating PLS regression for head pose
        estimation.
 
    (6) run_evaluation_of_PLS_regression_for_face_recognition()
 
        The method here uses the Xtest and Yest matrices constructed by the
        vectorize_images_and_construct_X_and_Y_matrices_for_face_recognition_with_PLS1()
        method from the images in the `testing/positives' and the
        /testing/negatives/ subdirectories for evaluating PLS regression for face
        recognition.
 
    (7) PLS()
 
        This implementation of PLS is based on the description of the algorithm
        by Herve Abdi in the article "Partial Least Squares Regression and
        Projection on Latent Structure Regression," Computational Statistics,
        2010.  From my experiments with the different variants of PLS, this
        particular version generates the best regression results.  The Examples
        directory contains a script that carries out head-pose estimation using
        this version of PLS.
 
    (8) PLS1()
 
        This implementation is based on the description of the algorithm in the
        article "Overview and Recent Advances in Partial Least Squares" by Roman
        Rosipal and Nicole Kramer, LNCS, 2006.  PLS1 assumes that the Y matrix
        consists of just one column. That makes it particularly appropriate for
        solving face recognition problems.  This module uses this method for a
        two-class discrimination between the faces.
 
    (9) PLS2()
 
        This implementation is based on the description of the algorithm as the
        same source as for PLS1().
 
 
THE EXAMPLES DIRECTORY:
 
    The best way to become familiar with this module is by executing the
    following scripts in the Examples subdirectory:
 
    1.  PLS_regression_with_supplied_X_and_Y.py
 
            This script computes the matrix B of regression coefficients from the
            X and Y matrices you supply in the form of CSV files through two
            constructor options.  First run the script with the two CSV files
            that are already in the Examples directory.  Subsequently, you can
            use your own CSV files for the X and Y matrices.
            
    2.  head_pose_estimation_with_PLS_regression_toy_example.py
 
            This script first learns the regression-coefficients matrix B from
            the images in a `training' directory and then applies the regression
            to estimate the head pose for the 2D images in a `testing' directory.
            For the purpose of training and testing, the script assumes that the
            name of each image file encodes the associated values of the roll,
            pitch, and yaw parameters of the head pose in the image.
 
    3.  face_recognition_with_PLS_toy_example.py
 
            This script uses the PLS1 algorithm for face recognition.  The PLS1
            algorithm is designed specifically for the case when the Y matrix
            consists of only one column.  For each row of the X matrix (which is
            a vector representation of a face), we place in the Y matrix +1 for
            the positive faces and -1 for the negative faces.  This is
            done separately for the training and the testing images.
           
 
INSTALLATION:
 
 
    The PartialLeastSquares class was packaged using setuptools.
 
    After you have downloaded the compressed archive into any directory of your
    choice, do the following:
 
    1) Uncompress the archive with a tool of your choice.  In a Linux environment,
       you are likely to use the following command:
 
             tar zxvf  the_downloaded_compressed_archive
 
    2) Next cd into the Examples subdirectory of the installation directory:
 
             cd  installation_directory/Examples
 
       where `installation_directory' is your pathname to the directory where the
       top-level uncompressed files and subdirectories reside.
 
    3) In the Examples directory, do the following
 
             tar zxvf face_images_toy_dataset.gz
 
             tar zxvf head_pose_images_toy_dataset.gz
 
    4) Now go back into the installation directory and execute the setup.py
       script:
 
             sudo python setup.py install                 
 
       and/or
 
             sudo python3 setup.py install 
 
    For Linux distributions, this will install the module at a location
    that looks like
 
         /usr/local/lib/python2.7/dist-packages/
 
    for Python2, and 
 
         /usr/local/lib/python3.4/dist-packages/
 
    for Python3.
 
    If you do not have root access, you have the option of working
    directly off the directory in which you downloaded the software by
    simply placing the following statements at the top of your scripts
    that use the PartialLeastSquares module:
 
        import sys
        sys.path.append( "pathname_to_PartialLeastSquares_directory" )
 
    To uninstall the module, simply delete the source directory, locate where
    PartialLeastSquares was installed with "locate partialleastsquares", and
    delete those files.  As mentioned above, the full pathname to the installed
    version is likely to look like
    /usr/local/lib/python2.7/dist-packages/PartialLeastSquares* or 
    /usr/local/lib/python3.4/dist-packages/PartialLeastSquares*.
 
    If you want to carry out a non-standard install of the PartialLeastSquares
    module, look up the on-line information on Disutils by pointing your browser
    to
 
          http://docs.python.org/dist/dist.html
 
 
    The PartialLeastSquares modules was packaged using setuptools.  
 
ACKNOWLEDGMENTS
 
The image dataset in the `head_pose_images' subdirectory of the Examples
directory was created by Dave Kim of the Robot Vision Lab at Purdue. Thanks,
Dave!
 
BUGS:
                             
Please notify the author if you encounter any bugs.  When sending email,
please place the string 'PLS' in the subject line.
 
 
ABOUT THE AUTHOR:  
 
    Avi Kak has just finished the last book of his three-volume Objects
    Trilogy project.  The last book deals with object-oriented design.  If
    interested, visit his home page at Purdue for further information
    related to The Objects Trilogy Project.
@endofdoc

 
Imported Modules
       
PIL.Image
functools
glob
numpy
os
re
sys

 
Classes
       
builtins.object
PartialLeastSquares

 
class PartialLeastSquares(builtins.object)
    PartialLeastSquares(*args, **kwargs)
 

 
  Methods defined here:
PLS(self)
This implementation is based on the description of the algorithm by Herve
Abdi in the article "Partial Least Squares Regression and Projection on
Latent Structure Regression," Computational Statistics, 2010.  From my
experiments with the different variants of PLS, this particular version
generates the best regression results.  The Examples directory contains a
script that carries out head-pose estimation using this version of PLS.
PLS1(self)
This implementation is based on the description of the algorithm in the article
"Overview and Recent Advances in Partial Least Squares" by Roman Rosipal and
Nicole Kramer, LNCS, 2006.  Note that PLS1 assumes that the Y matrix consists
of just one column. That makes it particularly appropriate for solving face
recognition problems.  This module uses this method for a two-class
discrimination between the faces.  We construct the X and Y matrices from the
positive and the negative examples of the face to be recognized.  Each row of
the X matrix consists of the vectorized representation of either a positive
example of a face or a negative example.  The corresponding element in the
one-column Y is +1 for the positive examples and -1 for the negative
examples.
PLS2(self)
This implementation is based on the description of the algorithm in the article
"Overview and Recent Advances in Partial Least Squares" by Roman Rosipal and
Nicole Kramer, LNCS, 2006.  Unlike PLS1, this implementation places no
constraints on the number of columns in the Y matrix.
__init__(self, *args, **kwargs)
Initialize self.  See help(type(self)) for accurate signature.
apply_regression_matrix_interactively_to_one_row_of_X_to_get_one_row_of_Y(self)
extract_pixels_from_image(self, imagename)
get_XMatrix_from_csv(self)
If you wish to use your own X and Y matrices for PLS regression, you'd need
to supply them in the form of CSV files.  This method extracts the X
matrix from the file named for this purpose by the constructor option
XMatrix_file.
get_YMatrix_from_csv(self)
If you wish to use your own X and Y matrices for PLS regression, you'd need
to supply them in the form of CSV files.  This method extracts the Y
matrix from the file named for this purpose by the constructor option
YMatrix_file.
run_evaluation_of_PLS_regression_for_face_recognition(self)
The docstring associated with the method
 
vectorize_images_and_construct_X_and_Y_matrices_for_face_recognition_with_PLS1()
 
applies here also. The method here uses the Xtest and Yest matrices
constructed by the `vectorize' method named above from the images in the
`testing/positives' and the /testing/negatives/ subdirectories for evaluating
PLS regression for face recognition.
run_evaluation_of_PLS_regression_for_head_pose_estimation(self)
The docstring associated with the method
 
   vectorize_images_and_construct_X_and_Y_matrices_for_head_pose_estimation_with_PLS()
 
applies here also. The method here uses the Xtest and Yest matrices
constructed by the `vectorize' method named above from the images in the
`testing' directory for evaluating PLS regression for head pose estimation.
vectorize_images_and_construct_X_and_Y_matrices_for_face_recognition_with_PLS1(self)
This method assumes that the images to be used for training and testing are
organized as follows in the image_directory option supplied to the
constructor of the module:
 
                                image_directory
                                     |
                                     |
                   --------------------------------------
                  |                                      |
                  |                                      |
               training                              testing
                  |                                      |
                  |                                      |
      -------------------------             -----------------------------
     |                         |           |                             |
     |                         |           |                             |
 positives                 negatives    positives                    negatives 
 
 
 The module constructs the X and the Y matrices from the images in the
 `training/positives' and the `training/negatives' subdirectories.  The
 vectorized representation of each image constitutes a row of the X
 matrix. The corresponding element in the one-column Y matrix is +1 for the
 images in the `positives' directory and -1 for the images in the `negatives'
 directory.  In a similar manner, the method constructs Xtest and Ytest
 matrices from the images in the `testing/positives' and `testing/negatives'
 subdirectories.
vectorize_images_and_construct_X_and_Y_matrices_for_head_pose_estimation_with_PLS(self)
This method assumes that the image directory contains two subdirectories named:
 
    --  training
 
    --  testing
 
Furthermore, the method assumes that the name of each image file in the two
subdirectories named above is an encoding of the roll, pitch, and yaw values
associated with the face image in that image.  For example, the name of the
first image file in the directory `/head_pose_images/training/' is
 
        y1p1r2.jpg
 
This name implies that the pose of the head in this image corresponds to the
following values for roll, pitch, and yaw:
 
        yaw   = -30 degrees
        pitch = -30 degrees
        roll  = -20 degrees
 
To understand why the name of the file translates into the values shown
above, note that the pose of the head is varied with respect to each of the
roll, pitch, and yaw parameters from -30 degrees to +30 degrees. We use the
following mapping between the integer indices associated with the parameters
in the file names and their actual angles:
 
       1   =>    -30 deg
       2   =>    -20 deg
       3   =>    -10 deg
       4   =>     0  deg
       5   =>    +10 deg
       6   =>    +20 deg
       7   =>    +30 deg
 
 This naming convention makes it easy to to create the rows of the Y matrix
 for each row of the X matrix.  Each row of the X matrix is the vectorized
 representation of the pixels in the image and each corresponding row of the
 Y matrix consists of the three pose angles associated with that image.

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
Functions
       
convert(value)

 
        __author__ = 'Avinash Kak (kak@purdue.edu)'
__copyright__ = '(C) 2020 Avinash Kak. Python Software Foundation.'
__date__ = '2020-October-3'
__url__ = 'https://engineering.purdue.edu/kak/distPLS/PartialLeastSquares-1.0.4.html'
__version__ = '1.0.4'
 
Author
        Avinash Kak (kak@purdue.edu)