Package mvpa :: Package mappers :: Module svd

[hide private]
[frames] | no frames]

# Source Code for Module mvpa.mappers.svd

     1  # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
     2  # vi: set ft=python sts=4 ts=4 sw=4 et:
     3  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
     4  #
     5  #   See COPYING file distributed along with the PyMVPA package for the
     6  #   copyright and license terms.
     7  #
     8  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
     9  """Singular-value decomposition mapper"""
    10
    11  __docformat__ = 'restructuredtext'
    12
    13  import numpy as N
    14
    15  from mvpa.base.dochelpers import enhancedDocString
    16  from mvpa.mappers.base import ProjectionMapper
    17  from mvpa.featsel.helpers import ElementSelector
    18
    19  if __debug__:
    20      from mvpa.base import debug
    21
    22
    23 -class SVDMapper(ProjectionMapper):
    24      """Mapper to project data onto SVD components estimated from some dataset.
    25      """
    26 -    def __init__(self, **kwargs):
    27          """Initialize the SVDMapper
    28
    29          :Parameters:
    30            **kwargs:
    31              All keyword arguments are passed to the ProjectionMapper
    32              constructor.
    33
    34              Note, that for the 'selector' argument this class also supports
    35              passing a `ElementSelector` instance, which will be used to
    36              determine the to be selected features, based on the singular
    37              values of each component.
    38          """
    39          ProjectionMapper.__init__(self, **kwargs)
    40
    41          self._sv = None
    42          """Singular values of the training matrix."""
    43
    44      __doc__ = enhancedDocString('SVDMapper', locals(), ProjectionMapper)
    45
    46
    47 -    def _train(self, dataset):
    48          """Determine the projection matrix onto the SVD components from
    49          a 2D samples x feature data matrix.
    50          """
    51          X = N.asmatrix(dataset.samples)
    52          X = self._demeanData(X)
    53
    54          # singular value decomposition
    55          U, SV, Vh = N.linalg.svd(X, full_matrices=0)
    56
    57          # store the final matrix with the new basis vectors to project the
    58          # features onto the SVD components. And store its .H right away to
    59          # avoid computing it in forward()
    60          self._proj = Vh.H
    61
    62          # also store singular values of all components
    63          self._sv = SV
    64
    65          if __debug__:
    66              debug("MAP", "SVD was done on %s and obtained %d SVs " %
    67                    (dataset, len(SV)) + " (%d non-0, max=%f)" %
    68                    (len(SV.nonzero()), SV[0]))
    69              # .norm might be somewhat expensive to compute
    70              if "MAP_" in debug.active:
    71                  debug("MAP_", "Mixing matrix has %s shape and norm=%f" %
    72                        (self._proj.shape, N.linalg.norm(self._proj)))
    73
    74
    75 -    def selectOut(self, outIds):
    76          """Choose a subset of SVD components (and remove all others)."""
    77          # handle ElementSelector operating on SV (base class has no idea about)
    78          # XXX think about more generic interface, where some 'measure' is assigned
    79          # per each projection dimension, like in _sv in case of SVD.
    80          # May be selector could be parametrized with an instance + attribute as literal
    81          # so later on it could extract necessary values?
    82          if isinstance(self._selector, ElementSelector):
    83              ProjectionMapper.selectOut(self, self._selector(self._sv))
    84          else:
    85              ProjectionMapper.selectOut(self, outIds)
    86
    87 -    def _computeRecon(self):
    88          """Since singular vectors are orthonormal, sufficient to take hermitian
    89          """
    90          return self._proj.H
    91
    92      sv = property(fget=lambda self: self._sv, doc="Singular values")
    93