Skip to content

randomized_svd flip sign according to v and not u when transpose=True #5608

@lesteve

Description

@lesteve

From the randomized_svd doc:

   flip_sign: boolean, (True by default)
        The output of a singular value decomposition is only unique up to a
        permutation of the signs of the singular vectors. If `flip_sign` is
        set to `True`, the sign ambiguity is resolved by making the largest
        loadings for each component in the left singular vectors positive.

Looking at svd_flip the sign flip is done by column so that the maximum of the column is ensured to be positive (u_based_decision is True by default).

Here is an example that shows that it is not the case when transpose=True (I guess in this case the svd_flip is according to v and not u):

import numpy as np

import sklearn.utils.extmath as extmath

mat = np.arange(10 * 8).reshape(10, -1)


def max_loading_is_positive(u, v):
    return {
        'u_based': (np.abs(u).max(axis=0) == u.max(axis=0)).all(),
        'v_based': (np.abs(v).max(axis=1) == v.max(axis=1)).all()
    }


u_flipped, _, v_flipped = extmath.randomized_svd(mat, 3, flip_sign=True)
u_flipped_with_transpose, _, v_flipped_with_transpose = extmath.randomized_svd(
    mat, 3, flip_sign=True, transpose=True)

print('flipped:', max_loading_is_positive(u_flipped, v_flipped))
print('flipped_with_transpose:',
      max_loading_is_positive(
          u_flipped_with_transpose, v_flipped_with_transpose))

Output:

flipped: {'u_based': True, 'v_based': False}
flipped_with_transpose: {'u_based': False, 'v_based': True}

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugEasyWell-defined and straightforward way to resolve

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions