1
2
3
4
5
6
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
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
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
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
92 """Map data from the IN dataspace into OUT space.
93 """
94
95 return self.node(data)
96
97
99 """Reverse map data from OUT space into the IN space.
100 """
101 raise NotImplementedError
102
103
105 """Returns the size of the entity in input space"""
106 return self.node.input_dim
107
108
110 """Returns the size of the entity in output space"""
111 return self.node.output_dim
112
113
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