def calcHardMergeGap_SpecificPairs(self, SS, PairList): ''' Calc change in ELBO for specific list of candidate hard merge pairs Returns --------- Gaps : 1D array, size L Gap[j] : scalar change in ELBO after merge of pair in PairList[j] ''' Gaps = np.zeros(len(PairList)) XcPrior = None XcPost_K = [None for k in range(SS.K)] YcPrior = None YcPost_K = [None for k in range(SS.K)] for ii, (kA, kB) in enumerate(PairList): gapX, XcPost_K, XcPrior = DiagGaussX.calcHardMergeGapForPair( SS=SS, Post=self.Post, Prior=self.Prior, kA=kA, kB=kB, cPrior=XcPrior, cPost_K=XcPost_K) gapY, YcPost_K, YcPrior = DiagGaussX.calcHardMergeGapForPair( SS=SS, Post=self.Post, Prior=self.Prior, kA=kA, kB=kB, cPrior=YcPrior, cPost_K=YcPost_K) Gaps[ii] = gapX + gapY return Gaps
def setPostFactors(self, obsModel=None, SS=None, LP=None, Data=None, **param_kwargs): ''' Set attribute Post to provided values. ''' self.ClearCache() if obsModel is not None: if hasattr(obsModel, 'Post'): self.Post = obsModel.Post.copy() self.K = self.Post.K else: self.setPostFromEstParams(obsModel.EstParams) return if LP is not None and Data is not None: SS = self.calcSummaryStats(Data, None, LP) if SS is not None: self.updatePost(SS) else: self.Post = DiagGaussX.packParamBagForPost(**param_kwargs) self.Post = RegressY.packParamBagForPost(Post=self.Post, **param_kwargs) self.K = self.Post.K
def calcELBO_Memoized(self, SS, returnVec=0, afterMStep=False, **kwargs): """ Calculate obsModel's objective using suff stats SS and Post. Args ------- SS : bnpy SuffStatBag afterMStep : boolean flag if 1, elbo calculated assuming M-step just completed Returns ------- elbo_K : scalar float Equal to E[ log p(x) + log p(phi) - log q(phi)] """ elbo_XModel = DiagGaussX.calcELBOFromSSAndPost(SS=SS, Post=self.Post, Prior=self.Prior, returnVec=returnVec, afterMStep=afterMStep) elbo_YModel = RegressY.calcELBOFromSSAndPost(SS=SS, Post=self.Post, Prior=self.Prior, returnVec=returnVec, afterMStep=afterMStep) return elbo_XModel + elbo_YModel
def calcSummaryStats(self, Data, SS, LP, **kwargs): ''' Calculate summary statistics for given dataset and local parameters Returns -------- SS : SuffStatBag object, with K components. ''' SS = DiagGaussX.calcSummaryStats(Data, SS, LP, **kwargs) SS = RegressY.calcSummaryStats(Data, SS, LP, **kwargs) return SS
def calcLogSoftEvMatrix_FromPost(self, Data, **kwargs): ''' Compute expected log soft evidence of each item under each cluster Returns ------- E_log_soft_ev_NK : 2D array, size N x K ''' E_log_soft_ev_NK = DiagGaussX.calcLogSoftEvMatrix_FromPost( Data, Post=self.Post) if hasattr(Data, 'Y'): # Only incorporate Y attribute if present E_log_soft_ev_NK = RegressY.calcLogSoftEvMatrix_FromPost( Data, Post=self.Post, E_log_soft_ev_NK=E_log_soft_ev_NK) return E_log_soft_ev_NK
def calcHardMergeGap(self, SS, kA, kB): ''' Calculate change in ELBO after a hard merge applied to this model Returns --------- gap : scalar real, indicates change in ELBO after merge of kA, kB ''' gapX, _, _ = DiagGaussX.calcHardMergeGapForPair(SS=SS, Post=self.Post, Prior=self.Prior, kA=kA, kB=kB) gapY, _, _ = RegressY.calcHardMergeGapForPair(SS=SS, Post=self.Post, Prior=self.Prior, kA=kA, kB=kB) return gapX + gapY
def updatePost(self, SS): ''' Update attribute Post for all comps given suff stats. Optimizes the variational objective for approximating the posterior Post Condition -------------- Attributes K and Post updated in-place. ''' self.ClearCache() if not hasattr(self, 'Post') or SS.K != self.Post.K: self.Post = None self.Post = DiagGaussX.calcPostParamsFromSS(SS=SS, Prior=self.Prior, Post=self.Post) self.Post = RegressY.calcPostParamsFromSS(SS=SS, Prior=self.Prior, Post=self.Post) self.K = SS.K
def __init__(self, inferType='VB', D=0, Data=None, **PriorArgs): ''' Initialize bare obsmodel with valid prior hyperparameters. Returns ------- obsmodel : bare observation model Resulting object lacks either EstParams or Post attributes. which must be created separately (see init_global_params). ''' if Data is not None: self.D = Data.dim else: self.D = int(D) self.E = self.D + 1 self.K = 0 self.inferType = inferType self.Cache = dict() PriorArgs['D'] = self.D PriorArgs['E'] = self.E self.Prior = DiagGaussX.createParamBagForPrior(Data, **PriorArgs) self.Prior = RegressY.createParamBagForPrior(Data, Prior=self.Prior, **PriorArgs)
def get_info_string_prior(self): return DiagGaussX.getStringSummaryOfPrior(self.Prior) \ + RegressY.getStringSummaryOfPrior(self.Prior)