/usr/share/pyshared/mvpa2/measures/noiseperturbation.py is in python-mvpa2 2.2.0-4ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
# See COPYING file distributed along with the PyMVPA package for the
# copyright and license terms.
#
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
"""This is a `FeaturewiseMeasure` that uses a scalar `Measure` and
selective noise perturbation to compute a sensitivity map.
"""
__docformat__ = 'restructuredtext'
if __debug__:
from mvpa2.base import debug
from mvpa2.support.copy import deepcopy
import numpy as np
from mvpa2.measures.base import FeaturewiseMeasure
from mvpa2.datasets.base import Dataset
class NoisePerturbationSensitivity(FeaturewiseMeasure):
"""Sensitivity based on the effect of noise perturbation on a measure.
This is a `FeaturewiseMeasure` that uses a scalar `Measure`
and selective noise perturbation to compute a sensitivity map.
First the scalar `Measure` computed using the original dataset. Next
the data measure is computed multiple times each with a single feature in
the dataset perturbed by noise. The resulting difference in the
scalar `Measure` is used as the sensitivity for the respective
perturbed feature. Large differences are treated as an indicator of a
feature having great impact on the scalar `Measure`.
Notes
-----
The computed sensitivity map might have positive and negative values!
"""
is_trained = True
"""Indicate that this measure is always trained."""
def __init__(self, datameasure,
noise=np.random.normal):
"""
Parameters
----------
datameasure : `Measure`
Used to quantify the effect of noise perturbation.
noise: Callable
Used to generate noise. The noise generator has to return an 1d array
of n values when called the `size=n` keyword argument. This is the
default interface of the random number generators in NumPy's
`random` module.
"""
# init base classes first
FeaturewiseMeasure.__init__(self)
self.__datameasure = datameasure
self.__noise = noise
def _call(self, dataset):
# first cast to floating point dtype, because noise is most likely
# floating point as well and '+=' on int would not do the right thing
if not np.issubdtype(dataset.samples.dtype, np.float):
ds = dataset.copy(deep=False)
ds.samples = dataset.samples.astype('float32')
dataset = ds
if __debug__:
nfeatures = dataset.nfeatures
# using a list here, to be able to handle output of unknown
# dimensionality
sens_map = []
# compute the datameasure on the original dataset
# this is used as a baseline
orig_measure = self.__datameasure(dataset)
# do for every _single_ feature in the dataset
for feature in xrange(dataset.nfeatures):
if __debug__:
debug('PSA', "Analyzing %i features: %i [%i%%]" \
% (nfeatures,
feature+1,
float(feature+1)/nfeatures*100,), cr=True)
# store current feature to restore it later on
current_feature = dataset.samples[:, feature].copy()
# add noise to current feature
dataset.samples[:, feature] += self.__noise(size=len(dataset))
# compute the datameasure on the perturbed dataset
perturbed_measure = self.__datameasure(dataset)
# restore the current feature
dataset.samples[:, feature] = current_feature
# difference from original datameasure is sensitivity
sens_map.append(perturbed_measure.samples - orig_measure.samples)
if __debug__:
debug('PSA', '')
# turn into an array and get rid of unnecessary axes -- ideally yielding
# 2D array
sens_map = np.array(sens_map).squeeze()
# swap first to axis: we have nfeatures on first but want it as second
# in a dataset
sens_map = np.swapaxes(sens_map, 0, 1)
return Dataset(sens_map)
|