Skip to content

TypeError: PLSRegression._single_perm() got an unexpected keyword argument 'samples' #71

@ChangJX521

Description

@ChangJX521

TypeError: PLSRegression._single_perm() got an unexpected keyword argument 'samples'

TO Repeoduce

from pyls import pls_regression
from netneurotools.stats import gen_spinsamples

n_spins=200

coords_dir = './parcellation/fsaverage/coords'

coords_lh = np.loadtxt(os.path.join(coords_dir, '1000Parcels_7Networks_coords_lh.txt'))
coords_rh = np.loadtxt(os.path.join(coords_dir, '1000Parcels_7Networks_coords_rh.txt'))

coords = np.vstack([coords_lh, coords_rh])
hemiid = np.array([0]*500 + [1]*500)


allspins = gen_spinsamples(coords, hemiid,
                                n_rotate=n_spins,
                                method='hungarian',
                                seed=42)


results = pls_regression(
    X, Y,
    n_components=1,
    n_perm=n_spins,
    n_boot=n_spins,
    permsamples=allspins,
    permindices=True,
    seed=42
)

Expected behavior

Permutation testing should run successfully, using the provided permsamples.

Actual behavior

Fails with a TypeError, because BasePLS.permutation() calls _single_perm(..., samples=...), but PLSRegression._single_perm() expects an argument named inds, not samples.

Proposed fix

Unify parameter names between BasePLS.permutation() and PLSRegression._single_perm().
Two possible solutions:

Change call in base.py from samples=... → inds=...

Or update PLSRegression._single_perm() signature to accept samples.

The below modification to PLSRegression._single_perm() would work


    def _single_perm(self, X, Y, samples, use_permind=True, groups=None, original=None, seed=None):
        """
        Permutes `Y` (w/o replacement) and recomputes PLS decomposition

        Parameters
        ----------
        X : (S, B) array_like
            Input data matrix, where `S` is observations and `B` is features
        Y : (S, T) array_like
            Input data matrix, where `S` is observations and `T` is features
        samples : (S,) array_like
            Resampling array
        groups : None
            Do nothing; here for compatibility purposes
        original : (B, N) array_like, optional
            Weights of `X` from original (non-permuted) decomposition; used to
            to align permuted weights
        seed : {int, :obj:`numpy.random.RandomState`, None}, optional
            Seed for random number generation. Default: None

        Returns
        -------
        varexp : (L,) `numpy.ndarray`
            Variance explained by PLS decomposition of permuted data
        """

        # should permute Y (but not X) by default
        Xp, Yp = self.make_permutation(X, Y, samples)
        x_weights, varexp, _ = self.svd(Xp, Yp, seed=seed)

        if self.inputs.rotate and original is not None:
            # flip signs of weights based on correlations with `original`
            flip = np.sign(compute.efficient_corr(x_weights, original))
            x_weights *= flip
            # NOTE: should we be doing a procrustes here?

            # recompute pctvar based on new x_weight signs
            mask = get_mask(Xp, Yp)
            y_loadings = Yp[mask].T @ (Xp @ x_weights)[mask]
            varexp = np.sum(y_loadings ** 2, axis=0) / np.sum(Yp[mask] ** 2)
        else:
            varexp = np.diag(varexp)

        # need to return len-3 for compatibility purposes
        return varexp, None, None

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions