示例#1
0
    def _fit(self, x, y=None):
        """Fit the PCA using input data.

        Parameters
        ----------
        x : array_like
            Training data, 2-Dim array like object with shape
            (n_patterns, n_features), where each row is a pattern
            of n_features columns.
        y : CArray or None, optional
            Flat array with the label of each pattern.
            Can be None if not required by the preprocessing algorithm.

        Returns
        -------
        CPCA
            Instance of the trained transformer.

        Examples
        --------
        >>> from secml.array import CArray
        >>> from secml.ml.features.reduction import CPCA

        >>> array = CArray([[1., 0., 2.], [2., 5., 0.], [0., 1., -9.]])
        >>> pca = CPCA().fit(array)
        >>> pca.eigenval
        CArray(3,)(dense: [8.390159e+00 3.777816e+00 1.909570e-17])
        >>> pca.eigenvec
        CArray(3, 3)(dense: [[-0.486132 -0.656005  0.57735 ] [-0.325051  0.749005  0.57735 ] [ 0.811183 -0.093     0.57735 ]])
        >>> pca.explained_variance
        CArray(3,)(dense: [3.519739e+01 7.135946e+00 1.823230e-34])
        >>> pca.explained_variance_ratio
        CArray(3,)(dense: [8.314343e-01 1.685657e-01 4.306842e-36])

        """
        data_carray = CArray(x).todense().atleast_2d()
        # Max number of components is the number of patterns available (rows)
        n_samples = data_carray.shape[0]
        n_features = data_carray.shape[1]

        if self.n_components is None:
            self.n_components = min(n_samples, n_features)
        else:
            if self.n_components > n_samples:
                raise ValueError(
                    "maximum number of components is {:}".format(n_samples))

        # Centering training data
        self._mean = data_carray.mean(axis=0, keepdims=False)
        data_carray -= self.mean

        # Performing training of PCA (used by KernelPCA too)
        return self._svd_train(data_carray)
    def _objective_function(self, xc, acc=False):
        """
        Parameters
        ----------
        xc: poisoning point

        Returns
        -------
        f_obj: values of objective function (average hinge loss) at x
        """

        # index of poisoning point within xc.
        # This will be replaced by the input parameter xc
        if self._idx is None:
            idx = 0
            self._xc = xc
            self._yc = 1
        else:
            idx = self._idx

        xc = CArray(xc).atleast_2d()

        n_samples = xc.shape[0]
        if n_samples > 1:
            raise TypeError("xc is not a single sample!")

        self._xc[idx, :] = xc
        clf, tr = self._update_poisoned_clf()

        # targeted attacks
        y_ts = self._y_target if self._y_target is not None else self.val.Y

        y_pred, score = clf.predict(self.val.X, return_decision_function=True)

        # TODO: binary loss check
        if self._attacker_loss.class_type != 'softmax':
            score = CArray(score[:, 1].ravel())

        if acc is True:
            error = CArray(y_ts != y_pred).ravel()  # compute test error
        else:
            error = self._attacker_loss.loss(y_ts, score)
        obj = error.mean()

        return obj