/usr/share/pyshared/mvpa/measures/noiseperturbation.py is in python-mvpa 0.4.8-3.
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 | # 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 `FeaturewiseDatasetMeasure` that uses a scalar `DatasetMeasure` and
selective noise perturbation to compute a sensitivity map.
"""
__docformat__ = 'restructuredtext'
if __debug__:
from mvpa.base import debug
from mvpa.support.copy import deepcopy
import numpy as N
from mvpa.measures.base import FeaturewiseDatasetMeasure
class NoisePerturbationSensitivity(FeaturewiseDatasetMeasure):
"""This is a `FeaturewiseDatasetMeasure` that uses a scalar
`DatasetMeasure` and selective noise perturbation to compute a sensitivity
map.
First the scalar `DatasetMeasure` 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 `DatasetMeasure` 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 `DatasetMeasure`.
The computed sensitivity map might have positive and negative values!
"""
def __init__(self, datameasure,
noise=N.random.normal):
"""Cheap initialization.
:Parameters:
datameasure: `Datameasure` that is used to quantify the effect of
noise perturbation.
noise: Functor 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
FeaturewiseDatasetMeasure.__init__(self)
self.__datameasure = datameasure
self.__noise = noise
def _call(self, dataset):
"""Compute the sensitivity map.
Returns a 1d array of sensitivities for all features in `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
# XXX should we already deepcopy here to keep orig dtype?
if not N.issubdtype(dataset.samples.dtype, N.float):
dataset.setSamplesDType('float32')
if __debug__:
nfeatures = dataset.nfeatures
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)
# make a copy of the dataset to preserve data integrity
wdata = deepcopy(dataset)
# add noise to current feature
wdata.samples[:, feature] += self.__noise(size=wdata.nsamples)
# compute the datameasure on the perturbed dataset
perturbed_measure = self.__datameasure(wdata)
# difference from original datameasure is sensitivity
sens_map.append(perturbed_measure - orig_measure)
if __debug__:
debug('PSA', '')
return N.array(sens_map)
|