def test_singular_covariance_init_of_non_strict_pd(estimator, build_dataset): """Tests that when using the 'covariance' init or prior, it returns the appropriate warning if the covariance matrix is singular, for algorithms that don't need a strictly PD init. Also checks that the returned inverse matrix has finite values """ input_data, labels, _, X = build_dataset() model = clone(estimator) set_random_state(model) # We create a feature that is a linear combination of the first two # features: input_data = np.concatenate([input_data, input_data[:, ..., :2].dot([[2], [3]])], axis=-1) model.set_params(init='covariance') msg = ('The covariance matrix is not invertible: ' 'using the pseudo-inverse instead.' 'To make the covariance matrix invertible' ' you can remove any linearly dependent features and/or ' 'reduce the dimensionality of your input, ' 'for instance using `sklearn.decomposition.PCA` as a ' 'preprocessing step.') with pytest.warns(UserWarning) as raised_warning: model.fit(input_data, labels) assert np.any([str(warning.message) == msg for warning in raised_warning]) M, _ = _initialize_metric_mahalanobis(X, init='covariance', random_state=RNG, return_inverse=True, strict_pd=False) assert np.isfinite(M).all()
def test_singular_array_init_of_non_strict_pd(w0): """Tests that when using a custom array init, it returns the appropriate warning if it is singular. Also checks if the returned inverse matrix is finite. This isn't checked for model fitting as no model curently uses this setting. """ rng = np.random.RandomState(42) X, y = shuffle(*make_blobs(random_state=rng), random_state=rng) P = ortho_group.rvs(X.shape[1], random_state=rng) w = np.abs(rng.randn(X.shape[1])) w[0] = w0 M = P.dot(np.diag(w)).dot(P.T) msg = ('The initialization matrix is not invertible: ' 'using the pseudo-inverse instead.') with pytest.warns(UserWarning) as raised_warning: _, M_inv = _initialize_metric_mahalanobis(X, init=M, random_state=rng, return_inverse=True, strict_pd=False) assert str(raised_warning[0].message) == msg assert np.isfinite(M_inv).all()