Skip to content

cca_zoo.datasets

Utilities for generating and loading multiview datasets.


make_joint_data

make_joint_data(
    n_samples: int = ...,
    n_features: int | list[int] = ...,
    n_views: int = ...,
    n_components: int = ...,
    signal_to_noise: float | list[float] = ...,
    random_state: int | RandomState | None = ...,
    return_latent: Literal[False] = ...,
) -> list[np.ndarray]
make_joint_data(
    n_samples: int = ...,
    n_features: int | list[int] = ...,
    n_views: int = ...,
    n_components: int = ...,
    signal_to_noise: float | list[float] = ...,
    random_state: int | RandomState | None = ...,
    *,
    return_latent: Literal[True],
) -> tuple[list[np.ndarray], np.ndarray]
make_joint_data(
    n_samples: int = 100,
    n_features: int | list[int] = 10,
    n_views: int = 2,
    n_components: int = 1,
    signal_to_noise: float | list[float] = 1.0,
    random_state: int | RandomState | None = None,
    return_latent: bool = False,
) -> list[np.ndarray] | tuple[list[np.ndarray], np.ndarray]

Generate multiview data from a linear latent variable model.

Each view is x_i = z @ W_i.T + noise_i, where z ~ N(0, I) is the shared latent variable of dimension n_components, W_i ~ N(0, I) is the view's loading matrix, and noise_i ~ N(0, I / signal_to_noise). For independent training and test sets, generate once and split with :func:sklearn.model_selection.train_test_split, which takes every view at once.

Parameters:

Name Type Description Default
n_samples int

Number of observations. Default is 100.

100
n_features int | list[int]

Features per view: a single integer for every view or a list with one entry per view. Default is 10.

10
n_views int

Number of views. Default is 2.

2
n_components int

Dimension of the shared latent variable. Default is 1.

1
signal_to_noise float | list[float]

Signal-to-noise ratio, a single float for every view or a list with one entry per view; higher means less noise. Default is 1.0.

1.0
random_state int | RandomState | None

Seed or RandomState for reproducible output.

None
return_latent bool

Also return the latent variable z. Default is False.

False

Returns:

Type Description
list[ndarray] | tuple[list[ndarray], ndarray]

The list of views, each of shape (n_samples, n_features_i); with

list[ndarray] | tuple[list[ndarray], ndarray]

return_latent, a tuple (views, z) with z of shape

list[ndarray] | tuple[list[ndarray], ndarray]

(n_samples, n_components).

Raises:

Type Description
ValueError

If a per-view list has the wrong length.

Examples:

>>> from sklearn.model_selection import train_test_split
>>> from cca_zoo.datasets import make_joint_data
>>> views = make_joint_data(n_samples=200, n_components=2, random_state=0)
>>> [v.shape for v in views]
[(200, 10), (200, 10)]
>>> X1_train, X1_test, X2_train, X2_test = train_test_split(
...     *views, random_state=0
... )
Source code in cca_zoo/datasets/_simulated.py
@validate_params(
    {
        "n_samples": [Interval(Integral, 1, None, closed="left")],
        "n_features": [Interval(Integral, 1, None, closed="left"), list],
        "n_views": [Interval(Integral, 1, None, closed="left")],
        "n_components": [Interval(Integral, 1, None, closed="left")],
        "signal_to_noise": [Interval(Real, 0, None, closed="neither"), list],
        "random_state": ["random_state"],
        "return_latent": ["boolean"],
    },
    prefer_skip_nested_validation=True,
)
def make_joint_data(
    n_samples: int = 100,
    n_features: int | list[int] = 10,
    n_views: int = 2,
    n_components: int = 1,
    signal_to_noise: float | list[float] = 1.0,
    random_state: int | np.random.RandomState | None = None,
    return_latent: bool = False,
) -> list[np.ndarray] | tuple[list[np.ndarray], np.ndarray]:
    """Generate multiview data from a linear latent variable model.

    Each view is ``x_i = z @ W_i.T + noise_i``, where ``z ~ N(0, I)`` is the
    shared latent variable of dimension ``n_components``, ``W_i ~ N(0, I)``
    is the view's loading matrix, and ``noise_i ~ N(0, I / signal_to_noise)``.
    For independent training and test sets, generate once and split with
    :func:`sklearn.model_selection.train_test_split`, which takes every view
    at once.

    Args:
        n_samples: Number of observations. Default is 100.
        n_features: Features per view: a single integer for every view or a
            list with one entry per view. Default is 10.
        n_views: Number of views. Default is 2.
        n_components: Dimension of the shared latent variable. Default is 1.
        signal_to_noise: Signal-to-noise ratio, a single float for every view
            or a list with one entry per view; higher means less noise.
            Default is 1.0.
        random_state: Seed or ``RandomState`` for reproducible output.
        return_latent: Also return the latent variable ``z``. Default is
            False.

    Returns:
        The list of views, each of shape (n_samples, n_features_i); with
        ``return_latent``, a tuple ``(views, z)`` with ``z`` of shape
        (n_samples, n_components).

    Raises:
        ValueError: If a per-view list has the wrong length.

    Examples:
        >>> from sklearn.model_selection import train_test_split
        >>> from cca_zoo.datasets import make_joint_data
        >>> views = make_joint_data(n_samples=200, n_components=2, random_state=0)
        >>> [v.shape for v in views]
        [(200, 10), (200, 10)]
        >>> X1_train, X1_test, X2_train, X2_test = train_test_split(
        ...     *views, random_state=0
        ... )
    """
    rng = check_random_state(random_state)
    features = _per_view(n_features, n_views, "n_features")
    snrs = _per_view(signal_to_noise, n_views, "signal_to_noise")
    latent = rng.standard_normal((n_samples, n_components))
    views = []
    for p, snr in zip(features, snrs):
        signal = latent @ rng.standard_normal((p, n_components)).T
        views.append(signal + rng.standard_normal(signal.shape) / np.sqrt(snr))
    if return_latent:
        return views, latent
    return views

load_linnerud

load_linnerud(
    *, return_views: bool = False
) -> Bunch | list[np.ndarray]

The Linnerud data as exercise and physiological views.

:func:sklearn.datasets.load_linnerud with its data and target as views.

Parameters:

Name Type Description Default
return_views bool

Whether to return the list of views rather than a Bunch, as sklearn's return_X_y. Default is False.

False

Returns:

Type Description
Bunch | list[ndarray]

A Bunch with views (exercise and physiological, each of shape

Bunch | list[ndarray]

(20, 3)), feature_names of each view and DESCR; or the views.

Examples:

>>> from cca_zoo.datasets import load_linnerud
>>> exercise, physiological = load_linnerud(return_views=True)
>>> load_linnerud().feature_names[0]
['Chins', 'Situps', 'Jumps']
Source code in cca_zoo/datasets/_toy.py
def load_linnerud(*, return_views: bool = False) -> Bunch | list[np.ndarray]:
    """The Linnerud data as exercise and physiological views.

    :func:`sklearn.datasets.load_linnerud` with its data and target as views.

    Args:
        return_views: Whether to return the list of views rather than a
            Bunch, as sklearn's ``return_X_y``. Default is False.

    Returns:
        A Bunch with ``views`` (exercise and physiological, each of shape
        (20, 3)), ``feature_names`` of each view and ``DESCR``; or the views.

    Examples:
        >>> from cca_zoo.datasets import load_linnerud
        >>> exercise, physiological = load_linnerud(return_views=True)
        >>> load_linnerud().feature_names[0]
        ['Chins', 'Situps', 'Jumps']
    """
    dataset = datasets.load_linnerud()
    views = [np.asarray(dataset.data), np.asarray(dataset.target)]
    if return_views:
        return views
    return Bunch(
        views=views,
        feature_names=[list(dataset.feature_names), list(dataset.target_names)],
        DESCR=dataset.DESCR,
    )

load_breast_cancer

load_breast_cancer(
    *, return_views: bool = False
) -> Bunch | list[np.ndarray]

The Wisconsin breast cancer features split into two 15-feature views.

:func:sklearn.datasets.load_breast_cancer's 30 features, the first half as one view and the second as the other.

Parameters:

Name Type Description Default
return_views bool

Whether to return the list of views rather than a Bunch, as sklearn's return_X_y. Default is False.

False

Returns:

Type Description
Bunch | list[ndarray]

A Bunch with views (each of shape (569, 15)), feature_names of

Bunch | list[ndarray]

each view and DESCR; or the views.

Examples:

>>> from cca_zoo.datasets import load_breast_cancer
>>> X1, X2 = load_breast_cancer(return_views=True)
>>> X1.shape, X2.shape
((569, 15), (569, 15))
Source code in cca_zoo/datasets/_toy.py
def load_breast_cancer(*, return_views: bool = False) -> Bunch | list[np.ndarray]:
    """The Wisconsin breast cancer features split into two 15-feature views.

    :func:`sklearn.datasets.load_breast_cancer`'s 30 features, the first half
    as one view and the second as the other.

    Args:
        return_views: Whether to return the list of views rather than a
            Bunch, as sklearn's ``return_X_y``. Default is False.

    Returns:
        A Bunch with ``views`` (each of shape (569, 15)), ``feature_names`` of
        each view and ``DESCR``; or the views.

    Examples:
        >>> from cca_zoo.datasets import load_breast_cancer
        >>> X1, X2 = load_breast_cancer(return_views=True)
        >>> X1.shape, X2.shape
        ((569, 15), (569, 15))
    """
    dataset = datasets.load_breast_cancer()
    data = np.asarray(dataset.data)
    names = list(dataset.feature_names)
    half = data.shape[1] // 2
    views = [data[:, :half], data[:, half:]]
    if return_views:
        return views
    return Bunch(
        views=views, feature_names=[names[:half], names[half:]], DESCR=dataset.DESCR
    )