3
3
# ------------------------------------------------------------------
4
4
5
5
"""
6
- EigenAnalysis(proj, ndim =nothing)
6
+ EigenAnalysis(proj; maxdim =nothing, pratio=1.0 )
7
7
8
8
The eigenanalysis of the covariance with a given projection `proj`.
9
- The number of dimensions of the output is defined by the `ndim` argument.
9
+ Optionally specify the maximum number of dimensions in the output `maxdim`
10
+ and the percentage of variance to retain `pratio`. Default to all dimensions of
11
+ the input.
10
12
11
13
## Projections
12
14
@@ -32,26 +34,30 @@ for more details about these three variants of eigenanalysis.
32
34
EigenAnalysis(:V)
33
35
EigenAnalysis(:VD)
34
36
EigenAnalysis(:VDV)
35
- EigenAnalysis(:V, 2)
37
+ EigenAnalysis(:V, maxdim=3)
38
+ EigenAnalysis(:VD, pratio=0.99)
39
+ EigenAnalysis(:VDV, maxdim=3, pratio=0.99)
36
40
```
37
41
"""
38
42
struct EigenAnalysis <: Transform
39
43
proj:: Symbol
40
- ndim:: Union{Int,Nothing}
44
+ maxdim:: Union{Int,Nothing}
45
+ pratio:: Float64
41
46
42
- function EigenAnalysis (proj, ndim = nothing )
47
+ function EigenAnalysis (proj, maxdim, pratio )
43
48
@assert proj ∈ (:V , :VD , :VDV ) " Invalid projection."
44
- new (proj, ndim)
49
+ @assert 0 ≤ pratio ≤ 1 " Invalid pratio."
50
+ new (proj, maxdim, pratio)
45
51
end
46
52
end
47
53
54
+ EigenAnalysis (proj; maxdim= nothing , pratio= 1.0 ) =
55
+ EigenAnalysis (proj, maxdim, pratio)
56
+
48
57
assertions (:: Type{EigenAnalysis} ) = [assert_continuous]
49
58
50
59
isrevertible (:: Type{EigenAnalysis} ) = true
51
60
52
- _ndim (ndim:: Int , X) = ndim
53
- _ndim (ndim:: Nothing , X) = size (X, 2 )
54
-
55
61
function apply (transform:: EigenAnalysis , table)
56
62
# basic checks
57
63
for assertion in assertions (transform)
@@ -65,21 +71,18 @@ function apply(transform::EigenAnalysis, table)
65
71
# table as matrix
66
72
X = Tables. matrix (table)
67
73
68
- # output dimension
69
- d = _ndim (transform. ndim, X)
70
-
71
74
# center the data
72
75
μ = mean (X, dims= 1 )
73
76
Y = X .- μ
74
77
75
78
# eigenanalysis of covariance
76
- S, S⁻¹ = eigenmatrices (transform, Y, d )
79
+ S, S⁻¹ = eigenmatrices (transform, Y)
77
80
78
81
# project the data
79
82
Z = Y * S
80
83
81
84
# column names
82
- names = Symbol .(:PC , 1 : d )
85
+ names = Symbol .(:PC , 1 : size (Z, 2 ) )
83
86
84
87
# table with transformed columns
85
88
𝒯 = (; zip (names, eachcol (Z))... )
@@ -115,9 +118,6 @@ function reapply(transform::EigenAnalysis, table, cache)
115
118
# table as matrix
116
119
X = Tables. matrix (table)
117
120
118
- # output dimension
119
- d = _ndim (transform. ndim, X)
120
-
121
121
# retrieve cache
122
122
μ, S, S⁻¹, onames = cache
123
123
@@ -128,14 +128,26 @@ function reapply(transform::EigenAnalysis, table, cache)
128
128
Z = Y * S
129
129
130
130
# column names
131
- names = Symbol .(:PC , 1 : d )
131
+ names = Symbol .(:PC , 1 : size (Z, 2 ) )
132
132
133
133
# table with transformed columns
134
134
𝒯 = (; zip (names, eachcol (Z))... )
135
135
𝒯 |> Tables. materializer (table)
136
136
end
137
137
138
- function eigenmatrices (transform, Y, d)
138
+ _maxdim (maxdim:: Int , Y) = maxdim
139
+ _maxdim (:: Nothing , Y) = size (Y, 2 )
140
+
141
+ function outdim (transform, Y, λ)
142
+ pratio = transform. pratio
143
+ csums = cumsum (λ)
144
+ ratios = csums ./ last (csums)
145
+ mdim = _maxdim (transform. maxdim, Y)
146
+ pdim = findfirst (≥ (pratio), ratios)
147
+ min (mdim, pdim)
148
+ end
149
+
150
+ function eigenmatrices (transform, Y)
139
151
proj = transform. proj
140
152
141
153
Σ = cov (Y)
@@ -154,56 +166,65 @@ function eigenmatrices(transform, Y, d)
154
166
S⁻¹ = V * Λ * transpose (V)
155
167
end
156
168
169
+ d = outdim (transform, Y, λ)
170
+
157
171
S[:, 1 : d], S⁻¹[1 : d, :]
158
172
end
159
173
160
174
"""
161
- PCA(ndim =nothing)
175
+ PCA(; maxdim =nothing, pratio=1.0 )
162
176
163
177
The PCA transform is a shortcut for
164
- `ZScore() → EigenAnalysis(:V, ndim )`.
178
+ `ZScore() → EigenAnalysis(:V; maxdim, pratio )`.
165
179
166
180
See also: [`ZScore`](@ref), [`EigenAnalysis`](@ref).
167
181
168
182
# Examples
169
183
170
184
```julia
171
- PCA()
172
- PCA(2)
185
+ PCA(maxdim=2)
186
+ PCA(pratio=0.86)
187
+ PCA(maxdim=2, pratio=0.86)
173
188
```
174
189
"""
175
- PCA (ndim= nothing ) = ZScore () → EigenAnalysis (:V , ndim)
190
+ PCA (; maxdim= nothing , pratio= 1.0 ) =
191
+ ZScore () → EigenAnalysis (:V , maxdim, pratio)
176
192
177
193
"""
178
- DRS(ndim =nothing)
194
+ DRS(; maxdim =nothing, pratio=1.0 )
179
195
180
196
The DRS transform is a shortcut for
181
- `ZScore() → EigenAnalysis(:VD, ndim )`.
197
+ `ZScore() → EigenAnalysis(:VD; maxdim, pratio )`.
182
198
183
199
See also: [`ZScore`](@ref), [`EigenAnalysis`](@ref).
184
200
185
201
# Examples
186
202
187
203
```julia
188
- DRS()
189
- DRS(3)
204
+ DRS(maxdim=3)
205
+ DRS(pratio=0.87)
206
+ DRS(maxdim=3, pratio=0.87)
190
207
```
191
208
"""
192
- DRS (ndim= nothing ) = ZScore () → EigenAnalysis (:VD , ndim)
209
+ DRS (; maxdim= nothing , pratio= 1.0 ) =
210
+ ZScore () → EigenAnalysis (:VD , maxdim, pratio)
193
211
194
212
"""
195
- SDS(ndim =nothing)
213
+ SDS(; maxdim =nothing, pratio=1.0 )
196
214
197
215
The SDS transform is a shortcut for
198
- `ZScore() → EigenAnalysis(:VDV, ndim )`.
216
+ `ZScore() → EigenAnalysis(:VDV; maxdim, pratio )`.
199
217
200
218
See also: [`ZScore`](@ref), [`EigenAnalysis`](@ref).
201
219
202
220
# Examples
203
221
204
222
```julia
205
223
SDS()
206
- SDS(4)
224
+ SDS(maxdim=4)
225
+ SDS(pratio=0.88)
226
+ SDS(maxdim=4, pratio=0.88)
207
227
```
208
228
"""
209
- SDS (ndim= nothing ) = ZScore () → EigenAnalysis (:VDV , ndim)
229
+ SDS (; maxdim= nothing , pratio= 1.0 ) =
230
+ ZScore () → EigenAnalysis (:VDV , maxdim, pratio)
0 commit comments