def emissionLikelihood( self, x, ys ): # Compute P( y | x, ϴ ) if( x.ndim == 2 ): # Multiple time steps if( ys.ndim == 2 ): assert x.shape[ 0 ] == ys.shape[ 0 ] else: # There are multiple measurements per latent state assert ys.ndim == 3 assert x.shape[ 0 ] == ys.shape[ 1 ] # Put the time index in front ys = np.swapaxes( ys, 0, 1 ) assert x.shape[ 0 ] == ys.shape[ 0 ] ans = 0.0 for t, ( _x, _ys ) in enumerate( zip( x, ys ) ): ans += Normal.log_likelihood( _ys, nat_params=( -0.5 * self.J1Emiss, self._hy.dot( _x ) ) ) return ans else: # Only 1 example. I don't think this code will ever be called assert x.ndim == 1 if( ys.ndim == 1 ): pass else: assert ys.ndim == 2 return Normal.log_likelihood( _ys, nat_params=( -0.5 * self.J1Emiss, self._hy.dot( _x ) ) )
def preprocessData( self, ys, computeMarginal=True ): ys = np.array( ys ) self._T = ys.shape[ 1 ] # Compute all of the emission probs here. This just makes the code cleaner self.L = np.zeros( ( self.T, self.K ) ) for k in range( self.K ): n1 = self.n1Emiss[ k ] n2 = self.n2Emiss[ k ] self.L[ :, k ] = Normal.log_likelihood( ys, nat_params=( n1, n2 ) ).sum( axis=0 )
def emissionProb( self, t, forward=False, ys=None ): if( ys is None ): emiss = self.L[ t ] else: emiss = np.zeros( self.K ) for k in range( self.K ): n1 = self.n1Emiss[ k ] n2 = self.n2Emiss[ k ] emiss += Normal.log_likelihood( ys[ :, t ], nat_params=( n1, n2 ) ).sum( axis=0 ) return emiss if forward == True else np.broadcast_to( emiss, ( self.K, self.K ) )
def preprocessData( self, xs, u=None, computeMarginal=True ): xs = np.array( xs ) # Not going to use multiple measurements here assert xs.ndim == 2 self._T = xs.shape[ 0 ] # Compute P( x_t | x_t-1, z ) for all of the observations over each z self.L0 = Normal.log_likelihood( xs[ 0 ], nat_params=( self.n1_0, self.n2_0 ) ) self.L = np.empty( ( self.T - 1, self.K ) ) for i, ( n1, n2, n3 ) in enumerate( zip( self.n1Trans, self.n2Trans, self.n3Trans ) ): def ll( _x ): x, x1 = np.split( _x, 2 ) return Regression.log_likelihood( ( x, x1 ), nat_params=( n1, n2, n3 ) ) self.L[ :, i ] = np.apply_along_axis( ll, -1, np.hstack( ( xs[ :-1 ], xs[ 1: ] ) ) )
def likelihoodStep( self, x, J, h ): return Normal.log_likelihood( x, params=Normal.natToStandard( J, h, fromPrecision=True ) )