2525from tqdm import trange
2626
2727__all__ = [
28- "GPFA "
28+ "BlockInvGPFA "
2929]
3030
3131
32- class GPFA (sklearn .base .BaseEstimator ):
33- """Gaussian Process Factor Analysis (GPFA) is a probabilistic
34- dimensionality reduction technique that extracts smooth latent
35- trajectories from noisy, high-dimensional time series data.
36- It combines Factor Analysis (FA) for dimensionality reduction with Gaussian
37- Processes (GPs) to model the time courses of the latent factors in a
38- unified, probabilistic framework.
32+ class BlockInvGPFA (sklearn .base .BaseEstimator ):
33+ """BlockInvGPFA is a high-performance implementation of Gaussian
34+ Process Factor Analysis (GPFA) is a probabilistic dimensionality
35+ reduction technique that extracts smooth latent trajectories from
36+ noisy, high-dimensional time series data. GPFA combines Factor
37+ Analysis (FA) for dimensionality reduction with Gaussian Processes
38+ (GPs) to model the time courses of the latent factors in a unified,
39+ probabilistic framework.
3940
4041 GPFA operates on a set of time-series data, where each time series is
4142 given by an ``x_dim`` x ``bins`` matrix. ``x_dim`` needs to be the same
@@ -47,6 +48,16 @@ class GPFA(sklearn.base.BaseEstimator):
4748 Please consult the :ref:`main page <gpfa_prob_model>` for more details on
4849 the underlying probabilistic model.
4950
51+ This implementation, BlockInvGPFA, builds on the core model described
52+ in [Yu et al., 2009] and is adapted from the Elephant's toolkit, with
53+ substantial algorithmic enhancements:
54+
55+ 1. It uses block-matrix identities and Schur complement updates to
56+ efficiently share kernel inversion computations across
57+ variable-length trials.
58+ 2. It introduces a new variance-explained metric to evaluate BlockInvGPFA
59+ model fits
60+
5061 Parameters
5162 ----------
5263 bin_size : float, optional, default=0.02
@@ -194,45 +205,45 @@ class GPFA(sklearn.base.BaseEstimator):
194205 Examples
195206 --------
196207 >>> import numpy as np
197- >>> from gpfa import GPFA
208+ >>> from blockinvgpfa import BlockInvGPFA
198209
199210 >>> X = np.array([[
200211 ... [3, 1, 0, 4, 1, 2, 1, 3, 4, 2, 2, 1, 2, 0, 0, 2, 2, 5, 1, 3],
201212 ... [1, 0, 2, 0, 2, 1, 4, 2, 0, 1, 4, 4, 1, 2, 8, 3, 2, 1, 3, 1],
202213 ... [2, 2, 1, 1, 3, 2, 3, 2, 2, 0, 3, 4, 1, 2, 3, 1, 4, 1, 0, 1]
203214 ... ]])
204215 >>>
205- >>> gpfa_model = GPFA (z_dim=1)
216+ >>> blockinv_gpfa = BlockInvGPFA (z_dim=1)
206217
207218 >>> # Fit the model
208- >>> gpfa_model .fit(X)
219+ >>> blockinv_gpfa .fit(X)
209220 Initializing parameters using factor analysis...
210- Fitting GPFA model ...
221+ Fitting GP parameters by EM ...
211222
212223 >>> # Infere latent variable time-courses for the same data
213- >>> Zs, _ = gpfa_model .predict()
224+ >>> Zs, _ = blockinv_gpfa .predict()
214225 >>> print(Zs)
215226 [array([[-1.18405633, -2.00878 , -0.01470251, -2.3143544 , 0.03651376,
216227 -1.06948736, 2.05355342, -0.16920794, -2.26437342, -1.21934552,
217228 1.98656088, 2.13305066, -1.14113106, 0.11319858, 6.14998095,
218229 0.89241818, 0.03509708, -1.3936327 , 0.84781358, -1.2281484 ]])]
219230
220231 >>> # Display the loading matrix (C_) and observation mean (d_) parameters
221- >>> print(gpfa_model .C_)
232+ >>> print(blockinv_gpfa .C_)
222233 [[-0.78376501]
223234 [ 1.77773876]
224235 [ 0.51134474]]
225236
226- >>> print(gpfa_model .d_)
237+ >>> print(blockinv_gpfa .d_)
227238 [1.95470037 2.08933859 1.89693338]
228239
229240 >>> # Obtaining log-likelihood scores
230- >>> llhs = gpfa_model .score()
241+ >>> llhs = blockinv_gpfa .score()
231242 >>> print(llhs)
232243 [-117.54588379661148, -107.17193271370158, ..., -100.13200154180569]
233244
234245 >>> # Evaluate the total explained variance regression score
235- >>> print(gpfa_model .variance_explained())
246+ >>> print(blockinv_gpfa .variance_explained())
236247 (0.6581475357501596, array([0.65814754]))
237248
238249
@@ -761,7 +772,7 @@ def _em(self, X):
761772
762773 if np .any (np .diag (self .R_ ) == var_floor ):
763774 warnings .warn ('Private variance floor used for one or more '
764- 'observed dimensions in GPFA .' )
775+ 'observed dimensions in BlockInvGPFA .' )
765776
766777 self .fit_info_ = {'iteration_time' : iter_time , 'log_likelihoods' : lls }
767778
@@ -1188,7 +1199,7 @@ def _fill_p_auto_sum(self, Seqs, precomp):
11881199 on the caller (which should be :func:`_learn_gp_params()`) to make
11891200 sure this is called correctly.
11901201
1191- Finally, see the notes in the GPFA README.
1202+ Finally, see the notes in the BlockInvGPFA README.
11921203 """
11931204 ############################################################
11941205 # Fill out PautoSum
0 commit comments