Пример #1
0
    def test_kernel_types(self):
        """
        This test checks that KernelPCovR can handle all kernels passable to
        sklearn kernel classes, including callable kernels
        """
        def _linear_kernel(X, Y):
            return X @ Y.T

        kernel_params = {
            "poly": {
                "degree": 2
            },
            "rbf": {
                "gamma": 3.0
            },
            "sigmoid": {
                "gamma": 3.0,
                "coef0": 0.5
            },
        }
        for kernel in [
                "linear", "poly", "rbf", "sigmoid", "cosine", _linear_kernel
        ]:
            with self.subTest(kernel=kernel):
                kpcovr = KernelPCovR(mixing=0.5,
                                     n_components=2,
                                     regressor=KernelRidge(kernel=kernel,
                                                           **kernel_params.get(
                                                               kernel, {})),
                                     kernel=kernel,
                                     **kernel_params.get(kernel, {}))
                kpcovr.fit(self.X, self.Y)
Пример #2
0
 def test_nonfitted_failure(self):
     """
     This test checks that KernelPCovR will raise a `NonFittedError` if
     `transform` is called before the model is fitted
     """
     kpcovr = KernelPCovR(mixing=0.5, n_components=2, tol=1e-12)
     with self.assertRaises(exceptions.NotFittedError):
         _ = kpcovr.transform(self.X)
Пример #3
0
 def test_no_arg_predict(self):
     """
     This test checks that KernelPCovR will raise a `ValueError` if
     `predict` is called without arguments
     """
     kpcovr = KernelPCovR(mixing=0.5, n_components=2, tol=1e-12)
     kpcovr.fit(self.X, self.Y)
     with self.assertRaises(ValueError):
         _ = kpcovr.predict()
Пример #4
0
 def test_T_shape(self):
     """
     This test checks that KernelPCovR returns a latent space projection
     consistent with the shape of the input matrix
     """
     n_components = 5
     kpcovr = KernelPCovR(mixing=0.5, n_components=n_components, tol=1e-12)
     kpcovr.fit(self.X, self.Y)
     T = kpcovr.transform(self.X)
     self.assertTrue(check_X_y(self.X, T, multi_output=True))
     self.assertTrue(T.shape[-1] == n_components)
Пример #5
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.random_state = np.random.RandomState(0)

        self.error_tol = 1e-6

        self.X, self.Y = get_dataset(return_X_y=True)

        # for the sake of expedience, only use a subset of the dataset
        idx = self.random_state.choice(len(self.X), 1000)
        self.X = self.X[idx]
        self.Y = self.Y[idx]

        # artificial second property
        self.Y = np.array([
            self.Y, self.X @ self.random_state.randint(-2, 2,
                                                       (self.X.shape[-1], ))
        ]).T
        self.Y = self.Y.reshape(self.X.shape[0], -1)

        self.X = SFS().fit_transform(self.X)
        self.Y = SFS(column_wise=True).fit_transform(self.Y)

        self.model = lambda mixing=0.5, regressor=KernelRidge(
            alpha=1e-8), **kwargs: KernelPCovR(mixing,
                                               regressor=regressor,
                                               svd_solver=kwargs.pop(
                                                   "svd_solver", "full"),
                                               **kwargs)
Пример #6
0
    def test_lr_with_x_errors(self):
        """
        This test checks that KernelPCovR returns a non-null property prediction
        and that the prediction error increases with `mixing`
        """
        prev_error = -1.0

        for i, mixing in enumerate(np.linspace(0, 1, 6)):

            kpcovr = KernelPCovR(mixing=mixing, n_components=2, tol=1e-12)
            kpcovr.fit(self.X, self.Y)

            error = (np.linalg.norm(self.Y - kpcovr.predict(self.X))**2.0 /
                     np.linalg.norm(self.Y)**2.0)

            with self.subTest(error=error):
                self.assertFalse(np.isnan(error))
            with self.subTest(error=error, alpha=round(mixing, 4)):
                self.assertGreaterEqual(error, prev_error - self.error_tol)

            prev_error = error
Пример #7
0
    def test_linear_matches_pcovr(self):
        """
        This test checks that KernelPCovR returns the same results as PCovR when
        using a linear kernel
        """

        ridge = RidgeCV(fit_intercept=False, alphas=np.logspace(-8, 2))
        ridge.fit(self.X, self.Y)

        # common instantiation parameters for the two models
        hypers = dict(
            mixing=0.5,
            n_components=1,
        )

        # computing projection and predicton loss with linear KernelPCovR
        # and use the alpha from RidgeCV for level regression comparisons
        kpcovr = KernelPCovR(regressor=KernelRidge(alpha=ridge.alpha_,
                                                   kernel="linear"),
                             kernel="linear",
                             fit_inverse_transform=True,
                             **hypers)
        kpcovr.fit(self.X, self.Y)
        ly = (np.linalg.norm(self.Y - kpcovr.predict(self.X))**2.0 /
              np.linalg.norm(self.Y)**2.0)

        # computing projection and predicton loss with PCovR
        ref_pcovr = PCovR(**hypers, regressor=ridge, space="sample")
        ref_pcovr.fit(self.X, self.Y)
        ly_ref = (np.linalg.norm(self.Y - ref_pcovr.predict(self.X))**2.0 /
                  np.linalg.norm(self.Y)**2.0)

        t_ref = ref_pcovr.transform(self.X)
        t = kpcovr.transform(self.X)

        K = kpcovr._get_kernel(self.X)

        k_ref = t_ref @ t_ref.T
        k = t @ t.T

        lk_ref = np.linalg.norm(K - k_ref)**2.0 / np.linalg.norm(K)**2.0
        lk = np.linalg.norm(K - k)**2.0 / np.linalg.norm(K)**2.0

        rounding = 3
        self.assertEqual(
            round(ly, rounding),
            round(ly_ref, rounding),
        )

        self.assertEqual(
            round(lk, rounding),
            round(lk_ref, rounding),
        )
Пример #8
0
    def test_reconstruction_errors(self):
        """
        This test checks that KernelPCovR returns a non-null reconstructed X
        and that the reconstruction error decreases with `mixing`
        """

        prev_error = 10.0
        prev_x_error = 10.0

        for i, mixing in enumerate(np.linspace(0, 1, 6)):
            kpcovr = KernelPCovR(mixing=mixing,
                                 n_components=2,
                                 fit_inverse_transform=True,
                                 tol=1e-12)
            kpcovr.fit(self.X, self.Y)

            t = kpcovr.transform(self.X)
            K = kpcovr._get_kernel(self.X)
            x = kpcovr.inverse_transform(t)

            error = np.linalg.norm(K - t @ t.T)**2.0 / np.linalg.norm(K)**2.0
            x_error = np.linalg.norm(self.X - x)**2.0 / np.linalg.norm(
                self.X)**2.0

            with self.subTest(error=error):
                self.assertFalse(np.isnan(error))
            with self.subTest(error=error, alpha=round(mixing, 4)):
                self.assertLessEqual(error, prev_error + self.error_tol)

            with self.subTest(error=x_error):
                self.assertFalse(np.isnan(x_error))
            with self.subTest(error=x_error, alpha=round(mixing, 4)):
                self.assertLessEqual(x_error, prev_x_error + self.error_tol)

            prev_error = error
            prev_x_error = x_error
Пример #9
0
 def test_none_regressor(self):
     kpcovr = KernelPCovR(mixing=0.5, regressor=None)
     kpcovr.fit(self.X, self.Y)
     self.assertTrue(kpcovr.regressor is None)
     self.assertTrue(kpcovr.regressor_ is not None)