Package mvpa :: Package mappers :: Module lle

[hide private]
[frames] | no frames]

# Source Code for Module mvpa.mappers.lle

      1  #emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*-
      2  #ex: set 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  """Local Linear Embedding Data mapper.
     10
     11  This is a wrapper class around the corresponding MDP nodes LLE and HLLE
     12  (since MDP 2.4).
     13  """
     14
     15  __docformat__ = 'restructuredtext'
     16
     17  from mvpa.base import externals
     18
     19  import numpy as N
     20
     21  from mvpa.mappers.base import Mapper
     22
     23  if externals.exists('mdp ge 2.4', raiseException=True):
     24      from mdp.nodes import LLENode, HLLENode
     25
     26
     27 -class LLEMapper(Mapper):
     28      """Locally linear embbeding Mapper.
     29
     30      This mapper performs dimensionality reduction. It wraps two algorithms
     31      provided by the Modular Data Processing (MDP) framework.
     32
     33      Locally linear embedding (LLE) approximates the input data with a
     34      low-dimensional surface and reduces its dimensionality by learning a
     35      mapping to the surface.
     36
     37      This wrapper class provides access to two different LLE algorithms (i.e.
     38      the corresponding MDP processing nodes). 1) An algorithm outlined in *An
     39      Introduction to Locally Linear Embedding* by L. Saul and S. Roweis, using
     40      improvements suggested in *Locally Linear Embedding for Classification* by
     41      D. deRidder and R.P.W. Duin (aka `LLENode`) and 2) Hessian Locally Linear
     42      Embedding analysis based on algorithm outlined in *Hessian Eigenmaps: new
     43      locally linear embedding techniques for high-dimensional data* by C. Grimes
     44      and D. Donoho, 2003.
     45
     46      .. note::
     47        This mapper only provides forward-mapping functionality -- no reverse
     48        mapping is available.
     49
     50      .. seealso::
     51        http://mdp-toolkit.sourceforge.net
     52      """
     53 -    def __init__(self, k, algorithm='lle', **kwargs):
     54          """
     55          :Parameters:
     56            k: int
     57              Number of nearest neighbor to be used by the algorithm.
     58            algorithm: 'lle' | 'hlle'
     59              Either use the standard LLE algorithm or Hessian Linear Local
     60              Embedding (HLLE).
     61            **kwargs:
     62              Additional arguments are passed to the underlying MDP node.
     63              Most importantly this is the `output_dim` argument, that determines
     64              the number of dimensions to mapper is using as output space.
     65          """
     66          # no meaningful metric
     67          Mapper.__init__(self, metric=None)
     68
     69          self._algorithm = algorithm
     70          self._node_kwargs = kwargs
     71          self._k = k
     72          self._node = None
     73
     74
     75 -    def train(self, ds):
     76          """Train the mapper.
     77          """
     78          if self._algorithm == 'lle':
     79              self._node = LLENode(self._k, dtype=ds.samples.dtype,
     80                                   **self._node_kwargs)
     81          elif self._algorithm == 'hlle':
     82              self._node = HLLENode(self._k, dtype=ds.samples.dtype,
     83                                    **self._node_kwargs)
     84          else:
     85              raise NotImplementedError
     86
     87          self._node.train(ds.samples)
     88          self._node.stop_training()
     89
     90
     91 -    def forward(self, data):
     92          """Map data from the IN dataspace into OUT space.
     93          """
     94          # experience the beauty of MDP -- just call the beast and be done ;-)
     95          return self.node(data)
     96
     97
     98 -    def reverse(self, data):
     99          """Reverse map data from OUT space into the IN space.
    100          """
    101          raise NotImplementedError
    102
    103
    104 -    def getInSize(self):
    105          """Returns the size of the entity in input space"""
    106          return self.node.input_dim
    107
    108
    109 -    def getOutSize(self):
    110          """Returns the size of the entity in output space"""
    111          return self.node.output_dim
    112
    113
    114 -    def _accessNode(self):
    115          """Provide access to the underlying MDP processing node.
    116
    117          With some care.
    118          """
    119          if self._node is None:
    120              raise RuntimeError, \
    121                    'The LLEMapper needs to be trained before access to the ' \
    122                    'processing node is possible.'
    123
    124          return self._node
    125
    126
    127      node = property(fget=_accessNode)
    128