cca_zoo.model_selection¶
Cross-validation, hyperparameter search and significance testing for multiview models.
GridSearchCV ¶
Bases: _MultiviewSearch, GridSearchCV
Exhaustive grid search over a multiview estimator's parameters.
The multiview form of :class:~sklearn.model_selection.GridSearchCV, with its
parameters, attributes and methods. fit, transform and score
take a list of views; parameter names are the estimator's own, with
name__<view> setting one view's value of a per-view parameter;
best_estimator_ is the fitted multiview estimator; and a scoring
callable is called as scoring(estimator, views).
Examples:
>>> import numpy as np
>>> from cca_zoo.linear import RidgeCCA
>>> from cca_zoo.model_selection import GridSearchCV
>>> rng = np.random.default_rng(0)
>>> X1 = rng.standard_normal((50, 5))
>>> X2 = rng.standard_normal((50, 4))
>>> grid = {"shrinkage__0": [0.0, 0.1], "shrinkage__1": [0.0, 0.5]}
>>> gs = GridSearchCV(RidgeCCA(), param_grid=grid, cv=2).fit([X1, X2])
>>> sorted(gs.best_params_.items())
[('shrinkage__0', 0.0), ('shrinkage__1', 0.5)]
RandomizedSearchCV ¶
Bases: _MultiviewSearch, RandomizedSearchCV
Randomized search over a multiview estimator's parameters.
The multiview form of :class:~sklearn.model_selection.RandomizedSearchCV, with its
parameters, attributes and methods. fit, transform and score
take a list of views; parameter names are the estimator's own, with
name__<view> setting one view's value of a per-view parameter;
best_estimator_ is the fitted multiview estimator; and a scoring
callable is called as scoring(estimator, views).
Examples:
>>> import numpy as np
>>> from scipy.stats import loguniform
>>> from cca_zoo.linear import RidgeCCA
>>> from cca_zoo.model_selection import RandomizedSearchCV
>>> rng = np.random.default_rng(0)
>>> X1 = rng.standard_normal((50, 5))
>>> X2 = rng.standard_normal((50, 4))
>>> space = {"shrinkage__0": loguniform(1e-3, 1.0)}
>>> rs = RandomizedSearchCV(
... RidgeCCA(), space, n_iter=5, cv=2, random_state=0
... ).fit([X1, X2])
>>> sorted(rs.best_params_)
['shrinkage__0']
HalvingGridSearchCV ¶
Bases: _MultiviewSearch, HalvingGridSearchCV
Successive-halving grid search over a multiview estimator's parameters.
The multiview form of
:class:~sklearn.model_selection.HalvingGridSearchCV, with its
parameters, attributes and methods. fit, transform and score
take a list of views; parameter names are the estimator's own, with
name__<view> setting one view's value of a per-view parameter;
best_estimator_ is the fitted multiview estimator; and a scoring
callable is called as scoring(estimator, views).
Examples:
>>> import numpy as np
>>> from cca_zoo.linear import RidgeCCA
>>> from cca_zoo.model_selection import HalvingGridSearchCV
>>> rng = np.random.default_rng(0)
>>> X1 = rng.standard_normal((60, 5))
>>> X2 = rng.standard_normal((60, 4))
>>> grid = {"shrinkage__0": [0.0, 0.1, 0.5]}
>>> hgs = HalvingGridSearchCV(RidgeCCA(), grid, cv=2, random_state=0)
>>> sorted(hgs.fit([X1, X2]).best_params_)
['shrinkage__0']
HalvingRandomSearchCV ¶
Bases: _MultiviewSearch, HalvingRandomSearchCV
Successive-halving randomized search over a multiview model's parameters.
The multiview form of
:class:~sklearn.model_selection.HalvingRandomSearchCV, with its
parameters, attributes and methods. fit, transform and score
take a list of views; parameter names are the estimator's own, with
name__<view> setting one view's value of a per-view parameter;
best_estimator_ is the fitted multiview estimator; and a scoring
callable is called as scoring(estimator, views).
Examples:
>>> import numpy as np
>>> from scipy.stats import loguniform
>>> from cca_zoo.linear import RidgeCCA
>>> from cca_zoo.model_selection import HalvingRandomSearchCV
>>> rng = np.random.default_rng(0)
>>> X1 = rng.standard_normal((60, 5))
>>> X2 = rng.standard_normal((60, 4))
>>> space = {"shrinkage__0": loguniform(1e-3, 1.0)}
>>> hrs = HalvingRandomSearchCV(RidgeCCA(), space, cv=2, random_state=0)
>>> sorted(hrs.fit([X1, X2]).best_params_)
['shrinkage__0']
cross_val_score ¶
Score a multiview estimator by cross-validation.
:func:sklearn.model_selection.cross_val_score on a list of views.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
estimator
|
BaseEstimator
|
A multiview estimator. |
required |
views
|
list[ArrayLike]
|
Arrays of shape (n_samples, n_features_i), one per view. |
required |
**kwargs
|
Any
|
Passed to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
ndarray
|
The score of each fold, by default the mean canonical correlation. |
Examples:
>>> import numpy as np
>>> from cca_zoo.linear import CCA
>>> from cca_zoo.model_selection import cross_val_score
>>> rng = np.random.default_rng(0)
>>> X1, X2 = rng.standard_normal((50, 5)), rng.standard_normal((50, 4))
>>> cross_val_score(CCA(), [X1, X2], cv=3).shape
(3,)
Source code in cca_zoo/model_selection/_validation.py
cross_validate ¶
cross_validate(
estimator: BaseEstimator,
views: list[ArrayLike],
**kwargs: Any,
) -> dict[str, Any]
Evaluate a multiview estimator by cross-validation.
:func:sklearn.model_selection.cross_validate on a list of views.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
estimator
|
BaseEstimator
|
A multiview estimator. |
required |
views
|
list[ArrayLike]
|
Arrays of shape (n_samples, n_features_i), one per view. |
required |
**kwargs
|
Any
|
Passed to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
sklearn's result dictionary; with |
dict[str, Any]
|
multiview estimators. |
Source code in cca_zoo/model_selection/_validation.py
cross_val_predict ¶
cross_val_predict(
estimator: BaseEstimator,
views: list[ArrayLike],
**kwargs: Any,
) -> list[np.ndarray]
Out-of-fold scores of a multiview estimator.
:func:sklearn.model_selection.cross_val_predict with method="transform"
on a list of views: each sample is transformed by the model fitted without
its fold. Each fold's model fixes its own sign and order of components, so
compare views within a component (e.g. with
:func:cca_zoo.metrics.pairwise_correlations) rather than scores across folds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
estimator
|
BaseEstimator
|
A multiview estimator. |
required |
views
|
list[ArrayLike]
|
Arrays of shape (n_samples, n_features_i), one per view. |
required |
**kwargs
|
Any
|
Passed to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
list[ndarray]
|
Arrays of shape (n_samples, n_components), one per view. |
Examples:
>>> import numpy as np
>>> from cca_zoo.linear import CCA
>>> from cca_zoo.model_selection import cross_val_predict
>>> rng = np.random.default_rng(0)
>>> X1, X2 = rng.standard_normal((50, 5)), rng.standard_normal((50, 4))
>>> [s.shape for s in cross_val_predict(CCA(n_components=2), [X1, X2], cv=3)]
[(50, 2), (50, 2)]
Source code in cca_zoo/model_selection/_validation.py
learning_curve ¶
learning_curve(
estimator: BaseEstimator,
views: list[ArrayLike],
**kwargs: Any,
) -> tuple[np.ndarray, ...]
Cross-validated scores of a multiview estimator against training set size.
:func:sklearn.model_selection.learning_curve on a list of views.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
estimator
|
BaseEstimator
|
A multiview estimator. |
required |
views
|
list[ArrayLike]
|
Arrays of shape (n_samples, n_features_i), one per view. |
required |
**kwargs
|
Any
|
Passed to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ...]
|
sklearn's |
Source code in cca_zoo/model_selection/_validation.py
validation_curve ¶
validation_curve(
estimator: BaseEstimator,
views: list[ArrayLike],
param_name: str,
param_range: ArrayLike,
**kwargs: Any,
) -> tuple[np.ndarray, np.ndarray]
Cross-validated scores of a multiview estimator across one parameter's values.
:func:sklearn.model_selection.validation_curve on a list of views.
param_name may set one view's value of a per-view parameter, e.g.
"shrinkage__0".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
estimator
|
BaseEstimator
|
A multiview estimator. |
required |
views
|
list[ArrayLike]
|
Arrays of shape (n_samples, n_features_i), one per view. |
required |
param_name
|
str
|
Parameter to vary. |
required |
param_range
|
ArrayLike
|
Values to try. |
required |
**kwargs
|
Any
|
Passed to :func: |
{}
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
|
Examples:
>>> import numpy as np
>>> from cca_zoo.linear import RidgeCCA
>>> from cca_zoo.model_selection import validation_curve
>>> rng = np.random.default_rng(0)
>>> X1, X2 = rng.standard_normal((50, 5)), rng.standard_normal((50, 4))
>>> train, test = validation_curve(
... RidgeCCA(), [X1, X2], "shrinkage__0", [0.0, 0.5, 1.0], cv=3
... )
>>> test.shape
(3, 3)
Source code in cca_zoo/model_selection/_validation.py
permutation_test_significance ¶
permutation_test_significance(
estimator: BaseEstimator,
views: list[ArrayLike],
n_permutations: int = 1000,
random_state: int | RandomState | None = None,
n_jobs: int | None = None,
) -> PermutationTestResult
Permutation test of the canonical correlations and factor loadings.
Refits estimator on data with the rows of every view but the first
shuffled independently, which keeps each view's covariance and breaks
their correspondence. Each permuted fit's loadings are aligned to the
observed ones by orthogonal Procrustes over all views before comparison,
since permuted fits can rotate or reflect near-tied dimensions.
Only the first dimension's p-value is a valid test. Each later dimension is compared with the permuted fits' dimension of the same rank, which were fitted without removing the earlier dimensions' signal; Winkler et al. (2020) test them step-down, residualising each earlier dimension first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
estimator
|
BaseEstimator
|
An unfitted multiview estimator. |
required |
views
|
list[ArrayLike]
|
Arrays of shape (n_samples, n_features_i), one per view. |
required |
n_permutations
|
int
|
Number of permutations. Default is 1000. |
1000
|
random_state
|
int | RandomState | None
|
Seed for the permutations. Default is None. |
None
|
n_jobs
|
int | None
|
Number of parallel jobs. Default is None. |
None
|
Returns:
| Type | Description |
|---|---|
PermutationTestResult
|
The observed and null statistics. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
References
Winkler, A. M., Renaud, O., Smith, S. M., & Nichols, T. E. (2020). Permutation inference for canonical correlation analysis. NeuroImage, 220, 117065.
Examples:
>>> import numpy as np
>>> from cca_zoo.linear import CCA
>>> from cca_zoo.model_selection import permutation_test_significance
>>> rng = np.random.default_rng(0)
>>> z = rng.standard_normal((40, 1))
>>> X1 = z @ rng.standard_normal((1, 5)) + 0.1 * rng.standard_normal((40, 5))
>>> X2 = z @ rng.standard_normal((1, 4)) + 0.1 * rng.standard_normal((40, 4))
>>> result = permutation_test_significance(
... CCA(), [X1, X2], n_permutations=49, random_state=0
... )
>>> float(result.p_values[0])
0.02
Source code in cca_zoo/model_selection/_significance.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
PermutationTestResult
dataclass
¶
PermutationTestResult(
correlations: ndarray,
null_correlations: ndarray,
p_values: ndarray,
loadings: list[ndarray],
null_loadings: list[ndarray],
loading_p_values: list[ndarray],
)
Result of :func:permutation_test_significance.
Attributes:
| Name | Type | Description |
|---|---|---|
correlations |
ndarray
|
Observed canonical correlation per dimension, shape (k,). |
null_correlations |
ndarray
|
Permuted correlations, shape (n_permutations, k). |
p_values |
ndarray
|
P-value per dimension, shape (k,). |
loadings |
list[ndarray]
|
Observed factor loadings, shape (n_features_i, k) per view. |
null_loadings |
list[ndarray]
|
Permuted loadings aligned to |
loading_p_values |
list[ndarray]
|
P-value per feature and dimension, shape (n_features_i, k) per view. |