예제 #1
0
    def _get_gramians(self, X):
        """
        Parameters
        ----------
        X: array, (n_dims, n_samples)

        Returns
        -------
        G: array, (n_class, n_subdims, n_subdims)
            gramian matricies of references of each class
        """

        # _X, (n_dims, n_samples)
        # K, (n_samples, n_samples)
        K = rbf_kernel(X, X, self.sigma)
        # in_coeff, (n_samles, test_n_subdims)
        in_coeff, _ = dual_vectors(K, self.test_n_subdims)

        gramians = []
        for i in range(self.n_data):
            # ref_X, (n_dims, n_samples_ref_X)
            # ref_coeff, (n_samples_ref_X, n_subdims)
            ref_X, ref_coeff = self.dic[i]

            # _K, (n_samples_ref_X, n_samples)
            _K = rbf_kernel(ref_X, X, self.sigma)
            # S, (n_subdims, test_n_subdims)
            S = ref_coeff.T.dot(_K.dot(in_coeff))
            gramians.append(S)
        return np.array(gramians)
예제 #2
0
    def fast_predict_proba(self, X):
        """
        Predict class probabilities

        Parameters:
        -----------
        X: list of 2d-arrays, (n_vector_sets, n_samples, n_dims)
            List of input vector sets.

        Returns:
        --------
        pred: array, (n_vector_sets)
            Prediction array

        """

        n_input = len(X)
        n_ref = len(self.dic)

        # preprocessing data matricies
        X = self._prepare_X(X)

        # manage reference informations
        ref_Xs, ref_coeffs = [], []
        for ref_X, ref_coeff in self.dic:
            ref_Xs.append(ref_X)
            ref_coeffs.append(ref_coeff)

        ref_mappings = np.array([
            i for i in range(len(ref_Xs))
            for _ in range(ref_coeffs[i].shape[1])
        ])
        ref_Xs = np.hstack(ref_Xs)
        ref_coeffs = block_diag(*ref_coeffs)

        in_coeffs = []
        for _X in X:
            K = rbf_kernel(_X, _X, self.sigma)
            in_coeff, _ = dual_vectors(K, self.n_subdims)
            in_coeffs.append(in_coeff)
        in_mappings = np.array(
            [i for i in range(n_input) for _ in range(in_coeffs[i].shape[1])])
        in_Xs = np.hstack(X)
        in_coeffs = block_diag(*in_coeffs)

        K = rbf_kernel(in_Xs, ref_Xs)
        del ref_Xs, in_Xs

        S = in_coeffs.T.dot(K).dot(ref_coeffs)
        del in_coeffs, ref_coeffs, K

        pred = np.zeros((n_input, n_ref), dtype=np.float64)
        for i in range(n_input):
            for j in range(n_ref):
                pred[i, j] = mean_square_singular_values(
                    S[in_mappings == i][:, ref_mappings == j])

        del S, X
        return np.array(pred)
예제 #3
0
    def _fit(self, X, y):
        """
        Parameters
        ----------
        X: list of 2d-arrays, (n_classes, n_dims, n_samples)
        y: array, (n_classes)
        """
        coeff = []
        for _X in X:
            K = rbf_kernel(_X, _X, self.sigma)
            _coeff, _ = dual_vectors(K, self.n_subdims)
            coeff.append(_coeff)

        self.dic = list(zip(X, coeff))
예제 #4
0
    def _get_gramians(self, X):
        """
        Parameters
        ----------
        X: array, (n_dims, n_samples)

        Returns
        -------
        G: array, (n_class, n_subdims, n_subdims)
            gramian matricies of references of each class
        """

        # K, (n_class * n_samples_train, n_samples)
        K = rbf_kernel(self.train_stack_X, X)
        # X_gds, (n_gds_dims, n_samples)
        X_gds = np.dot(self.gds_coeff.T, K)

        # input subspace bases
        bases = subspace_bases(X_gds, self.n_subdims)

        # grammians, (n_classes, n_subdims, n_subdims)
        gramians = np.dot(self.dic.transpose(0, 2, 1), bases)
        return gramians
예제 #5
0
    def _fit(self, X, y):
        """
        Parameters
        ----------
        X: list of 2d-arrays, (n_classes, n_dims, n_samples)
        y: array, (n_classes)
        """

        # mapings, (n_classes * n_samples)
        mappings = np.array([
            i for i, _X in enumerate(X)
            for _ in range(_X.shape[1])
        ])

        # stack_X, (n_dims, n_classes * n_samples)
        stack_X = np.hstack(X)

        # K, (n_classes * n_samples, n_classes * n_samples)
        K = rbf_kernel(stack_X, stack_X, self.sigma)

        coeff = []
        for i, _ in enumerate(X):
            p = (mappings == i)
            # clipping K(X[y==c], X[y==c])
            # _K, (n_samples_i, n_samples_i)
            _K = K[p][:, p]
            _coeff, _ = dual_vectors(_K, self.n_subdims)
            coeff.append(_coeff)
        # coeff, (n_classes * n_samples, n_classes * n_subdims)
        coeff = block_diag(*coeff)

        # gramian, (n_classes * n_subdims, n_classes * n_subdims)
        gramian = coeff.T @ K @ coeff

        # n_gds_dims
        if 0.0 < self.n_gds_dims <= 1.0:
            n_gds_dims = int(gramian.shape[0] * self.n_gds_dims)
        else:
            n_gds_dims = self.n_gds_dims

        # coefficients of `bases in feature space` to get GDS bases in feature space
        # gds_coeff, (n_classes * n_subdims, n_gds_dims)
        gds_coeff, _ = dual_vectors(gramian, n_gds_dims, higher=False)

        # coefficients of `given data X in feature space` to get GDS bases in features space
        # gds_coeff, (n_classes * n_samples, n_gds_dims)
        gds_coeff = np.dot(coeff, gds_coeff)

        # X_gds = (GDS bases in feature space).T @ (X_stacked in feature space)
        # projection coefficients of GDS in feature space.
        # this vectors have finite dimension, such as n_gds_dims,
        # and these vectors can treat as linear feature.
        # X_gds, (n_gds_dims, n_classes * n_samples)
        X_gds = np.dot(gds_coeff.T, K)
        # X_gds, (n_classes, n_gds_dims, n_samples)
        X_gds = [X_gds[:, mappings == i] for i, _ in enumerate(X)]

        # dic, (n_classes, n_dims, n_subdims)
        dic = [subspace_bases(_X, self.n_subdims) for _X in X_gds]
        dic = np.array(dic)

        self.train_stack_X = stack_X
        self.mappings = mappings
        self.gds_coeff = gds_coeff
        self.dic = dic
예제 #6
0
    def fast_predict_proba(self, X):
        """
        Predict class probabilities

        Parameters:
        -----------
        X: list of 2d-arrays, (n_vector_sets, n_samples, n_dims)
            List of input vector sets.

        Returns:
        --------
        pred: array, (n_vector_sets)
            Prediction array

        """

        n_input = len(X)
        n_ref = len(self.dic)

        # preprocessing data matricies
        X = self._prepare_X(X)

        # manage reference informations
        ref_Xs, ref_coeffs = [], []
        for ref_X, ref_coeff in self.dic:
            ref_Xs.append(ref_X)
            ref_coeffs.append(ref_coeff)

        ref_mappings = np.array([
            i for i in range(len(ref_Xs))
            for _ in range(ref_coeffs[i].shape[1])
        ])
        ref_Xs = np.hstack(ref_Xs)
        ref_coeffs = block_diag(*ref_coeffs)

        in_coeffs = []
        for _X in X:
            K = rbf_kernel(_X, _X, self.sigma)
            in_coeff, _ = dual_vectors(K, self.test_n_subdims)
            in_coeffs.append(in_coeff)
        in_mappings = np.array(
            [i for i in range(n_input) for _ in range(in_coeffs[i].shape[1])])
        in_Xs = np.hstack(X)
        in_coeffs = block_diag(*in_coeffs)

        K = rbf_kernel(in_Xs, ref_Xs, self.sigma)
        del ref_Xs, in_Xs

        S = in_coeffs.T.dot(K).dot(ref_coeffs)
        del in_coeffs, ref_coeffs, K

        # Split matrix into (n_input x n_ref) blocks
        in_split = np.where(np.diff(np.pad(in_mappings, (1, 0),
                                           'constant')))[0]
        ref_split = np.where(np.diff(np.pad(ref_mappings, (1, 0),
                                            'constant')))[0]
        S = [np.hsplit(_S, ref_split) for _S in np.vsplit(S, in_split)]

        vmssv = np.vectorize(lambda i, j: mean_square_singular_values(S[i][j]))
        pred = vmssv(*np.meshgrid(np.arange(n_input), np.arange(n_ref))).T

        del S, X
        return np.array(pred)