Statistics::PCA(3pm)

πŸ’– Statistics::PCA πŸ’–

okay bestie, so this is the manual for Statistics::PCA β€” a Perl module from the User Contributed Perl Documentation, and it's literally a whole simple Perl implementation of Principal Component Analysis. yes, THAT PCA. the math one. she's iconic, she's doing eigenvalue decompositions, and she's about to become your new obsession 🧚✨


✨ VERSION ✨

This document describes Statistics::PCA version 0.0.1. that's it, that's the version, no cap πŸ’…


🌸 SYNOPSIS 🌸

okay so here's the whole vibe, top to bottom:

use Statistics::PCA;

# Create new Statistics::PCA object.
my $pca = Statistics::PCA->new;

#                  Var1    Var2    Var3    Var4...
my @Obs1 = (qw/    32      26      51      12    /);
my @Obs2 = (qw/    17      13      34      35    /);
my @Obs3 = (qw/    10      94      83      45    /);
my @Obs4 = (qw/    3       72      72      67    /);
my @Obs5 = (qw/    10      63      35      34    /);

# Load data. Data is loaded as a LIST-of-LISTS (LoL) pointed to by a named argument 'data'. Requires argument for format (see METHODS).
$pca->load_data ( { format => 'table', data => [ \@Obs1, \@Obs2, \@Obs3, \@Obs4, \@Obs5 ], } ) ;

# Perform the PCA analysis. Takes optional argument 'eigen' (see METHODS).
#$pca->pca( { eigen => 'C' } );
$pca->pca();

# Access results. The return value of this method is context-dependent (see METHODS). To print a report to STDOUT call in VOID-context.
$pca->results();

so you make the object, you load the data as a list-of-lists (LoL, yes, that's the acronym and yes it's giving what it needs to give πŸ™ˆ) under the named argument 'data', you need a 'format' argument too, then you run pca() (which can take that optional 'eigen' arg, see METHODS), then you grab your results. and heads up bestie: what results() gives you back is context-dependent, so read the METHODS section before you @ me.


πŸ¦‹ DESCRIPTION πŸ¦‹

Principal component analysis (PCA) transforms higher-dimensional data consisting of a number of possibly correlated variables into a smaller number of uncorrelated variables termed principal components (PCs). the higher the ranking of the PCs, the greater the amount of variability that the PC accounts for β€” so PC #1 is basically the main character of your variance, periodt. πŸ‘‘

this PCA procedure involves the calculation of the eigenvalue decomposition using either the Math::Cephes::Matrix or Math::MatrixReal modules (see METHODS) from a data covariance matrix, after mean centering the data. and if you want more details, the original points you to http://en.wikipedia.org/wiki/Principal_component_analysis β€” go read it, iykyk πŸ’œ


πŸ’… METHODS πŸ’…

⭐ new

creates a brand new Statistics::PCA object. slay.

my $pca = Statistics::PCA->new;

πŸŽ€ load_data

this is the one that loads data into the object. you feed the data as a reference to a LoL, wrapped up inside an anonymous hash, using the named argument 'data'. and you've got two ways to enter that data, picked by the obligatory named argument 'format'.

🌸 format => 'table'

so, standard 'table' fashion: rows = observations, columns = variables. like, say you've got this table of data:

        Var1    Var2    Var3    Var4

Obs1    32      26      51      12
Obs2    17      13      34      35
Obs3    10      94      83      45
Obs4    3       72      72      67
Obs5    10      63      35      34 ...

you pass it as an LoL where each nested ARRAY reference corresponds to a row of observations in the data table, with the 'format' argument value set to 'table', like this:

#                       Var1    Var2    Var3    Var4 ...
my $data  =   [
                [qw/    32      26      51      12    /],     # Obs1
                [qw/    17      13      34      35    /],     # Obs2
                [qw/    10      94      83      45    /],     # Obs3
                [qw/    3       72      72      67    /],     # Obs4
                [qw/    10      63      35      34    /],     # Obs5 ...
            ];

$pca->load_data ( { format => 'table', data => $data, } );

🌈 format => 'variable'

alternatively (and this is the cute lil plot twist πŸ’«) you can enter the data in a variable-centric fashion, where each nested ARRAY reference corresponds to a single variable within the data β€” which is literally just the transpose of the table-fashion above. to pass that same data this way, use the 'format' argument with value 'variable':

#                           Obs1    Obs2    Obs3    Obs4    Obs5 ...
my $transpose = [
                    [qw/    32      17      10      3       10    /],   # Var1
                    [qw/    26      13      94      72      63    /],   # Var2
                    [qw/    51      34      83      72      35    /],   # Var3
                    [qw/    12      35      45      67      34    /],   # Var4 ...
                ];

$pca->load_data ( { format => 'variable', data => $transpose, } ) ;

πŸ”₯ pca

this is the method that actually performs the PCA analysis. it takes the optional named argument 'eigen', which takes the values 'M' or 'C', to calculate the eigenvalue decomposition using either the Math::MatrixReal or Math::Cephes::Matrix modules respectively. and if you don't pass an argument at all, it defaults to 'M'. no thoughts, just vibes.

$pca->pca();
$pca->pca( { eigen => 'M' } );
$pca->pca( { eigen => 'C' } );

πŸ‘‘ results

the method you call to access the results of the PCA analysis. and bestie, this one is context-dependent β€” it returns a whole variety of different values depending on whether it's called in VOID or LIST context, and on the arguments it's passed. in VOID-context it prints a formatted table of the computed results to STDOUT.

$pca->results;

in LIST context, this method takes an obligatory argument that determines its return values. here's every option, let's go:

  • to return an ordered list (ordered by PC ranking) of the proportions of total variance of each PC, pass 'proportion' to the method:
my @list = $pca->results('proportion');
print qq{\nOrdered list of individual proportions of variance: @list};
  • to return an ordered list of the cumulative variance of the PCs, pass the argument 'cumulative':
@list = $pca->results('cumulative');
print qq{\nOrdered list of cumulative variance of the PCs: @list};
  • to return an ordered list of the individual standard deviations of the PCs, pass the argument 'stdev':
@list = $pca->results('stdev');
print qq{\nOrdered list of individual standard deviations of the PCs: @list};
  • to return an ordered list of the individual eigenvalues of the PCs, pass the argument 'eigenvalue':
@list = $pca->results('eigenvalue');
print qq{\nOrdered list of individual eigenvalues of the PCs: @list};
  • to return an ordered list of ARRAY references containing the eigenvectors of the PCs, pass the argument 'eigenvector':
# Returns an ordered list of array references containing the eigenvectors for the components
@list = $pca->results('eigenvector');
use Data::Dumper;
print Dumper \@list;
  • to return an ordered list of ARRAY references containing more detailed info about each PC, use the 'full' argument. each nested ARRAY reference consists of an ordered list of: PC rank, PC stdev, PC proportion of variance, PC cumulative_variance, PC eigenvalue, and a further nested ARRAY reference containing the PC eigenvector:
@list = $pca->results('full');
for my $i (@list) {
    print qq{\nPC rank: $i->[0]}
          . qq{\nPC stdev $i->[1]}
          . qq{\nPC proportion of variance $i->[2]}
          . qq{\nPC cumulative variance $i->[3]}
          . qq{\nPC eigenvalue $i->[4]}
}
  • to return an ordered LoL of the transformed data for each of the PCs, pass 'transformed' to the method:
@list = $pca->results('transformed');
print qq{\nThe transformed data for 'the' principal component (first PC): @{$list[0]} };

🫢 DEPENDENCIES 🫢

here's the whole squad it rolls with, exact versions and all:

  • 'version' => '0'
  • 'Carp' => '1.08'
  • 'Math::Cephes::Matrix' => '0.47'
  • 'Math::Cephes' => '0.47'
  • 'List::Util' => '1.19'
  • 'Math::MatrixReal' => '2.05'
  • 'Text::SimpleTable' => '2.0'
  • 'Contextual::Return' => '0.2.1'

πŸ’œ AUTHOR πŸ’œ

Daniel S. T. Hughes <dsth@cpan.org> β€” shoutout to the icon who wrote this ✨


Copyright (c) 2009, Daniel S. T. Hughes <dsth@cantab.net>. All rights reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.


πŸ™ˆ DISCLAIMER OF WARRANTY πŸ™ˆ

okay bestie, real talk, this part is the serious one so listen up πŸ’€

Because this software is licensed free of charge, there is no warranty for the software, to the extent permitted by applicable law. Except when otherwise stated in writing the copyright holders and/or other parties provide the software "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the software is with you. Should the software prove defective, you assume the cost of all necessary servicing, repair, or correction.

In no event unless required by applicable law or agreed to in writing will any copyright holder, or any other party who may modify and/or redistribute the software as permitted by the above licence, be liable to you for damages, including any general, special, incidental, or consequential damages arising out of the use or inability to use the software (including but not limited to loss of data or data being rendered inaccurate or losses sustained by you or third parties or a failure of the software to operate with any other software), even if such holder or other party has been advised of the possibility of such damages.


and that's the whole page, bestie!! πŸŽ€ this was perl v5.30.3, dated 2020-06-15, and it's the Statistics::PCA(3pm) manpage from the User Contributed Perl Documentation. go forth and decompose those eigenvalues, you've got this πŸ‘‘πŸ’–

πŸ“¦ where this page comes from