def test_inverse_coef(): """Test inverse coefficients computation.""" from sklearn.linear_model import Ridge tmin, tmax = 0., 10. n_feats, n_targets, n_samples = 3, 2, 1000 n_delays = int((tmax - tmin) + 1) # Check coefficient dims, for all estimator types X, y = _make_data(n_feats, n_targets, n_samples, tmin, tmax) tdr = TimeDelayingRidge(tmin, tmax, 1., 0.1, 'laplacian') for estimator in (0., 0.01, Ridge(alpha=0.), tdr): rf = ReceptiveField(tmin, tmax, 1., estimator=estimator, patterns=True) rf.fit(X, y) inv_rf = ReceptiveField(tmin, tmax, 1., estimator=estimator, patterns=True) inv_rf.fit(y, X) assert_array_equal(rf.coef_.shape, rf.patterns_.shape, (n_targets, n_feats, n_delays)) assert_array_equal(inv_rf.coef_.shape, inv_rf.patterns_.shape, (n_feats, n_targets, n_delays)) # we should have np.dot(patterns.T,coef) ~ np.eye(n) c0 = rf.coef_.reshape(n_targets, n_feats * n_delays) c1 = rf.patterns_.reshape(n_targets, n_feats * n_delays) assert_allclose(np.dot(c0, c1.T), np.eye(c0.shape[0]), atol=0.2)
def test_receptive_field_1d(n_jobs): """Test that the fast solving works like Ridge.""" from sklearn.linear_model import Ridge rng = np.random.RandomState(0) x = rng.randn(500, 1) for delay in range(-2, 3): y = np.zeros(500) slims = [(-2, 4)] if delay == 0: y[:] = x[:, 0] elif delay < 0: y[:delay] = x[-delay:, 0] slims += [(-4, -1)] else: y[delay:] = x[:-delay, 0] slims += [(1, 2)] for ndim in (1, 2): y.shape = (y.shape[0], ) + (1, ) * (ndim - 1) for slim in slims: smin, smax = slim lap = TimeDelayingRidge(smin, smax, 1., 0.1, 'laplacian', fit_intercept=False, n_jobs=n_jobs) for estimator in (Ridge(alpha=0.), Ridge(alpha=0.1), 0., 0.1, lap): for offset in (-100, 0, 100): model = ReceptiveField(smin, smax, 1., estimator=estimator, n_jobs=n_jobs) use_x = x + offset model.fit(use_x, y) if estimator is lap: continue # these checks are too stringent assert_allclose(model.estimator_.intercept_, -offset, atol=1e-1) assert_array_equal(model.delays_, np.arange(smin, smax + 1)) expected = (model.delays_ == delay).astype(float) expected = expected[np.newaxis] # features if y.ndim == 2: expected = expected[np.newaxis] # outputs assert_equal(model.coef_.ndim, ndim + 1) assert_allclose(model.coef_, expected, atol=1e-3) start = model.valid_samples_.start or 0 stop = len(use_x) - (model.valid_samples_.stop or 0) assert stop - start >= 495 assert_allclose( model.predict(use_x)[model.valid_samples_], y[model.valid_samples_], atol=1e-2) score = np.mean(model.score(use_x, y)) assert score > 0.9999
def test_inverse_coef(): """Test inverse coefficients computation.""" from sklearn.linear_model import Ridge rng = np.random.RandomState(0) tmin, tmax = 0., 10. n_feats, n_targets, n_samples = 64, 2, 10000 n_delays = int((tmax - tmin) + 1) def make_data(n_feats, n_targets, n_samples, tmin, tmax): X = rng.randn(n_samples, n_feats) w = rng.randn(int((tmax - tmin) + 1) * n_feats, n_targets) # Delay inputs X_del = np.concatenate(_delay_time_series(X, tmin, tmax, 1.).transpose(2, 0, 1), axis=1) y = np.dot(X_del, w) return X, y # Check coefficient dims, for all estimator types X, y = make_data(n_feats, n_targets, n_samples, tmin, tmax) tdr = TimeDelayingRidge(tmin, tmax, 1., 0.1, 'laplacian') for estimator in (0., 0.01, Ridge(alpha=0.), tdr): rf = ReceptiveField(tmin, tmax, 1., estimator=estimator, patterns=True) rf.fit(X, y) inv_rf = ReceptiveField(tmin, tmax, 1., estimator=estimator, patterns=True) inv_rf.fit(y, X) assert_array_equal(rf.coef_.shape, rf.patterns_.shape, (n_targets, n_feats, n_delays)) assert_array_equal(inv_rf.coef_.shape, inv_rf.patterns_.shape, (n_feats, n_targets, n_delays)) # we should have np.dot(patterns.T,coef) ~ np.eye(n) c0 = rf.coef_.reshape(n_targets, n_feats * n_delays) c1 = rf.patterns_.reshape(n_targets, n_feats * n_delays) assert_allclose(np.dot(c0, c1.T), np.eye(c0.shape[0]), atol=0.1) # Check that warnings are issued when no regularization is applied n_feats, n_targets, n_samples = 5, 60, 50 X, y = make_data(n_feats, n_targets, n_samples, tmin, tmax) for estimator in (0., Ridge(alpha=0.)): rf = ReceptiveField(tmin, tmax, 1., estimator=estimator, patterns=True) with warnings.catch_warnings(record=True) as w: rf.fit(y, X) # For some reason there is no warning if estimator and not check_version('numpy', '1.13'): continue assert_equal(len(w), 1) assert any(x in str(w[0].message).lower() for x in ('singular', 'scipy.linalg.solve'))
def test_inverse_coef(): """Test inverse coefficients computation.""" from sklearn.linear_model import Ridge rng = np.random.RandomState(0) tmin, tmax = 0., 10. n_feats, n_targets, n_samples = 64, 2, 10000 n_delays = int((tmax - tmin) + 1) def make_data(n_feats, n_targets, n_samples, tmin, tmax): X = rng.randn(n_samples, n_feats) w = rng.randn(int((tmax - tmin) + 1) * n_feats, n_targets) # Delay inputs X_del = np.concatenate(_delay_time_series(X, tmin, tmax, 1.).transpose(2, 0, 1), axis=1) y = np.dot(X_del, w) return X, y # Check coefficient dims, for all estimator types X, y = make_data(n_feats, n_targets, n_samples, tmin, tmax) tdr = TimeDelayingRidge(tmin, tmax, 1., 0.1, 'laplacian') for estimator in (0., 0.01, Ridge(alpha=0.), tdr): rf = ReceptiveField(tmin, tmax, 1., estimator=estimator, patterns=True) rf.fit(X, y) inv_rf = ReceptiveField(tmin, tmax, 1., estimator=estimator, patterns=True) inv_rf.fit(y, X) assert_array_equal(rf.coef_.shape, rf.patterns_.shape, (n_targets, n_feats, n_delays)) assert_array_equal(inv_rf.coef_.shape, inv_rf.patterns_.shape, (n_feats, n_targets, n_delays)) # we should have np.dot(patterns.T,coef) ~ np.eye(n) c0 = rf.coef_.reshape(n_targets, n_feats * n_delays) c1 = rf.patterns_.reshape(n_targets, n_feats * n_delays) assert_allclose(np.dot(c0, c1.T), np.eye(c0.shape[0]), atol=0.1) # Check that warnings are issued when no regularization is applied n_feats, n_targets, n_samples = 5, 60, 50 X, y = make_data(n_feats, n_targets, n_samples, tmin, tmax) for estimator in (0., Ridge(alpha=0.)): rf = ReceptiveField(tmin, tmax, 1., estimator=estimator, patterns=True) with pytest.warns((RuntimeWarning, UserWarning), match='[Singular|scipy.linalg.solve]'): rf.fit(y, X)
def test_receptive_field_nd(): """Test multidimensional support.""" from sklearn.linear_model import Ridge # multidimensional x = rng.randn(1000, 3) y = np.zeros((1000, 2)) slim = [0, 5] # This is a weird assignment, but it's just a way to distribute some # unique values at various delays, and "expected" explains how they # should appear in the resulting RF for ii in range(1, 5): y[ii:, ii % 2] += (-1)**ii * ii * x[:-ii, ii % 3] y -= np.mean(y, axis=0) x -= np.mean(x, axis=0) x_off = x + 1e3 expected = [ [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 4, 0], [0, 0, 2, 0, 0, 0]], [[0, 0, 0, -3, 0, 0], [0, -1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]], ] tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.1, 'laplacian') for estimator in (Ridge(alpha=0.), 0., 0.01, tdr): model = ReceptiveField(slim[0], slim[1], 1., estimator=estimator) model.fit(x, y) assert_array_equal(model.delays_, np.arange(slim[0], slim[1] + 1)) assert_allclose(model.coef_, expected, atol=1e-1) tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.01, reg_type='foo') model = ReceptiveField(slim[0], slim[1], 1., estimator=tdr) pytest.raises(ValueError, model.fit, x, y) tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.01, reg_type=['laplacian']) model = ReceptiveField(slim[0], slim[1], 1., estimator=tdr) pytest.raises(ValueError, model.fit, x, y) # Now check the intercept_ tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.) tdr_no = TimeDelayingRidge(slim[0], slim[1], 1., 0., fit_intercept=False) for estimator in (Ridge(alpha=0.), tdr, Ridge(alpha=0., fit_intercept=False), tdr_no): # first with no intercept in the data model = ReceptiveField(slim[0], slim[1], 1., estimator=estimator) model.fit(x, y) assert_allclose(model.estimator_.intercept_, 0., atol=1e-7, err_msg=repr(estimator)) assert_allclose(model.coef_, expected, atol=1e-3, err_msg=repr(estimator)) y_pred = model.predict(x) assert_allclose(y_pred[model.valid_samples_], y[model.valid_samples_], atol=1e-2, err_msg=repr(estimator)) score = np.mean(model.score(x, y)) assert score > 0.9999 # now with an intercept in the data model.fit(x_off, y) if estimator.fit_intercept: val = [-6000, 4000] itol = 0.5 ctol = 5e-4 else: val = itol = 0. ctol = 2. assert_allclose(model.estimator_.intercept_, val, atol=itol, err_msg=repr(estimator)) assert_allclose(model.coef_, expected, atol=ctol, rtol=ctol, err_msg=repr(estimator)) if estimator.fit_intercept: ptol = 1e-2 stol = 0.999999 else: ptol = 10 stol = 0.6 y_pred = model.predict(x_off)[model.valid_samples_] assert_allclose(y_pred, y[model.valid_samples_], atol=ptol, err_msg=repr(estimator)) score = np.mean(model.score(x_off, y)) assert score > stol, estimator model = ReceptiveField(slim[0], slim[1], 1., fit_intercept=False) model.fit(x_off, y) assert_allclose(model.estimator_.intercept_, 0., atol=1e-7) score = np.mean(model.score(x_off, y)) assert score > 0.6
mne.viz.tight_layout() # Create and fit a receptive field model # Time delays to use in the receptive field tmin, tmax = -1, 0 # Initialize the model interpolator = interp1d(np.arange(len(envelope)) / sfreq, envelope, fill_value=0., bounds_error=False, assume_sorted=True) envelope_rs = interpolator(speech_epochs.times) envelope_rs[0] = 0. assert np.isfinite(envelope_rs).all() est = TimeDelayingRidge(tmin, tmax, epochs.info['sfreq'], 1., 'laplacian') rf = ReceptiveField(tmin, tmax, epochs.info['sfreq'], estimator=est, scoring='corrcoef') n_delays = int((tmax - tmin) * sfreq) + 2 rf.fit(envelope_rs[:, np.newaxis], virtual_channels) score = rf.score(envelope_rs[:, np.newaxis], virtual_channels) coefs = rf.coef_[0, :] times = rf.delays_ / float(rf.sfreq) fig, ax = plt.subplots() ax.plot(times, coefs) ax.axhline(0, ls='--', color='r')
# smoothing the TRF estimate in a way that is insensitive to # the amplitude of the signal of interest. However, the Laplacian # approach (Equation 6) reduces off-sample error whilst preserving # signal amplitude (Lalor et al., 2006). As a result, this approach # usually leads to an improved estimate of the system’s response (as # indexed by MSE) compared to Tikhonov regularization. # alphas = np.logspace(-4, 0, 10) old_scores = scores scores = np.zeros_like(alphas) models = [] for ii, alpha in enumerate(alphas): estimator = TimeDelayingRidge(tmin, tmax, sfreq, reg_type='laplacian', alpha=alpha) rf = ReceptiveField(tmin, tmax, sfreq, freqs, estimator=estimator) rf.fit(X_train, y_train) # Now make predictions about the model output, given input stimuli. scores[ii] = rf.score(X_test, y_test) models.append(rf) ix_best_alpha = np.argmax(scores) ############################################################################### # Compare model performance # ------------------------- # Below we visualize the model performance of each regularization method
def test_receptive_field_fast(): """Test that the fast solving works like Ridge.""" from sklearn.linear_model import Ridge rng = np.random.RandomState(0) y = np.zeros(500) x = rng.randn(500) for delay in range(-2, 3): y.fill(0.) slims = [(-4, 2)] if delay == 0: y = x.copy() elif delay < 0: y[-delay:] = x[:delay] slims += [(-4, -1)] else: y[:-delay] = x[delay:] slims += [(1, 2)] for slim in slims: tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.1, 'laplacian', fit_intercept=False) for estimator in (Ridge(alpha=0.), 0., 0.1, tdr): model = ReceptiveField(slim[0], slim[1], 1., estimator=estimator) model.fit(x[:, np.newaxis], y) assert_array_equal(model.delays_, np.arange(slim[0], slim[1] + 1)) expected = (model.delays_ == delay).astype(float) assert_allclose(model.coef_[0], expected, atol=1e-2) p = model.predict(x[:, np.newaxis])[:, 0] assert_allclose(y, p, atol=5e-2) # multidimensional x = rng.randn(1000, 3) y = np.zeros((1000, 2)) slim = [-5, 0] # This is a weird assignment, but it's just a way to distribute some # unique values at various delays, and "expected" explains how they # should appear in the resulting RF for ii in range(1, 5): y[ii:, ii % 2] += (-1)**ii * ii * x[:-ii, ii % 3] expected = [ [[0, 0, 0, 0, 0, 0], [0, 4, 0, 0, 0, 0], [0, 0, 0, 2, 0, 0]], [[0, 0, -3, 0, 0, 0], [0, 0, 0, 0, -1, 0], [0, 0, 0, 0, 0, 0]], ] tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.1, 'laplacian') for estimator in (Ridge(alpha=0.), 0., 0.01, tdr): model = ReceptiveField(slim[0], slim[1], 1., estimator=estimator) model.fit(x, y) assert_array_equal(model.delays_, np.arange(slim[0], slim[1] + 1)) assert_allclose(model.coef_, expected, atol=1e-1) tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.01, reg_type='foo') model = ReceptiveField(slim[0], slim[1], 1., estimator=tdr) assert_raises(ValueError, model.fit, x, y) tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.01, reg_type=['laplacian']) model = ReceptiveField(slim[0], slim[1], 1., estimator=tdr) assert_raises(ValueError, model.fit, x, y) # Now check the intercept_ tdr = TimeDelayingRidge(slim[0], slim[1], 1., 0.) tdr_no = TimeDelayingRidge(slim[0], slim[1], 1., 0., fit_intercept=False) for estimator in (Ridge(alpha=0.), tdr, Ridge(alpha=0., fit_intercept=False), tdr_no): x -= np.mean(x, axis=0) y -= np.mean(y, axis=0) model = ReceptiveField(slim[0], slim[1], 1., estimator=estimator) model.fit(x, y) assert_allclose(model.estimator_.intercept_, 0., atol=1e-2) assert_allclose(model.coef_, expected, atol=1e-1) x += 1e3 model.fit(x, y) if estimator.fit_intercept: val, itol, ctol = [-6000, 4000], 20., 1e-1 else: val, itol, ctol = 0., 0., 2. # much worse assert_allclose(model.estimator_.intercept_, val, atol=itol) assert_allclose(model.coef_, expected, atol=ctol) model = ReceptiveField(slim[0], slim[1], 1., fit_intercept=False) model.fit(x, y) assert_allclose(model.estimator_.intercept_, 0., atol=1e-7)