Skip to content

Commit 9120f21

Browse files
committed
report loadings for PCA models
1 parent 21ee57d commit 9120f21

File tree

3 files changed

+68
-15
lines changed

3 files changed

+68
-15
lines changed

src/models/decomposition_models.jl

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ function MMI.fit(model::PCA, verbosity::Int, X)
3232
tresidualvar=MS.tresidualvar(fitresult),
3333
tvar=MS.var(fitresult),
3434
mean=copy(MS.mean(fitresult)),
35-
principalvars=copy(MS.principalvars(fitresult))
35+
principalvars=copy(MS.principalvars(fitresult)),
36+
# no need to copy here as a new copy is created
37+
# for each function call
38+
loadings = MS.loadings(fitresult)
3639
)
3740
return fitresult, cache, report
3841
end
@@ -175,7 +178,7 @@ function MMI.fit(model::PPCA, verbosity::Int, X)
175178
outdim=size(fitresult)[2],
176179
tvar=MS.var(fitresult),
177180
mean=copy(MS.mean(fitresult)),
178-
loadings=MS.loadings(fitresult)
181+
loadings = copy(MS.loadings(fitresult))
179182
)
180183
return fitresult, cache, report
181184
end
@@ -362,7 +365,12 @@ The fields of `report(mach)` are:
362365
363366
- `mean`: The mean of the untransformed training data, of length `indim`.
364367
365-
- `principalvars`: The variance of the principal components.
368+
- `principalvars`: The variance of the principal components. An AbstractVector of
369+
length `outdim`
370+
371+
- `loadings`: The models loadings, weights for each variable used when calculating
372+
principal components. A matrix of size (`indim`, `outdim`) where `indim` and
373+
`outdim` are as defined above.
366374
367375
# Examples
368376
@@ -669,7 +677,8 @@ The fields of `report(mach)` are:
669677
670678
- `mean`: The mean of the untransformed training data, of length `indim`.
671679
672-
- `loadings`: The factor loadings.
680+
- `loadings`: The factor loadings. A matrix of size (`indim`, `outdim`) where
681+
`indim` and `outdim` are as defined above.
673682
674683
# Examples
675684
@@ -765,8 +774,8 @@ The fields of `report(mach)` are:
765774
766775
- `tvat`: The variance of the components.
767776
768-
- `loadings`: The models loadings, weights for each variable used when calculating
769-
principal components.
777+
- `loadings`: The model's loadings matrix. A matrix of size (`indim`, `outdim`) where
778+
`indim` and `outdim` as as defined above.
770779
771780
# Examples
772781

test/models/decomposition_models.jl

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,17 @@ X, y = @load_crabs
1111
)
1212
# MLJ PCA
1313
pca_mlj = PCA(variance_ratio=variance_ratio)
14-
test_composition_model(pca_ms, pca_mlj, X, X_array)
14+
_, _, report = test_decomposition_model(pca_ms, pca_mlj, X, X_array)
15+
16+
# Test report
17+
@test report.indim == size(pca_ms)[1]
18+
@test report.outdim == size(pca_ms)[2]
19+
@test report.tprincipalvar == MS.tprincipalvar(pca_ms)
20+
@test report.tresidualvar == MS.tresidualvar(pca_ms)
21+
@test report.tvar == MS.var(pca_ms)
22+
@test report.mean == MS.mean(pca_ms)
23+
@test report.principalvars == MS.principalvars(pca_ms)
24+
@test report.loadings == MS.loadings(pca_ms)
1525
end
1626

1727
@testset "KernelPCA" begin
@@ -23,7 +33,12 @@ end
2333
)
2434
# MLJ KernelPCA
2535
kpca_mlj = KernelPCA()
26-
test_composition_model(kpca_ms, kpca_mlj, X, X_array)
36+
_, _, report = test_decomposition_model(kpca_ms, kpca_mlj, X, X_array)
37+
38+
# Test report
39+
@test report.indim == size(kpca_ms)[1]
40+
@test report.outdim == size(kpca_ms)[2]
41+
@test report.principalvars == MS.eigvals(kpca_ms)
2742
end
2843

2944
@testset "ICA" begin
@@ -47,7 +62,14 @@ end
4762
outdim=outdim,
4863
tol=tolerance,
4964
winit=randn(rng, eltype(X_array), size(X_array, 2), outdim))
50-
test_composition_model(ica_ms, ica_mlj, X, X_array, test_inverse=false)
65+
_, _, report = test_decomposition_model(
66+
ica_ms, ica_mlj, X, X_array, test_inverse=false
67+
)
68+
69+
# Test report
70+
@test report.indim == size(ica_ms)[1]
71+
@test report.outdim == size(ica_ms)[2]
72+
@test report.mean == MS.mean(ica_ms)
5173
end
5274

5375
@testset "ICA2" begin
@@ -73,7 +95,10 @@ end
7395
tol=tolerance,
7496
fun=:gaus,
7597
winit=randn(rng, eltype(X_array), size(X_array, 2), outdim))
76-
test_composition_model(ica_ms, ica_mlj, X, X_array, test_inverse=false)
98+
test_decomposition_model(
99+
ica_ms, ica_mlj, X, X_array;
100+
test_inverse=false
101+
)
77102
end
78103

79104
@testset "PPCA" begin
@@ -87,7 +112,14 @@ end
87112
)
88113
# MLJ PPCA
89114
ppca_mlj = PPCA(;tol=tolerance)
90-
test_composition_model(ppca_ms, ppca_mlj, X, X_array)
115+
_, _, report = test_decomposition_model(ppca_ms, ppca_mlj, X, X_array)
116+
117+
# Test report
118+
@test report.indim == size(ppca_ms)[1]
119+
@test report.outdim == size(ppca_ms)[2]
120+
@test report.tvar == MS.var(ppca_ms)
121+
@test report.mean == MS.mean(ppca_ms)
122+
@test report.loadings == MS.loadings(ppca_ms)
91123
end
92124

93125
@testset "FactorAnalysis" begin
@@ -102,6 +134,16 @@ end
102134
η=eta
103135
)
104136
factoranalysis_mlj = FactorAnalysis(;tol=tolerance, eta=eta)
105-
test_composition_model(factoranalysis_ms, factoranalysis_mlj, X, X_array)
137+
_, _, report = test_decomposition_model(
138+
factoranalysis_ms, factoranalysis_mlj, X, X_array
139+
)
140+
141+
# Test report
142+
@test report.indim == size(factoranalysis_ms)[1]
143+
@test report.outdim == size(factoranalysis_ms)[2]
144+
@test report.variance == MS.var(factoranalysis_ms)
145+
@test report.covariance_matrix == MS.cov(factoranalysis_ms)
146+
@test report.mean == MS.mean(factoranalysis_ms)
147+
@test report.loadings == MS.loadings(factoranalysis_ms)
106148
end
107149

test/testutils.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ function test_regression(model, X, y)
1919
return yhat, fr
2020
end
2121

22-
function test_composition_model(ms_model, mlj_model, X, X_array ; test_inverse=true)
23-
mlj_model_type = typeof(mlj_model)
22+
function test_decomposition_model(ms_model, mlj_model, X, X_array ; test_inverse=true)
2423
Xtr_ms = permutedims(
2524
MultivariateStats.predict(ms_model, permutedims(X_array))
2625
)
27-
fitresult, _, _ = fit(mlj_model, 1, X)
26+
fitresult, cache, report = fit(mlj_model, 1, X)
2827
Xtr_mlj_table = transform(mlj_model, fitresult, X)
2928
Xtr_mlj = matrix(Xtr_mlj_table)
3029
# Compare MLJ and MultivariateStats transformed matrices
@@ -43,4 +42,7 @@ function test_composition_model(ms_model, mlj_model, X, X_array ; test_inverse=t
4342
# smoke test for issue #42
4443
fp = MLJBase.fitted_params(mlj_model, fitresult)
4544
:projection in keys(fp)
45+
46+
return fitresult, cache, report
4647
end
48+

0 commit comments

Comments
 (0)