Skip to content

Commit c03ffc9

Browse files
Merge pull request #11 from MatthewSZhang/ssc
FEAT add ssc function
2 parents 735dc0c + a52b99c commit c03ffc9

File tree

5 files changed

+83
-2
lines changed

5 files changed

+83
-2
lines changed

doc/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
.. currentmodule:: fastcan
1313

1414

15-
FastCan Class
15+
API Reference
1616
~~~~~~~~~~~~~
1717
.. autosummary::
1818
:toctree: generated/
1919

2020
FastCan
21+
ssc
2122

2223

2324
...................

fastcan/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
"""
44

55
from ._fastcan import FastCan
6+
from ._ssc import ssc
67

78
__all__ = [
89
"FastCan",
10+
"ssc",
911
]

fastcan/_ssc.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""Sum squared of correlation."""
2+
3+
import numpy as np
4+
from sklearn.cross_decomposition import CCA
5+
from sklearn.utils import check_X_y
6+
from sklearn.utils._param_validation import validate_params
7+
8+
9+
@validate_params(
10+
{
11+
"X": ["array-like"],
12+
"y": ["array-like"],
13+
},
14+
prefer_skip_nested_validation=True,
15+
)
16+
def ssc(X, y):
17+
"""Sum of the squared canonical correlation coefficients.
18+
19+
Parameters
20+
----------
21+
X : array-like of shape (n_samples, n_features)
22+
Feature matrix.
23+
24+
y : array-like of shape (n_samples, n_outputs)
25+
Target matrix.
26+
27+
Returns
28+
-------
29+
ssc : float
30+
Sum of the squared canonical correlation coefficients.
31+
32+
Examples
33+
--------
34+
>>> from fastcan import ssc
35+
>>> X = [[1], [-1], [0]]
36+
>>> y = [[0], [1], [-1]]
37+
>>> ssc(X, y)
38+
np.float64(0.25)
39+
"""
40+
X, y = check_X_y(
41+
X, y, dtype=float, ensure_2d=True, multi_output=True, ensure_min_samples=2
42+
)
43+
n_components = min(X.shape[1], y.shape[1])
44+
cca = CCA(n_components=n_components)
45+
X_c, y_c = cca.fit_transform(X, y)
46+
corrcoef = np.diagonal(np.corrcoef(X_c, y_c, rowvar=False), offset=n_components)
47+
return sum(corrcoef**2)

tests/test_correlation.py renamed to tests/test_fastcan.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pylint: skip-file
21
"""Test FastCan"""
32

43
import numpy as np

tests/test_ssc.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"Test ssc"
2+
3+
import numpy as np
4+
from numpy.testing import assert_almost_equal
5+
from sklearn.linear_model import LinearRegression
6+
7+
from fastcan import ssc
8+
9+
10+
def test_pearson_r():
11+
"""Test Pearson's correlation."""
12+
rng = np.random.default_rng(12345)
13+
X = rng.random(100)
14+
y = rng.random(100)
15+
r2 = ssc(X.reshape(-1, 1), y.reshape(-1, 1))
16+
gtruth_r2 = np.corrcoef(X, y)[0, 1]**2
17+
assert_almost_equal(actual=r2, desired=gtruth_r2)
18+
19+
def test_multi_r():
20+
"""Test multiple correlation."""
21+
rng = np.random.default_rng(12345)
22+
X = rng.random((100, 10))
23+
y = rng.random(100)
24+
r2 = ssc(X, y.reshape(-1, 1))
25+
gtruth_r2 = LinearRegression().fit(X, y).score(X, y)
26+
assert_almost_equal(actual=r2, desired=gtruth_r2)
27+
28+
X = rng.random(100)
29+
y = rng.random((100, 10))
30+
r2 = ssc(X.reshape(-1, 1), y)
31+
gtruth_r2 = LinearRegression().fit(y, X).score(y, X)
32+
assert_almost_equal(actual=r2, desired=gtruth_r2)

0 commit comments

Comments
 (0)