Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving feature names #42

Merged
merged 6 commits into from
Sep 28, 2018
29 changes: 29 additions & 0 deletions mne_features/feature_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from .bivariate import get_bivariate_funcs
from .univariate import get_univariate_funcs
from .utils import _idxiter


class FeatureFunctionTransformer(FunctionTransformer):
Expand Down Expand Up @@ -67,12 +68,40 @@ def transform(self, X, y='deprecated'):
"""
X_out = super(FeatureFunctionTransformer, self).transform(X, y)
self.output_shape_ = X_out.shape[0]
self.n_channels = X.shape[0]
return X_out

def get_feature_names(self):
"""Mapping of the feature indices to feature names."""
if hasattr(self.func, 'func'):
# If `_params['func'] is of type `functools.partial`
feature_func = self.func.func
elif hasattr(self.func, 'py_func'):
# If `_params['func'] is a jitted Python function
feature_func = self.func.py_func
else:
# If `_params['func'] is an actual Python function
feature_func = self.func
func_name = feature_func.__name__.split('compute_')[-1]
_params = super(FeatureFunctionTransformer,
self).get_params(True)['params']
if not hasattr(self, 'output_shape_'):
raise ValueError('Call `transform` or `fit_transform` first.')
elif func_name == 'pow_freq_bands':
freq_bands = _params['freq_bands']
n_freq_bands = (freq_bands.shape[0] - 1 if
freq_bands.ndim == 1 else freq_bands.shape[0])
ratios_names = ['ch%s_%s_%s' % (ch_num, i, j) for ch_num in
range(self.n_channels) for _, i, j in
_idxiter(n_freq_bands, triu=False)]
pow_names = ['ch%s_%s' % (ch_num, i) for ch_num in
range(self.n_channels) for i in range(n_freq_bands)]
if _params['ratios'] is None:
return pow_names
elif _params['ratios'] == 'only':
return ratios_names
else:
return pow_names + ratios_names
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not really clean. This gymnastic should be done via the function pow_freq_bands. You have some logic in a function agnostic class which percolates from a custom function. You should attach this logic to the pow_freq_bands callable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, this is not clean. This first commit was just to allow @l-omar-chehab to move on (and have meaning feature names for compute_pow_freq_bands). Now, we can think about making it nice.

else:
return np.arange(self.output_shape_).astype(str)

Expand Down