def test_resid(): # Data is projected onto k=10 dimensional subspace then has its mean # removed. Should still have rank 10. k = 10 ncomp = 5 ntotal = k X = np.random.standard_normal((data['nimages'], k)) p = pca(data['fmridata'], -1, ncomp=ncomp, design_resid=X) yield assert_equal( p['basis_vectors'].shape, (data['nimages'], ntotal)) yield assert_equal( p['basis_projections'].shape, data['mask'].shape + (ncomp,)) yield assert_equal(p['pcnt_var'].shape, (ntotal,)) yield assert_almost_equal(p['pcnt_var'].sum(), 100.) # if design_resid is None, we do not remove the mean, and we get # full rank from our data p = pca(data['fmridata'], -1, design_resid=None) rank = p['basis_vectors'].shape[1] yield assert_equal(rank, data['nimages']) rarr = reconstruct(p['basis_vectors'], p['basis_projections'], -1) # add back the sqrt MSE, because we standardized rmse = root_mse(data['fmridata'], axis=-1)[...,None] yield assert_array_almost_equal(rarr * rmse, data['fmridata'])
def test_same_basis(): arr4d = data['fmridata'] shp = arr4d.shape arr2d = arr4d.reshape((np.prod(shp[:3]), shp[3])) res = pca(arr2d, axis=-1) p1b_0 = pos1basis(res) for i in range(3): res_again = pca(arr2d, axis=-1) assert_true(np.all(pos1basis(res_again) == p1b_0))
def test_2d_eq_4d(): arr4d = data['fmridata'] shp = arr4d.shape arr2d = arr4d.reshape((np.prod(shp[:3]), shp[3])) arr3d = arr4d.reshape((shp[0], -1, shp[3])) res4d = pca(arr4d, axis=-1, standardize=False) res3d = pca(arr3d, axis=-1, standardize=False) res2d = pca(arr2d, axis=-1, standardize=False) assert_array_almost_equal(pos1basis(res4d), pos1basis(res2d)) assert_array_almost_equal(pos1basis(res4d), pos1basis(res3d))
def test_PCANoMask_nostandardize(): ntotal = data['nimages'] - 1 ncomp = 5 p = pca(data['fmridata'], -1, ncomp=ncomp, standardize=False) yield assert_equal, p['basis_vectors'].shape, (data['nimages'], ntotal) yield assert_equal, p['basis_projections'].shape, data['mask'].shape + (ncomp,) yield assert_equal, p['pcnt_var'].shape, (ntotal,) yield assert_almost_equal, p['pcnt_var'].sum(), 100.
def test_both(): k1 = 10 k2 = 8 ncomp = 5 ntotal = k1 X1 = np.random.standard_normal((data['nimages'], k1)) X2 = np.random.standard_normal((data['nimages'], k2)) p = pca(data['fmridata'], -1, ncomp=ncomp, design_resid=X2, design_keep=X1) yield assert_equal, p['basis_vectors'].shape, (data['nimages'], ntotal) yield assert_equal, p['basis_projections'].shape, data['mask'].shape + (ncomp,) yield assert_equal, p['pcnt_var'].shape, (ntotal,) yield assert_almost_equal, p['pcnt_var'].sum(), 100.
def test_PCAMask(): ntotal = data['nimages'] - 1 ncomp = 5 p = pca(data['fmridata'], -1, data['mask'], ncomp=ncomp) yield assert_equal( p['basis_vectors'].shape, (data['nimages'], ntotal)) yield assert_equal( p['basis_projections'].shape, data['mask'].shape + (ncomp,)) yield assert_equal(p['pcnt_var'].shape, (ntotal,)) yield assert_almost_equal(p['pcnt_var'].sum(), 100.)
def test_keep(): # Data is projected onto k=10 dimensional subspace # then has its mean removed. # Should still have rank 10. k = 10 ncomp = 5 ntotal = k X = np.random.standard_normal((data['nimages'], k)) p = pca(data['fmridata'], -1, ncomp=ncomp, design_keep=X) yield assert_equal, p['basis_vectors'].shape, (data['nimages'], ntotal) yield assert_equal, p['basis_projections'].shape, data['mask'].shape + (ncomp,) yield assert_equal, p['pcnt_var'].shape, (ntotal,) yield assert_almost_equal, p['pcnt_var'].sum(), 100.
def test_2D(): # check that a standard 2D PCA works too M = 100 N = 20 L = M-1 # rank after mean removal data = np.random.uniform(size=(M, N)) p = pca(data) ts = p['basis_vectors'] imgs = p['basis_projections'] yield assert_equal(ts.shape, (M, L)) yield assert_equal(imgs.shape, (L, N)) rimgs = reconstruct(ts, imgs) # add back the sqrt MSE, because we standardized data_mean = data.mean(0)[None,...] demeaned = data - data_mean rmse = root_mse(demeaned, axis=0)[None,...] # also add back the mean yield assert_array_almost_equal((rimgs * rmse) + data_mean, data) # if standardize is set, or not, covariance is diagonal yield assert_true(diagonal_covariance(imgs)) p = pca(data, standardize=False) imgs = p['basis_projections'] yield assert_true(diagonal_covariance(imgs))
def test_input_effects(): ntotal = data['nimages'] - 1 # return full rank - mean PCA over last axis p = pca(data['fmridata'], -1) yield assert_equal( p['basis_vectors'].shape, (data['nimages'], ntotal)) yield assert_equal( p['basis_projections'].shape, data['mask'].shape + (ntotal,)) yield assert_equal(p['pcnt_var'].shape, (ntotal,)) # Reconstructed data lacks only mean rarr = reconstruct(p['basis_vectors'], p['basis_projections'], -1) rarr = rarr + data['fmridata'].mean(-1)[...,None] # same effect if over axis 0, which is the default arr = data['fmridata'] arr = np.rollaxis(arr, -1) pr = pca(arr) out_arr = np.rollaxis(pr['basis_projections'], 0, 4) yield assert_array_equal(out_arr, p['basis_projections']) yield assert_array_equal(p['basis_vectors'], pr['basis_vectors']) yield assert_array_equal(p['pcnt_var'], pr['pcnt_var']) # Check axis None raises error yield assert_raises(ValueError, pca, data['fmridata'], None)
def test_PCAMask(): # for 2 and 4D case ntotal = data['nimages'] - 1 ncomp = 5 arr4d = data['fmridata'] mask3d = data['mask'] arr2d = arr4d.reshape((-1, data['nimages'])) mask1d = mask3d.reshape((-1)) for arr, mask in (arr4d, mask3d), (arr2d, mask1d): p = pca(arr, -1, mask, ncomp=ncomp) yield assert_equal( p['basis_vectors'].shape, (data['nimages'], ntotal)) yield assert_equal( p['basis_projections'].shape, mask.shape + (ncomp,)) yield assert_equal(p['pcnt_var'].shape, (ntotal,)) yield assert_almost_equal(p['pcnt_var'].sum(), 100.)
def test_diagonality(): # basis_projections are diagonal, whether standarized or not p = pca(data['fmridata'], -1) # standardized yield assert_true(diagonal_covariance(p['basis_projections'], -1)) pns = pca(data['fmridata'], -1, standardize=False) # not yield assert_true(diagonal_covariance(pns['basis_projections'], -1))