def test_time_delay(): """Test that time-delaying w/ times and samples works properly.""" # Explicit delays + sfreq X = np.random.RandomState(0).randn(1000, 2) assert (X == 0).sum() == 0 # need this for later test_tlims = [ ((1, 2), 1), ((1, 1), 1), ((0, 2), 1), ((0, 1), 1), ((0, 0), 1), ((-1, 2), 1), ((-1, 1), 1), ((-1, 0), 1), ((-1, -1), 1), ((-2, 2), 1), ((-2, 1), 1), ((-2, 0), 1), ((-2, -1), 1), ((-2, -1), 1), ((0, .2), 10), ((-.1, .1), 10)] for (tmin, tmax), isfreq in test_tlims: # sfreq must be int/float with pytest.raises(TypeError, match='`sfreq` must be an instance of'): _delay_time_series(X, tmin, tmax, sfreq=[1]) # Delays must be int/float with pytest.raises(TypeError, match='.*complex.*'): _delay_time_series(X, np.complex128(tmin), tmax, 1) # Make sure swapaxes works start, stop = int(round(tmin * isfreq)), int(round(tmax * isfreq)) + 1 n_delays = stop - start X_delayed = _delay_time_series(X, tmin, tmax, isfreq) assert_equal(X_delayed.shape, (1000, 2, n_delays)) # Make sure delay slice is correct delays = _times_to_delays(tmin, tmax, isfreq) assert_array_equal(delays, np.arange(start, stop)) keep = _delays_to_slice(delays) expected = np.where((X_delayed != 0).all(-1).all(-1))[0] got = np.arange(len(X_delayed))[keep] assert_array_equal(got, expected) assert X_delayed[keep].shape[-1] > 0 assert (X_delayed[keep] == 0).sum() == 0 del_zero = int(round(-tmin * isfreq)) for ii in range(-2, 3): idx = del_zero + ii err_msg = '[%s,%s] (%s): %s %s' % (tmin, tmax, isfreq, ii, idx) if 0 <= idx < X_delayed.shape[-1]: if ii == 0: assert_array_equal(X_delayed[:, :, idx], X, err_msg=err_msg) elif ii < 0: # negative delay assert_array_equal(X_delayed[:ii, :, idx], X[-ii:, :], err_msg=err_msg) assert_array_equal(X_delayed[ii:, :, idx], 0.) else: assert_array_equal(X_delayed[ii:, :, idx], X[:-ii, :], err_msg=err_msg) assert_array_equal(X_delayed[:ii, :, idx], 0.)
def test_time_delay(): """Test that time-delaying w/ times and samples works properly.""" from scipy.sparse import csr_matrix # Explicit delays + sfreq X = rng.randn(2, 1000) X_sp = np.zeros([2, 10]) X_sp[0, 1] = 1 X_sp = csr_matrix(X_sp) test_tlims = [((0, 2), 1), ((0, .2), 10), ((-.1, .1), 10)] for (tmin, tmax), isfreq in test_tlims: # sfreq must be int/float assert_raises(ValueError, _delay_time_series, X, tmin, tmax, sfreq=[1]) # Delays must be int/float assert_raises(ValueError, _delay_time_series, X, np.complex(tmin), tmax, 1) # Make sure swapaxes works delayed = _delay_time_series(X, tmin, tmax, isfreq, newaxis=2, axis=-1) assert_equal(delayed.shape[2], 3) # Make sure delay slice is correct delays = _times_to_delays(tmin, tmax, isfreq) keep = _delays_to_slice(delays) assert_true(delayed[..., keep].shape[-1] > 0) assert_true(np.isnan(delayed[..., keep]).sum() == 0) for idata in [X, X_sp]: if tmin < 0: continue X_delayed = _delay_time_series(X, tmin, tmax, isfreq, axis=-1) assert_array_equal(X_delayed[0], X) assert_array_equal(X_delayed[1][0, :-1], X[0, 1:]) assert_equal(len(X_delayed), (tmax - tmin) * isfreq + 1)
def test_time_delay(): """Test that time-delaying w/ times and samples works properly.""" # Explicit delays + sfreq X = np.random.RandomState(0).randn(1000, 2) assert (X == 0).sum() == 0 # need this for later test_tlims = [ ((1, 2), 1), ((1, 1), 1), ((0, 2), 1), ((0, 1), 1), ((0, 0), 1), ((-1, 2), 1), ((-1, 1), 1), ((-1, 0), 1), ((-1, -1), 1), ((-2, 2), 1), ((-2, 1), 1), ((-2, 0), 1), ((-2, -1), 1), ((-2, -1), 1), ((0, .2), 10), ((-.1, .1), 10)] for (tmin, tmax), isfreq in test_tlims: # sfreq must be int/float with pytest.raises(TypeError, match='`sfreq` must be an instance of'): _delay_time_series(X, tmin, tmax, sfreq=[1]) # Delays must be int/float with pytest.raises(TypeError, match='.*complex.*'): _delay_time_series(X, np.complex(tmin), tmax, 1) # Make sure swapaxes works start, stop = int(round(tmin * isfreq)), int(round(tmax * isfreq)) + 1 n_delays = stop - start X_delayed = _delay_time_series(X, tmin, tmax, isfreq) assert_equal(X_delayed.shape, (1000, 2, n_delays)) # Make sure delay slice is correct delays = _times_to_delays(tmin, tmax, isfreq) assert_array_equal(delays, np.arange(start, stop)) keep = _delays_to_slice(delays) expected = np.where((X_delayed != 0).all(-1).all(-1))[0] got = np.arange(len(X_delayed))[keep] assert_array_equal(got, expected) assert X_delayed[keep].shape[-1] > 0 assert (X_delayed[keep] == 0).sum() == 0 del_zero = int(round(-tmin * isfreq)) for ii in range(-2, 3): idx = del_zero + ii err_msg = '[%s,%s] (%s): %s %s' % (tmin, tmax, isfreq, ii, idx) if 0 <= idx < X_delayed.shape[-1]: if ii == 0: assert_array_equal(X_delayed[:, :, idx], X, err_msg=err_msg) elif ii < 0: # negative delay assert_array_equal(X_delayed[:ii, :, idx], X[-ii:, :], err_msg=err_msg) assert_array_equal(X_delayed[ii:, :, idx], 0.) else: assert_array_equal(X_delayed[ii:, :, idx], X[:-ii, :], err_msg=err_msg) assert_array_equal(X_delayed[:ii, :, idx], 0.)
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
def test_time_delaying_fast_calc(): """Test time delaying and fast calculations.""" X = np.array([[1, 2, 3], [5, 7, 11]]).T # all negative smin, smax = 1, 2 X_del = _delay_time_series(X, smin, smax, 1.) # (n_times, n_features, n_delays) -> (n_times, n_features * n_delays) X_del.shape = (X.shape[0], -1) expected = np.array([[0, 1, 2], [0, 0, 1], [0, 5, 7], [0, 0, 5]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = [[5, 2, 19, 10], [2, 1, 7, 5], [19, 7, 74, 35], [10, 5, 35, 25]] assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # all positive smin, smax = -2, -1 X_del = _delay_time_series(X, smin, smax, 1.) X_del.shape = (X.shape[0], -1) expected = np.array([[3, 0, 0], [2, 3, 0], [11, 0, 0], [7, 11, 0]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = [[9, 6, 33, 21], [6, 13, 22, 47], [33, 22, 121, 77], [21, 47, 77, 170]] assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # both sides smin, smax = -1, 1 X_del = _delay_time_series(X, smin, smax, 1.) X_del.shape = (X.shape[0], -1) expected = np.array([[2, 3, 0], [1, 2, 3], [0, 1, 2], [7, 11, 0], [5, 7, 11], [0, 5, 7]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = [[13, 8, 3, 47, 31, 15], [8, 14, 8, 29, 52, 31], [3, 8, 5, 11, 29, 19], [47, 29, 11, 170, 112, 55], [31, 52, 29, 112, 195, 112], [15, 31, 19, 55, 112, 74]] assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # slightly harder to get the non-Toeplitz correction correct X = np.array([[1, 2, 3, 5]]).T smin, smax = 0, 3 X_del = _delay_time_series(X, smin, smax, 1.) X_del.shape = (X.shape[0], -1) expected = np.array([[1, 2, 3, 5], [0, 1, 2, 3], [0, 0, 1, 2], [0, 0, 0, 1]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = [[39, 23, 13, 5], [23, 14, 8, 3], [13, 8, 5, 2], [5, 3, 2, 1]] assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # even worse X = np.array([[1, 2, 3], [5, 7, 11]]).T smin, smax = 0, 2 X_del = _delay_time_series(X, smin, smax, 1.) X_del.shape = (X.shape[0], -1) expected = np.array([[1, 2, 3], [0, 1, 2], [0, 0, 1], [5, 7, 11], [0, 5, 7], [0, 0, 5]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = np.array([[14, 8, 3, 52, 31, 15], [8, 5, 2, 29, 19, 10], [3, 2, 1, 11, 7, 5], [52, 29, 11, 195, 112, 55], [31, 19, 7, 112, 74, 35], [15, 10, 5, 55, 35, 25]]) assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # And a bunch of random ones for good measure rng = np.random.RandomState(0) X = rng.randn(25, 3) y = np.empty((25, 2)) vals = (0, -1, 1, -2, 2, -11, 11) for smax in vals: for smin in vals: if smin > smax: continue for ii in range(X.shape[1]): kernel = rng.randn(smax - smin + 1) kernel -= np.mean(kernel) y[:, ii % y.shape[-1]] = np.convolve(X[:, ii], kernel, 'same') x_xt, x_yt, n_ch_x = _compute_corrs(X, y, smin, smax + 1) X_del = _delay_time_series(X, smin, smax, 1., fill_mean=False) x_yt_true = einsum('tfd,to->ofd', X_del, y) x_yt_true = np.reshape(x_yt_true, (x_yt_true.shape[0], -1)).T assert_allclose(x_yt, x_yt_true, atol=1e-7, err_msg=(smin, smax)) X_del.shape = (X.shape[0], -1) x_xt_true = np.dot(X_del.T, X_del).T assert_allclose(x_xt, x_xt_true, atol=1e-7, err_msg=(smin, smax))
def test_receptive_field(): """Test model prep and fitting.""" from sklearn.linear_model import Ridge # Make sure estimator pulling works mod = Ridge() # Test the receptive field model # Define parameters for the model and simulate inputs + weights tmin, tmax = -10., 0 n_feats = 3 X = rng.randn(10000, n_feats) w = rng.randn(int((tmax - tmin) + 1) * n_feats) # Delay inputs and cut off first 4 values since they'll be cut in the fit X_del = np.concatenate(_delay_time_series(X, tmin, tmax, 1.).transpose(2, 0, 1), axis=1) y = np.dot(X_del, w) # Fit the model and test values feature_names = ['feature_%i' % ii for ii in [0, 1, 2]] rf = ReceptiveField(tmin, tmax, 1, feature_names, estimator=mod, patterns=True) rf.fit(X, y) assert_array_equal(rf.delays_, np.arange(tmin, tmax + 1)) y_pred = rf.predict(X) assert_allclose(y[rf.valid_samples_], y_pred[rf.valid_samples_], atol=1e-2) scores = rf.score(X, y) assert scores > .99 assert_allclose(rf.coef_.T.ravel(), w, atol=1e-2) # Make sure different input shapes work rf.fit(X[:, np.newaxis:, ], y[:, np.newaxis]) rf.fit(X, y[:, np.newaxis]) pytest.raises(ValueError, rf.fit, X[..., np.newaxis], y) pytest.raises(ValueError, rf.fit, X[:, 0], y) pytest.raises(ValueError, rf.fit, X[..., np.newaxis], np.tile(y[..., np.newaxis], [2, 1, 1])) # stim features must match length of input data pytest.raises(ValueError, rf.fit, X[:, :1], y) # auto-naming features rf = ReceptiveField(tmin, tmax, 1, estimator=mod) rf.fit(X, y) assert_equal(rf.feature_names, ['feature_%s' % ii for ii in [0, 1, 2]]) # X/y same n timepoints pytest.raises(ValueError, rf.fit, X, y[:-2]) # Float becomes ridge rf = ReceptiveField(tmin, tmax, 1, ['one', 'two', 'three'], estimator=0, patterns=True) str(rf) # repr works before fit rf.fit(X, y) assert isinstance(rf.estimator_, TimeDelayingRidge) str(rf) # repr works after fit rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0, patterns=True) rf.fit(X[:, [0]], y) str(rf) # repr with one feature # Should only accept estimators or floats rf = ReceptiveField(tmin, tmax, 1, estimator='foo', patterns=True) pytest.raises(ValueError, rf.fit, X, y) rf = ReceptiveField(tmin, tmax, 1, estimator=np.array([1, 2, 3])) pytest.raises(ValueError, rf.fit, X, y) # tmin must be <= tmax rf = ReceptiveField(5, 4, 1, patterns=True) pytest.raises(ValueError, rf.fit, X, y) # scorers for key, val in _SCORERS.items(): rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0, scoring=key, patterns=True) rf.fit(X[:, [0]], y) y_pred = rf.predict(X[:, [0]]).T.ravel()[:, np.newaxis] assert_allclose(val(y[:, np.newaxis], y_pred, multioutput='raw_values'), rf.score(X[:, [0]], y), rtol=1e-2) # Need 2D input pytest.raises(ValueError, _SCORERS['corrcoef'], y.ravel(), y_pred, multioutput='raw_values') # Need correct scorers rf = ReceptiveField(tmin, tmax, 1., scoring='foo') pytest.raises(ValueError, rf.fit, X, y)
def test_receptive_field_basic(n_jobs): """Test model prep and fitting.""" from sklearn.linear_model import Ridge # Make sure estimator pulling works mod = Ridge() rng = np.random.RandomState(1337) # Test the receptive field model # Define parameters for the model and simulate inputs + weights tmin, tmax = -10., 0 n_feats = 3 rng = np.random.RandomState(0) X = rng.randn(10000, n_feats) w = rng.randn(int((tmax - tmin) + 1) * n_feats) # Delay inputs and cut off first 4 values since they'll be cut in the fit X_del = np.concatenate(_delay_time_series(X, tmin, tmax, 1.).transpose(2, 0, 1), axis=1) y = np.dot(X_del, w) # Fit the model and test values feature_names = ['feature_%i' % ii for ii in [0, 1, 2]] rf = ReceptiveField(tmin, tmax, 1, feature_names, estimator=mod, patterns=True) rf.fit(X, y) assert_array_equal(rf.delays_, np.arange(tmin, tmax + 1)) y_pred = rf.predict(X) assert_allclose(y[rf.valid_samples_], y_pred[rf.valid_samples_], atol=1e-2) scores = rf.score(X, y) assert scores > .99 assert_allclose(rf.coef_.T.ravel(), w, atol=1e-3) # Make sure different input shapes work rf.fit(X[:, np.newaxis:], y[:, np.newaxis]) rf.fit(X, y[:, np.newaxis]) with pytest.raises(ValueError, match='If X has 3 .* y must have 2 or 3'): rf.fit(X[..., np.newaxis], y) with pytest.raises(ValueError, match='X must be shape'): rf.fit(X[:, 0], y) with pytest.raises(ValueError, match='X and y do not have the same n_epo'): rf.fit(X[:, np.newaxis], np.tile(y[:, np.newaxis, np.newaxis], [1, 2, 1])) with pytest.raises(ValueError, match='X and y do not have the same n_tim'): rf.fit(X, y[:-2]) with pytest.raises(ValueError, match='n_features in X does not match'): rf.fit(X[:, :1], y) # auto-naming features feature_names = ['feature_%s' % ii for ii in [0, 1, 2]] rf = ReceptiveField(tmin, tmax, 1, estimator=mod, feature_names=feature_names) assert_equal(rf.feature_names, feature_names) rf = ReceptiveField(tmin, tmax, 1, estimator=mod) rf.fit(X, y) assert_equal(rf.feature_names, None) # Float becomes ridge rf = ReceptiveField(tmin, tmax, 1, ['one', 'two', 'three'], estimator=0) str(rf) # repr works before fit rf.fit(X, y) assert isinstance(rf.estimator_, TimeDelayingRidge) str(rf) # repr works after fit rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0) rf.fit(X[:, [0]], y) str(rf) # repr with one feature # Should only accept estimators or floats with pytest.raises(ValueError, match='`estimator` must be a float or'): ReceptiveField(tmin, tmax, 1, estimator='foo').fit(X, y) with pytest.raises(ValueError, match='`estimator` must be a float or'): ReceptiveField(tmin, tmax, 1, estimator=np.array([1, 2, 3])).fit(X, y) with pytest.raises(ValueError, match='tmin .* must be at most tmax'): ReceptiveField(5, 4, 1).fit(X, y) # scorers for key, val in _SCORERS.items(): rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0, scoring=key, patterns=True) rf.fit(X[:, [0]], y) y_pred = rf.predict(X[:, [0]]).T.ravel()[:, np.newaxis] assert_allclose(val(y[:, np.newaxis], y_pred, multioutput='raw_values'), rf.score(X[:, [0]], y), rtol=1e-2) with pytest.raises(ValueError, match='inputs must be shape'): _SCORERS['corrcoef'](y.ravel(), y_pred, multioutput='raw_values') # Need correct scorers with pytest.raises(ValueError, match='scoring must be one of'): ReceptiveField(tmin, tmax, 1., scoring='foo').fit(X, y)
def test_receptive_field(): """Test model prep and fitting.""" from sklearn.linear_model import Ridge # Make sure estimator pulling works mod = Ridge() # Test the receptive field model # Define parameters for the model and simulate inputs + weights tmin, tmax = 0., 10. n_feats = 3 X = rng.randn(n_feats, 10000) w = rng.randn(int((tmax - tmin) + 1) * n_feats) # Delay inputs and cut off first 4 values since they'll be cut in the fit X_del = np.vstack(_delay_time_series(X, tmin, tmax, 1., axis=-1)) y = np.dot(w, X_del) X = np.rollaxis(X, -1, 0) # time to first dimension # Fit the model and test values feature_names = ['feature_%i' % ii for ii in [0, 1, 2]] rf = ReceptiveField(tmin, tmax, 1, feature_names, estimator=mod) rf.fit(X, y) assert_array_equal(rf.delays_, np.arange(tmin, tmax + 1)) y_pred = rf.predict(X) assert_array_almost_equal(y[rf.keep_samples_], y_pred.squeeze()[rf.keep_samples_], 2) scores = rf.score(X, y) assert_true(scores > .99) assert_array_almost_equal(rf.coef_.reshape(-1, order='F'), w, 2) # Make sure different input shapes work rf.fit(X[:, np.newaxis:, ], y[:, np.newaxis]) rf.fit(X, y[:, np.newaxis]) assert_raises(ValueError, rf.fit, X[..., np.newaxis], y) assert_raises(ValueError, rf.fit, X[:, 0], y) assert_raises(ValueError, rf.fit, X[..., np.newaxis], np.tile(y[..., np.newaxis], [2, 1, 1])) # stim features must match length of input data assert_raises(ValueError, rf.fit, X[:, :1], y) # auto-naming features rf = ReceptiveField(tmin, tmax, 1, estimator=mod) rf.fit(X, y) assert_equal(rf.feature_names, ['feature_%s' % ii for ii in [0, 1, 2]]) # X/y same n timepoints assert_raises(ValueError, rf.fit, X, y[:-2]) # Float becomes ridge rf = ReceptiveField(tmin, tmax, 1, ['one', 'two', 'three'], estimator=0) str(rf) # repr works before fit rf.fit(X, y) assert_true(isinstance(rf.estimator_, TimeDelayingRidge)) str(rf) # repr works after fit rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0) rf.fit(X[:, [0]], y) str(rf) # repr with one feature # Should only accept estimators or floats rf = ReceptiveField(tmin, tmax, 1, estimator='foo') assert_raises(ValueError, rf.fit, X, y) rf = ReceptiveField(tmin, tmax, 1, estimator=np.array([1, 2, 3])) assert_raises(ValueError, rf.fit, X, y) # tmin must be <= tmax rf = ReceptiveField(5, 4, 1) assert_raises(ValueError, rf.fit, X, y) # scorers for key, val in _SCORERS.items(): rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0, scoring=key) rf.fit(X[:, [0]], y) y_pred = rf.predict(X[:, [0]]) assert_array_almost_equal(val(y[:, np.newaxis], y_pred), rf.score(X[:, [0]], y), 4) # Need 2D input assert_raises(ValueError, _SCORERS['corrcoef'], y.squeeze(), y_pred) # Need correct scorers rf = ReceptiveField(tmin, tmax, 1., scoring='foo') assert_raises(ValueError, rf.fit, X, y)
def test_time_delaying_fast_calc(n_jobs): """Test time delaying and fast calculations.""" X = np.array([[1, 2, 3], [5, 7, 11]]).T # all negative smin, smax = 1, 2 X_del = _delay_time_series(X, smin, smax, 1.) # (n_times, n_features, n_delays) -> (n_times, n_features * n_delays) X_del.shape = (X.shape[0], -1) expected = np.array([[0, 1, 2], [0, 0, 1], [0, 5, 7], [0, 0, 5]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = [[5, 2, 19, 10], [2, 1, 7, 5], [19, 7, 74, 35], [10, 5, 35, 25]] assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # all positive smin, smax = -2, -1 X_del = _delay_time_series(X, smin, smax, 1.) X_del.shape = (X.shape[0], -1) expected = np.array([[3, 0, 0], [2, 3, 0], [11, 0, 0], [7, 11, 0]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = [[9, 6, 33, 21], [6, 13, 22, 47], [33, 22, 121, 77], [21, 47, 77, 170]] assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # both sides smin, smax = -1, 1 X_del = _delay_time_series(X, smin, smax, 1.) X_del.shape = (X.shape[0], -1) expected = np.array([[2, 3, 0], [1, 2, 3], [0, 1, 2], [7, 11, 0], [5, 7, 11], [0, 5, 7]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = [[13, 8, 3, 47, 31, 15], [8, 14, 8, 29, 52, 31], [3, 8, 5, 11, 29, 19], [47, 29, 11, 170, 112, 55], [31, 52, 29, 112, 195, 112], [15, 31, 19, 55, 112, 74]] assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # slightly harder to get the non-Toeplitz correction correct X = np.array([[1, 2, 3, 5]]).T smin, smax = 0, 3 X_del = _delay_time_series(X, smin, smax, 1.) X_del.shape = (X.shape[0], -1) expected = np.array([[1, 2, 3, 5], [0, 1, 2, 3], [0, 0, 1, 2], [0, 0, 0, 1]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = [[39, 23, 13, 5], [23, 14, 8, 3], [13, 8, 5, 2], [5, 3, 2, 1]] assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # even worse X = np.array([[1, 2, 3], [5, 7, 11]]).T smin, smax = 0, 2 X_del = _delay_time_series(X, smin, smax, 1.) X_del.shape = (X.shape[0], -1) expected = np.array([[1, 2, 3], [0, 1, 2], [0, 0, 1], [5, 7, 11], [0, 5, 7], [0, 0, 5]]).T assert_allclose(X_del, expected) Xt_X = np.dot(X_del.T, X_del) expected = np.array([[14, 8, 3, 52, 31, 15], [8, 5, 2, 29, 19, 10], [3, 2, 1, 11, 7, 5], [52, 29, 11, 195, 112, 55], [31, 19, 7, 112, 74, 35], [15, 10, 5, 55, 35, 25]]) assert_allclose(Xt_X, expected) x_xt = _compute_corrs(X, np.zeros((X.shape[0], 1)), smin, smax + 1)[0] assert_allclose(x_xt, expected) # And a bunch of random ones for good measure rng = np.random.RandomState(0) X = rng.randn(25, 3) y = np.empty((25, 2)) vals = (0, -1, 1, -2, 2, -11, 11) for smax in vals: for smin in vals: if smin > smax: continue for ii in range(X.shape[1]): kernel = rng.randn(smax - smin + 1) kernel -= np.mean(kernel) y[:, ii % y.shape[-1]] = np.convolve(X[:, ii], kernel, 'same') x_xt, x_yt, n_ch_x, _, _ = _compute_corrs(X, y, smin, smax + 1) X_del = _delay_time_series(X, smin, smax, 1., fill_mean=False) x_yt_true = einsum('tfd,to->ofd', X_del, y) x_yt_true = np.reshape(x_yt_true, (x_yt_true.shape[0], -1)).T assert_allclose(x_yt, x_yt_true, atol=1e-7, err_msg=(smin, smax)) X_del.shape = (X.shape[0], -1) x_xt_true = np.dot(X_del.T, X_del).T assert_allclose(x_xt, x_xt_true, atol=1e-7, err_msg=(smin, smax))
def test_receptive_field(n_jobs): """Test model prep and fitting.""" from sklearn.linear_model import Ridge # Make sure estimator pulling works mod = Ridge() rng = np.random.RandomState(1337) # Test the receptive field model # Define parameters for the model and simulate inputs + weights tmin, tmax = -10., 0 n_feats = 3 rng = np.random.RandomState(0) X = rng.randn(10000, n_feats) w = rng.randn(int((tmax - tmin) + 1) * n_feats) # Delay inputs and cut off first 4 values since they'll be cut in the fit X_del = np.concatenate( _delay_time_series(X, tmin, tmax, 1.).transpose(2, 0, 1), axis=1) y = np.dot(X_del, w) # Fit the model and test values feature_names = ['feature_%i' % ii for ii in [0, 1, 2]] rf = ReceptiveField(tmin, tmax, 1, feature_names, estimator=mod, patterns=True) rf.fit(X, y) assert_array_equal(rf.delays_, np.arange(tmin, tmax + 1)) y_pred = rf.predict(X) assert_allclose(y[rf.valid_samples_], y_pred[rf.valid_samples_], atol=1e-2) scores = rf.score(X, y) assert scores > .99 assert_allclose(rf.coef_.T.ravel(), w, atol=1e-3) # Make sure different input shapes work rf.fit(X[:, np.newaxis:, ], y[:, np.newaxis]) rf.fit(X, y[:, np.newaxis]) pytest.raises(ValueError, rf.fit, X[..., np.newaxis], y) pytest.raises(ValueError, rf.fit, X[:, 0], y) pytest.raises(ValueError, rf.fit, X[..., np.newaxis], np.tile(y[..., np.newaxis], [2, 1, 1])) # stim features must match length of input data pytest.raises(ValueError, rf.fit, X[:, :1], y) # auto-naming features feature_names = ['feature_%s' % ii for ii in [0, 1, 2]] rf = ReceptiveField(tmin, tmax, 1, estimator=mod, feature_names=feature_names) assert_equal(rf.feature_names, feature_names) rf = ReceptiveField(tmin, tmax, 1, estimator=mod) rf.fit(X, y) assert_equal(rf.feature_names, None) # X/y same n timepoints pytest.raises(ValueError, rf.fit, X, y[:-2]) # Float becomes ridge rf = ReceptiveField(tmin, tmax, 1, ['one', 'two', 'three'], estimator=0, patterns=True) str(rf) # repr works before fit rf.fit(X, y) assert isinstance(rf.estimator_, TimeDelayingRidge) str(rf) # repr works after fit rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0, patterns=True) rf.fit(X[:, [0]], y) str(rf) # repr with one feature # Should only accept estimators or floats rf = ReceptiveField(tmin, tmax, 1, estimator='foo', patterns=True) pytest.raises(ValueError, rf.fit, X, y) rf = ReceptiveField(tmin, tmax, 1, estimator=np.array([1, 2, 3])) pytest.raises(ValueError, rf.fit, X, y) # tmin must be <= tmax rf = ReceptiveField(5, 4, 1, patterns=True) pytest.raises(ValueError, rf.fit, X, y) # scorers for key, val in _SCORERS.items(): rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0, scoring=key, patterns=True) rf.fit(X[:, [0]], y) y_pred = rf.predict(X[:, [0]]).T.ravel()[:, np.newaxis] assert_allclose(val(y[:, np.newaxis], y_pred, multioutput='raw_values'), rf.score(X[:, [0]], y), rtol=1e-2) # Need 2D input pytest.raises(ValueError, _SCORERS['corrcoef'], y.ravel(), y_pred, multioutput='raw_values') # Need correct scorers rf = ReceptiveField(tmin, tmax, 1., scoring='foo') pytest.raises(ValueError, rf.fit, X, y)
def test_receptive_field(): """Test model prep and fitting""" from sklearn.linear_model import Ridge # Make sure estimator pulling works mod = Ridge() # Test the receptive field model # Define parameters for the model and simulate inputs + weights tmin, tmax = 0., 10. n_feats = 3 X = rng.randn(n_feats, 10000) w = rng.randn(int((tmax - tmin) + 1) * n_feats) # Delay inputs and cut off first 4 values since they'll be cut in the fit X_del = np.vstack(_delay_time_series(X, tmin, tmax, 1., axis=-1)) y = np.dot(w, X_del) X = np.rollaxis(X, -1, 0) # time to first dimension # Fit the model and test values feature_names = ['feature_%i' % ii for ii in [0, 1, 2]] rf = ReceptiveField(tmin, tmax, 1, feature_names, estimator=mod) rf.fit(X, y) assert_array_equal(rf.delays_, np.arange(tmin, tmax + 1)) y_pred = rf.predict(X) assert_array_almost_equal(y[rf.keep_samples_], y_pred.squeeze()[rf.keep_samples_], 2) scores = rf.score(X, y) assert_true(scores > .99) assert_array_almost_equal(rf.coef_.reshape(-1, order='F'), w, 2) # Make sure different input shapes work rf.fit(X[:, np.newaxis:, ], y[:, np.newaxis]) rf.fit(X, y[:, np.newaxis]) assert_raises(ValueError, rf.fit, X[..., np.newaxis], y) assert_raises(ValueError, rf.fit, X[:, 0], y) assert_raises(ValueError, rf.fit, X[..., np.newaxis], np.tile(y[..., np.newaxis], [2, 1, 1])) # stim features must match length of input data assert_raises(ValueError, rf.fit, X[:, :1], y) # auto-naming features rf = ReceptiveField(tmin, tmax, 1, estimator=mod) rf.fit(X, y) assert_equal(rf.feature_names, ['feature_%s' % ii for ii in [0, 1, 2]]) # X/y same n timepoints assert_raises(ValueError, rf.fit, X, y[:-2]) # Float becomes ridge rf = ReceptiveField(tmin, tmax, 1, ['one', 'two', 'three'], estimator=0) str(rf) # repr works before fit rf.fit(X, y) assert_true(isinstance(rf.estimator_, Ridge)) str(rf) # repr works after fit rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0) rf.fit(X[:, [0]], y) str(rf) # repr with one feature # Should only accept estimators or floats rf = ReceptiveField(tmin, tmax, 1, estimator='foo') assert_raises(ValueError, rf.fit, X, y) rf = ReceptiveField(tmin, tmax, 1, estimator=np.array([1, 2, 3])) assert_raises(ValueError, rf.fit, X, y) # tmin must be <= tmax rf = ReceptiveField(5, 4, 1) assert_raises(ValueError, rf.fit, X, y) # scorers for key, val in _SCORERS.items(): rf = ReceptiveField(tmin, tmax, 1, ['one'], estimator=0, scoring=key) rf.fit(X[:, [0]], y) y_pred = rf.predict(X[:, [0]]) assert_array_almost_equal(val(y[:, np.newaxis], y_pred), rf.score(X[:, [0]], y), 4) # Need 2D input assert_raises(ValueError, _SCORERS['corrcoef'], y.squeeze(), y_pred) # Need correct scorers assert_raises(ValueError, ReceptiveField, tmin, tmax, 1, scoring='foo')