def _tvl1_objective(X, y, w, alpha, l1_ratio, mask, loss="mse"): """The TV-L1 squared loss regression objective functions. Returns ------- float Value of TV-L1 penalty. """ loss = loss.lower() if loss not in ['mse', 'logistic']: raise ValueError("loss must be one of 'mse' or 'logistic'; got '%s'" % loss) if loss == "mse": out = _squared_loss(X, y, w) else: out = _logistic_loss(X, y, w) w = w[:-1] grad_id = _gradient_id(_unmask_from_to_3d_array(w, mask), l1_ratio=l1_ratio) out += alpha * _tvl1_objective_from_gradient(grad_id) return out
def f2_prox(w, stepsize, dgap_tol, init=None): out, info = _prox_tvl1_with_intercept( unmaskvec(w), volume_shape, l1_ratio, alpha * stepsize, dgap_tol, prox_max_iter, init=_unmask_from_to_3d_array( init[:-1], mask) if init is not None else None, verbose=verbose) return maskvec(out.ravel()), info
def _tvl1_objective(X, y, w, alpha, l1_ratio, mask, loss="mse"): """The TV-L1 squared loss regression objective functions. Returns ------- float Value of TV-L1 penalty. """ loss = loss.lower() if loss not in ['mse', 'logistic']: raise ValueError( "loss must be one of 'mse' or 'logistic'; got '%s'" % loss) if loss == "mse": out = _squared_loss(X, y, w) else: out = _logistic_loss(X, y, w) w = w[:-1] grad_id = _gradient_id( _unmask_from_to_3d_array(w, mask), l1_ratio=l1_ratio) out += alpha * _tvl1_objective_from_gradient(grad_id) return out
def test_unmask_from_to_3d_array(size=5): rng = check_random_state(42) for ndim in range(1, 4): shape = [size] * ndim mask = np.zeros(shape).astype(np.bool) mask[rng.rand(*shape) > .8] = 1 support = rng.randn(mask.sum()) full = _unmask_from_to_3d_array(support, mask) np.testing.assert_array_equal(full.shape, shape) np.testing.assert_array_equal(full[mask], support)
def test_unmask_from_to_3d_array(size=5): rng = np.random.RandomState(42) for ndim in range(1, 4): shape = [size] * ndim mask = np.zeros(shape).astype(np.bool) mask[rng.uniform(size=shape) > .8] = 1 support = rng.standard_normal(size=mask.sum()) full = _unmask_from_to_3d_array(support, mask) np.testing.assert_array_equal(full.shape, shape) np.testing.assert_array_equal(full[mask], support)
def test_unmask_from_to_3d_array(size=5): rng = check_random_state(42) for ndim in range(1, 4): shape = [size] * ndim mask = np.zeros(shape).astype(np.bool) mask[rng.rand(*shape) > .8] = 1 support = rng.randn(mask.sum()) full = _unmask_from_to_3d_array(support, mask) np.testing.assert_array_equal(full.shape, shape) np.testing.assert_array_equal(full[mask], support)
def f2_prox(w, stepsize, dgap_tol, init=None): out, info = _prox_tvl1_with_intercept( unmaskvec(w), volume_shape, l1_ratio, alpha * stepsize, dgap_tol, prox_max_iter, init=_unmask_from_to_3d_array(init[:-1], mask) if init is not None else None, verbose=verbose) return maskvec(out.ravel()), info
def to_niimgs(X, dim): p = np.prod(dim) assert len(dim) == 3 assert X.shape[-1] <= p mask = np.zeros(p).astype(bool) mask[:X.shape[-1]] = 1 assert mask.sum() == X.shape[1] mask = mask.reshape(dim) X = np.rollaxis( np.array([_unmask_from_to_3d_array(x, mask) for x in X]), 0, start=4) affine = np.eye(4) return nibabel.Nifti1Image(X, affine), nibabel.Nifti1Image( mask.astype(np.float64), affine)
def to_niimgs(X, dim): p = np.prod(dim) assert_equal(len(dim), 3) assert_true(X.shape[-1] <= p) mask = np.zeros(p).astype(np.bool) mask[:X.shape[-1]] = 1 assert_equal(mask.sum(), X.shape[1]) mask = mask.reshape(dim) X = np.rollaxis( np.array([_unmask_from_to_3d_array(x, mask) for x in X]), 0, start=4) affine = np.eye(4) return nibabel.Nifti1Image(X, affine), nibabel.Nifti1Image( mask.astype(np.float), affine)
def _compute_weights(X, mask_img): """Compute the weights in the direction of each axis using the Euclidean distance --i.e. weights = (weight_deep, weights_right, weight_down). Notes ----- Here we assume a square lattice (no diagonal connections). Parameters ---------- X : ndarray, shape = [n_samples, n_features] Training data. mask_img : Niimg-like object Object used for masking the data. Returns ------- weights : ndarray Weights corresponding to all edges in the mask. shape: (n_edges,). """ n_samples, n_features = X.shape mask = get_data(mask_img).astype('bool') shape = mask.shape data = np.empty((shape[0], shape[1], shape[2], n_samples)) for sample in range(n_samples): data[:, :, :, sample] = \ _unmask_from_to_3d_array(X[sample].copy(), mask) weights_deep = np.sum(np.diff(data, axis=2)**2, axis=-1).ravel() weights_right = np.sum(np.diff(data, axis=1)**2, axis=-1).ravel() weights_down = np.sum(np.diff(data, axis=0)**2, axis=-1).ravel() weights = np.hstack([weights_deep, weights_right, weights_down]) return weights
def _univariate_feature_screening( X, y, mask, is_classif, screening_percentile, smoothing_fwhm=2.): """ Selects the most import features, via a univariate test Parameters ---------- X : ndarray, shape (n_samples, n_features) Design matrix. y : ndarray, shape (n_samples,) Response Vector. mask: ndarray or booleans, shape (nx, ny, nz) Mask defining brain Rois. is_classif: bool Flag telling whether the learning task is classification or regression. screening_percentile : float in the closed interval [0., 100.] Only the `screening_percentile * 100" percent most import voxels will be retained. %(smoothing_fwhm)s Default=2. Returns ------- X_: ndarray, shape (n_samples, n_features_) Reduced design matrix with only columns corresponding to the voxels retained after screening. mask_ : ndarray of booleans, shape (nx, ny, nz) Mask with support reduced to only contain voxels retained after screening. support : ndarray of ints, shape (n_features_,) Support of the screened mask, as a subset of the support of the original mask. """ # smooth the data (with isotropic Gaussian kernel) before screening if smoothing_fwhm > 0.: sX = np.empty(X.shape) for sample in range(sX.shape[0]): sX[sample] = ndimage.gaussian_filter( _unmask_from_to_3d_array(X[sample].copy(), # avoid modifying X mask), (smoothing_fwhm, smoothing_fwhm, smoothing_fwhm))[mask] else: sX = X # do feature screening proper selector = SelectPercentile(f_classif if is_classif else f_regression, percentile=screening_percentile).fit(sX, y) support = selector.get_support() # erode and then dilate mask, thus obtaining a "cleaner" version of # the mask on which a spatial prior actually makes sense mask_ = mask.copy() mask_[mask] = (support > 0) mask_ = ndimage.binary_dilation(ndimage.binary_erosion( mask_)).astype(bool) mask_[np.logical_not(mask)] = 0 support = mask_[mask] X = X[:, support] return X, mask_, support
def unmaskvec(w): if loss == "mse": return _unmask_from_to_3d_array(w, mask) else: return np.append(_unmask_from_to_3d_array(w[:-1], mask), w[-1])
def unmaskvec(w): if loss == "mse": return _unmask_from_to_3d_array(w, mask) else: return np.append(_unmask_from_to_3d_array(w[:-1], mask), w[-1])