1
2
3
4
5
6
7
8
9 """Simply functors that transform something."""
10
11 __docformat__ = 'restructuredtext'
12
13
14 import numpy as N
15
16
18 """Returns the elementwise absolute of any argument."""
19 return N.absolute(x)
20
21
23 """Returns elementwise '1 - x' of any argument."""
24 return 1 - x
25
26
28 """Return whatever it was called with."""
29 return x
30
31
33 """Mean computed along the first axis."""
34 return N.mean(x, axis=0)
35
36
38 """Mean across 2nd axis
39
40 Use cases:
41 - to combine multiple sensitivities to get sense about
42 mean sensitivity across splits
43 """
44 return N.mean(x, axis=1)
45
46
48 """Sum of absolute values along the 2nd axis
49
50 Use cases:
51 - to combine multiple sensitivities to get sense about
52 what features are most influential
53 """
54 return N.abs(x).sum(axis=1)
55
56
58 """Max of absolute values along the 2nd axis
59 """
60 return N.abs(x).max(axis=1)
61
62
64 """Just what the name suggests."""
65 return N.mean(x)
66
67
68 -def L2Normed(x, norm=1.0, reverse=False):
69 """Norm the values so that regular vector norm becomes `norm`
70
71 More verbose: Norm that the sum of the squared elements of the
72 returned vector becomes `norm`.
73 """
74 xnorm = N.linalg.norm(x)
75 return x * (norm/xnorm)
76
77 -def L1Normed(x, norm=1.0, reverse=False):
78 """Norm the values so that L_1 norm (sum|x|) becomes `norm`"""
79 xnorm = N.sum(N.abs(x))
80 return x * (norm/xnorm)
81
82
84 """Rank-order by value. Highest gets 0"""
85
86
87 nelements = len(x)
88 indexes = N.arange(nelements)
89 t_indexes = indexes
90 if not reverse:
91 t_indexes = indexes[::-1]
92 tosort = zip(x, indexes)
93 tosort.sort()
94 ztosort = zip(tosort, t_indexes)
95 rankorder = N.empty(nelements, dtype=int)
96 rankorder[ [x[0][1] for x in ztosort] ] = \
97 [x[1] for x in ztosort]
98 return rankorder
99
100
104
105
107 """Helper to apply transformer over specific axis
108 """
109
110 - def __init__(self, transformer, axis=None):
111 """Initialize transformer wrapper with an axis.
112
113 :Parameters:
114 transformer
115 A callable to be used
116 axis : None or int
117 If None -- apply transformer across all the data. If some
118 int -- over that axis
119 """
120 self.transformer = transformer
121
122 if not (axis is None or isinstance(axis, int)):
123 raise ValueError, "axis must be specified by integer"
124 self.axis = axis
125
126
127 - def __call__(self, x, *args, **kwargs):
128 transformer = self.transformer
129 axis = self.axis
130 if axis is None:
131 return transformer(x, *args, **kwargs)
132
133 x = N.asanyarray(x)
134 shape = x.shape
135 if axis >= len(shape):
136 raise ValueError, "Axis given in constructor %d is higher " \
137 "than dimensionality of the data of shape %s" % (axis, shape)
138
139
140
141
142
143
144
145 shape_sweep = shape[:axis] + shape[axis+1:]
146 shrinker = None
147 """Either transformer reduces the dimensionality of the data"""
148
149 for index_sweep in N.ndindex(shape_sweep):
150 if axis > 0:
151 index = index_sweep[:axis]
152 else:
153 index = ()
154 index = index + (slice(None),) + index_sweep[axis:]
155 x_sel = x[index]
156 x_t = transformer(x_sel, *args, **kwargs)
157 if shrinker is None:
158 if N.isscalar(x_t) or x_t.shape == shape_sweep:
159 results = N.empty(shape_sweep, dtype=x.dtype)
160 shrinker = True
161 elif x_t.shape == x_sel.shape:
162 results = N.empty(x.shape, dtype=x.dtype)
163 shrinker = False
164 else:
165 raise RuntimeError, 'Not handled by OverAxis kind of transformer'
166
167 if shrinker:
168 results[index_sweep] = x_t
169 else:
170 results[index] = x_t
171
172 return results
173