def setUp(self): """Creates test data""" random_state = np.random.RandomState(0) modes_location = np.concatenate( (random_state.normal(-.3, .04, size=15), random_state.normal(.3, .04, size=15))) idx = np.arange(30) random_state.shuffle(idx) modes_location = modes_location[idx] self.modes_location = modes_location self.y = np.array(15 * [0] + 15 * [1])[idx] self.X = make_multimodal_samples(n_samples=30, modes_location=modes_location, noise=.05, random_state=random_state) self.X2 = make_multimodal_samples(n_samples=30, modes_location=modes_location, noise=.05, random_state=1) self.probs = np.array(15 * [[1., 0.]] + 15 * [[0., 1.]])[idx] # Dataset with outliers fd_clean = make_sinusoidal_process(n_samples=25, error_std=0, phase_std=0.1, random_state=0) fd_outliers = make_sinusoidal_process(n_samples=2, error_std=0, phase_mean=0.5, random_state=5) self.fd_lof = fd_outliers.concatenate(fd_clean)
def test_amplitude_distance_limit(self): """Test limit of amplitude distance penalty""" f = make_multimodal_samples(n_samples=1, random_state=1) g = make_multimodal_samples(n_samples=1, random_state=9999) amplitude_limit = amplitude_distance(f, g, lam=1000) fr_distance = fisher_rao_distance(f, g) np.testing.assert_almost_equal(amplitude_limit, fr_distance)
def setUp(self): """Initialization of samples""" template = make_multimodal_samples(n_samples=1, std=0, random_state=1) self.template = template self.template_rep = template.concatenate(template).concatenate( template) self.unimodal_samples = make_multimodal_samples(n_samples=3, random_state=1) t = np.linspace(-3, 3, 9) self.dummy_sample = FDataGrid([np.sin(t)], t)
def test_phase_distance_id(self): """Test of phase distance invariance""" f = make_multimodal_samples(n_samples=1, random_state=1) phase = phase_distance(f, 2 * f) np.testing.assert_allclose(phase, 0, atol=1e-7)
def test_landmark_shift(self): fd = make_multimodal_samples(n_samples=3, random_state=1) landmarks = make_multimodal_landmarks(n_samples=3, random_state=1) landmarks = landmarks.squeeze() original_modes = fd(landmarks.reshape((3, 1, 1)), aligned=False) # Test default location fd_registered = landmark_shift(fd, landmarks) center = (landmarks.max() + landmarks.min()) / 2 reg_modes = fd_registered(center) # Test callable location np.testing.assert_almost_equal(reg_modes, original_modes, decimal=2) fd_registered = landmark_shift(fd, landmarks, location=np.mean) center = np.mean(landmarks) reg_modes = fd_registered(center) np.testing.assert_almost_equal(reg_modes, original_modes, decimal=2) # Test integer location fd_registered = landmark_shift(fd, landmarks, location=0) center = np.mean(landmarks) reg_modes = fd_registered(0) np.testing.assert_almost_equal(reg_modes, original_modes, decimal=2) # Test array location fd_registered = landmark_shift(fd, landmarks, location=[0, 0.1, 0.2]) reg_modes = fd_registered([[0], [.1], [.2]], aligned=False) np.testing.assert_almost_equal(reg_modes, original_modes, decimal=2)
def test_landmark_shift_deltas(self): fd = make_multimodal_samples(n_samples=3, random_state=1) landmarks = make_multimodal_landmarks(n_samples=3, random_state=1) landmarks = landmarks.squeeze() shifts = landmark_shift_deltas(fd, landmarks).round(3) np.testing.assert_almost_equal(shifts, [0.25, -0.25, -0.231])
def test_multivariate_response_score(self): neigh = RadiusNeighborsRegressor() y = make_multimodal_samples(n_samples=5, dim_domain=2, random_state=0) neigh.fit(self.X[:5], y) # It is not supported the multivariate score by the moment with np.testing.assert_raises(ValueError): neigh.score(self.X[:5], y)
def setUp(self): grid_points = [1, 2, 3, 4, 5] self.fd = FDataGrid([[2, 3, 4, 5, 6], [1, 4, 9, 16, 25]], grid_points=grid_points) basis = Monomial(n_basis=3, domain_range=(1, 5)) self.fd_basis = FDataBasis(basis, [[1, 1, 0], [0, 0, 1]]) self.fd_curve = self.fd.concatenate(self.fd, as_coordinates=True) self.fd_surface = make_multimodal_samples(n_samples=3, dim_domain=2, random_state=0)
def test_mse_decomposition(self): fd = make_multimodal_samples(n_samples=3, random_state=1) landmarks = make_multimodal_landmarks(n_samples=3, random_state=1) landmarks = landmarks.squeeze() warping = landmark_registration_warping(fd, landmarks) fd_registered = fd.compose(warping) ret = mse_decomposition(fd, fd_registered, warping) np.testing.assert_almost_equal(ret.mse_amp, 0.0009866997121476962) np.testing.assert_almost_equal(ret.mse_pha, 0.11576861468435257) np.testing.assert_almost_equal(ret.rsq, 0.9915489952877273) np.testing.assert_almost_equal(ret.cr, 0.9999963424653829)
def test_mse_decomposition(self): fd = make_multimodal_samples(n_samples=3, random_state=1) landmarks = make_multimodal_landmarks(n_samples=3, random_state=1) landmarks = landmarks.squeeze() warping = landmark_registration_warping(fd, landmarks) fd_registered = fd.compose(warping) scorer = AmplitudePhaseDecomposition(return_stats=True) ret = scorer.score_function(fd, fd_registered, warping=warping) np.testing.assert_allclose(ret.mse_amp, 0.0009866997121476962) np.testing.assert_allclose(ret.mse_pha, 0.11576935495450151) np.testing.assert_allclose(ret.r_squared, 0.9915489952877273) np.testing.assert_allclose(ret.c_r, 0.999999, rtol=1e-6)
def setUp(self): """Creates test data""" random_state = np.random.RandomState(0) modes_location = np.concatenate( (random_state.normal(-.3, .04, size=15), random_state.normal(.3, .04, size=15))) idx = np.arange(30) random_state.shuffle(idx) modes_location = modes_location[idx] self.modes_location = modes_location self.y = np.array(15 * [0] + 15 * [1])[idx] self.X = make_multimodal_samples(n_samples=30, modes_location=modes_location, noise=.05, random_state=random_state) self.X2 = make_multimodal_samples(n_samples=30, modes_location=modes_location, noise=.05, random_state=1) self.probs = np.array(15 * [[1., 0.]] + 15 * [[0., 1.]])[idx]
def test_landmark_registration_warping(self): fd = make_multimodal_samples(n_samples=3, n_modes=2, random_state=9) landmarks = make_multimodal_landmarks(n_samples=3, n_modes=2, random_state=9) landmarks = landmarks.squeeze() # Default location warping = landmark_registration_warping(fd, landmarks) center = (landmarks.max(axis=0) + landmarks.min(axis=0)) / 2 np.testing.assert_almost_equal(warping(center), landmarks, decimal=1) # Fixed location center = [.3, .6] warping = landmark_registration_warping(fd, landmarks, location=center) np.testing.assert_almost_equal(warping(center), landmarks, decimal=3)
def test_landmark_registration(self): fd = make_multimodal_samples(n_samples=3, n_modes=2, random_state=9) landmarks = make_multimodal_landmarks(n_samples=3, n_modes=2, random_state=9) landmarks = landmarks.squeeze() original_values = fd(landmarks.reshape(3, 2), aligned=False) # Default location fd_reg = landmark_registration(fd, landmarks) center = (landmarks.max(axis=0) + landmarks.min(axis=0)) / 2 np.testing.assert_almost_equal(fd_reg(center), original_values, decimal=2) # Fixed location center = [.3, .6] fd_reg = landmark_registration(fd, landmarks, location=center) np.testing.assert_array_almost_equal(fd_reg(center), original_values, decimal=2)
def test_raises(self): reg = ShiftRegistration() # Test not fitted with np.testing.assert_raises(NotFittedError): reg.transform(self.fd) reg.fit(self.fd) reg.set_params(restrict_domain=True) # Test use fit or transform with restrict_domain=True with np.testing.assert_raises(AttributeError): reg.transform(self.fd) with np.testing.assert_raises(AttributeError): reg.fit(self.fd) # Test inverse_transform without previous transformation with np.testing.assert_raises(AttributeError): reg.inverse_transform(self.fd) reg.fit_transform(self.fd) # Test inverse transform with different number of sample with np.testing.assert_raises(ValueError): reg.inverse_transform(self.fd[:1]) fd = make_multimodal_samples(dim_domain=2, random_state=0) with np.testing.assert_raises(ValueError): reg.fit_transform(fd) reg.set_params(initial=[0.]) # Wrong initial estimation with np.testing.assert_raises(ValueError): reg.fit_transform(self.fd)
# # In the case of elastic registration it is taken as energy function the # Fisher-Rao distance with a penalisation term, due to the property of # invariance to reparameterizations of warpings functions. # # .. math:: # E[f \circ \gamma, g] = d_{FR} (f \circ \gamma, g) # # Firstly, we will create two unimodal samples, :math:`f` and :math:`g`, # defined in [0, 1] wich will be used to show the elastic registration. # Due to the similarity of these curves can be aligned almost perfectly # between them. # # Samples with modes in 1/3 and 2/3 fd = make_multimodal_samples(n_samples=2, modes_location=[1 / 3, 2 / 3], random_state=1, start=0, mode_std=.01) fig = fd.plot() fig.axes[0].legend(['$f$', '$g$']) ############################################################################## # In this example :math:`g` will be used as template and :math:`f` will be # aligned to it. In the following figure it is shown the result of the # registration process, wich can be computed using # :class:`~skfda.preprocessing.registration.ElasticRegistration`. # f, g = fd[0], fd[1] elastic_registration = ElasticRegistration(template=g)
############################################################################## # In the example of pairwise alignment was shown the usage of # :class:`~skfda.preprocessing.registration.ElasticRegistration` to align # a set of functional observations to a given template or a set of templates. # # In the groupwise alignment all the samples are aligned to the same template, # constructed to minimise some distance, generally a mean or a median. In the # case of the elastic registration, due to the use of the elastic distance in # the alignment, one of the most suitable templates is the karcher mean under # this metric. # # We will create a synthetic dataset to show the basic usage of the # registration. # fd = make_multimodal_samples(n_modes=2, stop=4, random_state=1) fd.plot() ############################################################################### # The following figure shows the # :func:`~skfda.preprocessing.registration.elastic.elastic_mean` of the # dataset and the cross-sectional mean, which correspond to the karcher-mean # under the :math:`\mathbb{L}^2` distance. # # It can be seen how the elastic mean better captures the geometry of the # curves compared to the standard mean, since it is not affected by the # deformations of the curves. fig = fd.mean().plot(label="L2 mean") elastic_mean(fd).plot(fig=fig, label="Elastic mean")