Repository: scikit-learn/scikit-learn
File: sklearn/kernel_approximation.py (Python)

Code before:
        self.n_jobs = n_jobs

    @_fit_context(prefer_skip_nested_validation=True)
    def fit(self, X, y=None):
        """Fit estimator to data.

        Samples a subset of training points, computes kernel
        on these and computes normalization matrix.

        Parameters
        ----------
        X : array-like, shape (n_samples, n_features)
            Training data, where `n_samples` is the number of samples
            and `n_features` is the number of features.

        y : array-like, shape (n_samples,) or (n_samples, n_outputs), \
                default=None
            Target values (None for unsupervised transformations).

        Returns
        -------
        self : object
            Returns the instance itself.
        """
        xp, _ = get_namespace(X)
        if X.ndim < 2:
            X = xp.reshape(X, (1, -1))
        if y is not None:
            y = xp.asarray(y, device=device(X))
        X = self._validate_data(X, accept_sparse="csr")
        rnd = check_random_state(self.random_state)
        n_samples = X.shape[0]

        # get basis vectors
        if self.n_components > n_samples:
            # XXX should we just bail?
            n_components = n_samples
            warnings.warn(
                "n_components > n_samples. This is not possible.\n"
                "n_components was set to n_samples, which results"
                " in inefficient evaluation of the full kernel."
            )

        else:
            n_components = self.n_components
        n_components = min(n_samples, n_components)
        inds = rnd.permutation(n_samples)
        basis_inds = xp.asarray(inds[:n_components], dtype=xp.int64)
        basis = xp.take(X, basis_inds, axis=0)

        basis_kernel = pairwise_kernels(

Review comment (suggestion):
We should not access `X.ndim` before the call to `self._validate_data(X, accept_sparse="csr")` a few lines below.

Furthermore, `self._validate_data` itself is in charge of checking the shape of `X` by passing appropriate values to `**check_params` if needed.

However, all scikit-learn estimators are expected to raise a standardized error message when input data is 1D. `self._validate_data` is in doing this automatically by default so there is no need to do it manually.

Code after:
        "degree": [Interval(Real, 1, None, closed="left"), None],
        "kernel_params": [dict, None],
        "n_components": [Interval(Integral, 1, None, closed="left")],
        "random_state": ["random_state"],
        "n_jobs": [Integral, None],
    }

    def __init__(
        self,
        kernel="rbf",
        *,
        gamma=None,
        coef0=None,
        degree=None,
        kernel_params=None,
        n_components=100,
        random_state=None,
        n_jobs=None,
    ):
        self.kernel = kernel
        self.gamma = gamma
        self.coef0 = coef0
        self.degree = degree
        self.kernel_params = kernel_params
        self.n_components = n_components
        self.random_state = random_state
        self.n_jobs = n_jobs

    @_fit_context(prefer_skip_nested_validation=True)
    def fit(self, X, y=None):
        """Fit estimator to data.

        Samples a subset of training points, computes kernel
        on these and computes normalization matrix.

        Parameters
        ----------
        X : array-like, shape (n_samples, n_features)
            Training data, where `n_samples` is the number of samples
            and `n_features` is the number of features.

        y : array-like, shape (n_samples,) or (n_samples, n_outputs), \
                default=None
            Target values (None for unsupervised transformations).

        Returns
        -------
        self : object
            Returns the instance itself.
        """
        xp, _, device = get_namespace_and_device(X)