Beispiel #1
0
 def fit(self, views: Iterable[np.ndarray], y=None, **kwargs):
     views = _check_views(
         *views, copy=self.copy_data, accept_sparse=self.accept_sparse
     )
     views = self._centre_scale(views)
     self.n_views = len(views)
     self.n = views[0].shape[0]
     self._check_params()
     self.train_views = views
     self.knns = [
         NearestNeighbors(n_neighbors=self.nearest_neighbors[i]).fit(view)
         for i, view in enumerate(views)
     ]
     NNs = [
         self.knns[i].kneighbors(view, self.nearest_neighbors[i])
         for i, view in enumerate(views)
     ]
     kernels = [self._get_kernel(i, view) for i, view in enumerate(self.train_views)]
     self.Ws = [fill_w(kernel, inds) for kernel, (dists, inds) in zip(kernels, NNs)]
     self.Ws = [
         self.Ws[0] / self.Ws[0].sum(axis=1, keepdims=True),
         self.Ws[1] / self.Ws[1].sum(axis=0, keepdims=True),
     ]
     S = self.Ws[0] @ self.Ws[1]
     U, S, Vt = np.linalg.svd(S)
     self.f = U[:, 1 : self.latent_dims + 1] * np.sqrt(self.n)
     self.g = Vt[1 : self.latent_dims + 1, :].T * np.sqrt(self.n)
     self.S = S[1 : self.latent_dims + 1]
     return self
Beispiel #2
0
    def transform(self, views: Iterable[np.ndarray], **kwargs):
        """
        Transforms data given a fit model

        :param views: numpy arrays with the same number of rows (samples) separated by commas
        :param kwargs: any additional keyword arguments required by the given model
        """
        check_is_fitted(self, attributes=["f", "g"])
        views = _check_views(
            *views, copy=self.copy_data, accept_sparse=self.accept_sparse
        )
        views = self._centre_scale_transform(views)
        nns = [
            self.knns[i].kneighbors(view, self.nearest_neighbors[i])
            for i, view in enumerate(views)
        ]
        kernels = [
            self._get_kernel(i, self.train_views[i], Y=view)
            for i, view in enumerate(views)
        ]
        Wst = [fill_w(kernel, inds) for kernel, (dists, inds) in zip(kernels, nns)]
        Wst = [
            Wst[0] / Wst[0].sum(axis=1, keepdims=True),
            Wst[1] / Wst[1].sum(axis=1, keepdims=True),
        ]
        St = [Wst[0] @ self.Ws[1], Wst[1] @ self.Ws[0]]
        return St[0] @ self.g * (1 / self.S), St[1] @ self.f * (1 / self.S)
Beispiel #3
0
    def fit(self, views: Iterable[np.ndarray], y=None, **kwargs):
        """
        Fits a regularised CCA (canonical ridge) model

        :param views: list/tuple of numpy arrays or array likes with the same number of rows (samples)
        """
        views = _check_views(*views,
                             copy=self.copy_data,
                             accept_sparse=self.accept_sparse)
        views = self._centre_scale(views)
        self.n_views = len(views)
        self.n = views[0].shape[0]
        self._check_params()
        views, C, D = self._setup_evp(views, **kwargs)
        self._solve_evp(views, C, D, **kwargs)
        return self
Beispiel #4
0
    def fit(self, views: Iterable[np.ndarray], y=None, **kwargs):
        """
        Fits the model by running an inner loop to convergence and then using either CCA or PLS deflation

        :param views: list/tuple of numpy arrays or array likes with the same number of rows (samples)
        """
        views = _check_views(*views,
                             copy=self.copy_data,
                             accept_sparse=self.accept_sparse)
        views = self._centre_scale(views)
        self.n_views = len(views)
        self.n = views[0].shape[0]
        if isinstance(self.initialization, str):
            initializer = _default_initializer(views, self.initialization,
                                               self.random_state,
                                               self.latent_dims)
        else:
            initializer = self.initialization()
        n = views[0].shape[0]
        p = [view.shape[1] for view in views]
        # List of d: p x k
        self.weights = [np.zeros((p_, self.latent_dims)) for p_ in p]
        self.loadings = [np.zeros((p_, self.latent_dims)) for p_ in p]

        # List of d: n x k
        self.scores = [np.zeros((n, self.latent_dims)) for _ in views]

        residuals = copy.deepcopy(list(views))
        self.track = []
        # For each of the dimensions
        for k in range(self.latent_dims):
            self._set_loop_params()
            self.loop = self.loop.fit(*residuals,
                                      initial_scores=next(initializer))
            for i, residual in enumerate(residuals):
                self.weights[i][:, k] = self.loop.weights[i].ravel()
                self.scores[i][:, k] = self.loop.scores[i].ravel()
                self.loadings[i][:, k] = np.dot(self.scores[i][:, k], residual)
                residuals[i] = self._deflate(residuals[i], self.scores[i][:,
                                                                          k],
                                             self.weights[i][:, k])
            self.track.append(self.loop.track)
            if not self.track[-1]["converged"]:
                warnings.warn(
                    f"Inner loop {k} not converged. Increase number of iterations."
                )
        return self
Beispiel #5
0
    def transform(self, views: Iterable[np.ndarray], **kwargs):
        """
        Transforms data given a fit model

        :param views: numpy arrays with the same number of rows (samples) separated by commas
        :param kwargs: any additional keyword arguments required by the given model
        """
        check_is_fitted(self, attributes=["weights"])
        views = _check_views(*views,
                             copy=self.copy_data,
                             accept_sparse=self.accept_sparse)
        views = self._centre_scale_transform(views)
        transformed_views = []
        for i, (view) in enumerate(views):
            transformed_view = view @ self.weights[i]
            transformed_views.append(transformed_view)
        return transformed_views
Beispiel #6
0
    def transform(self, views: np.ndarray, **kwargs):
        """
        Transforms data given a fit KCCA model

        :param views: list/tuple of numpy arrays or array likes with the same number of rows (samples)
        :param kwargs: any additional keyword arguments required by the given model
        """
        check_is_fitted(self, attributes=["weights"])
        views = _check_views(*views,
                             copy=self.copy_data,
                             accept_sparse=self.accept_sparse)
        views = self._centre_scale_transform(views)
        Ktest = [
            self._get_kernel(i, self.train_views[i], Y=view)
            for i, view in enumerate(views)
        ]
        transformed_views = [
            kernel.T @ self.weights[i] for i, kernel in enumerate(Ktest)
        ]
        return transformed_views
Beispiel #7
0
    def fit(self, views: Iterable[np.ndarray], y=None, **kwargs):
        """

        :param views: list/tuple of numpy arrays or array likes with the same number of rows (samples)
        """
        views = _check_views(*views,
                             copy=self.copy_data,
                             accept_sparse=self.accept_sparse)
        views = self._centre_scale(views)
        self.n_views = len(views)
        self.n = views[0].shape[0]
        self._check_params()
        # returns whitened views along with whitening matrices
        whitened_views, covs_invsqrt = self._setup_tensor(*views)
        # The idea here is to form a matrix with M dimensions one for each view where at index
        # M[p_i,p_j,p_k...] we have the sum over n samples of the product of the pth feature of the
        # ith, jth, kth view etc.
        for i, el in enumerate(whitened_views):
            # To achieve this we start with the first view so M is nxp.
            if i == 0:
                M = el
            # For the remaining views we expand their dimensions to match M i.e. nx1x...x1xp
            else:
                for _ in range(len(M.shape) - 1):
                    el = np.expand_dims(el, 1)
                # Then we perform an outer product by expanding the dimensionality of M and
                # outer product with the expanded el
                M = np.expand_dims(M, -1) @ el
        M = np.mean(M, 0)
        tl.set_backend("numpy")
        M_parafac = parafac(M, self.latent_dims, verbose=False)
        self.weights = [
            cov_invsqrt @ fac for i, (view, cov_invsqrt, fac) in enumerate(
                zip(whitened_views, covs_invsqrt, M_parafac.factors))
        ]
        return self