Exemple #1
0
 def get_atoms_4(self, ii, jj):
     # ii = self.ii
     # jj = self.jj
     natoms = self.natoms
     adj = np.asarray([ii, jj])
     adj2 = adj.copy()
     adj2[0, :] = adj[1, :]
     adj2[1, :] = adj[0, :]
     adjacencymatrix = np.concatenate([adj, adj2], axis=1)
     ii = adjacencymatrix[0, :]
     jj = adjacencymatrix[1, :]
     # ii = ii - 1
     # jj = jj - 1
     # known adjacencies
     molecularadjacencymatrix = sparse.csr_matrix((np.ones(len(ii)), (ii, jj)))
     # compute atomic tetrahedra with central atoms in middle two coordinates
     atoms4 = np.ones((1, 4))
     for i in range(natoms):
         nebs = molecularadjacencymatrix[i].indices
         # nnebs = len(molecularadjacencymatrix[i].indices)
         for j in nebs:
             if j > i:
                 i1s = np.setdiff1d(molecularadjacencymatrix[i].indices, j)
                 j1s = np.setdiff1d(molecularadjacencymatrix[j].indices, i)
                 for j1 in j1s:
                     for i1 in i1s:
                         atom4 = np.reshape(np.asarray([i1, i, j, j1, ]), (1, 4))
                         atoms4 = np.concatenate((atoms4, atom4), axis=0)
     atoms4 = atoms4[1:atoms4.shape[0], :]
     atoms4 = np.asarray(atoms4, dtype=int)
     return (atoms4, atoms4.shape[0])
    def runJointParentChild( self ):
        initial_dist, transition_dists, emission_dist = self.generateDists()
        graphs = self.graphs

        msg = self.msg
        msg.updateParams( initial_dist, transition_dists, emission_dist, graphs )
        print( 'About to filter' )
        U, V = msg.filter()

        print( '\nJoint parent child should marginalize out to joint probs' )
        for n, probs in msg.jointParentChild( U, V, msg.nodes ):
            parents, parent_order = msg.getParents( n, get_order=True )
            n_parents = parents.shape[ 0 ]

            joints = msg.nodeJoint( U, V, parents )
            for i, ( ( p, j ), o ) in enumerate( zip( joints, parent_order ) ):
                # Marginalize out the other parents from probs
                int_axes = np.setdiff1d( np.hstack( ( n_parents, parent_order ) ), o )
                reduced = msg.integrate( probs, axes=int_axes )
                print( 'sum_{ parents except %d }P( x_%d, x_p1..pN, Y ) for node %d - P( x_%d, Y ) : ->'%( p, p, n, p ), ( j - reduced ).sum() )
                assert np.allclose( reduced, j ), 'reduced: %s, j: %s'%( reduced, j )

            ( _, joint ), = msg.nodeJoint( U, V, [ n ] )
            # Marginalize out all of the parents
            reduced = msg.integrate( probs, axes=parent_order )
            print( 'sum_{ parents }P( x_%d, x_p1..pN, Y ) - P( x_%d, Y ) : ->'%( n, n ), ( joint - reduced ).sum() )
            assert np.allclose( reduced, joint ), 'reduced: %s, j: %s'%( reduced, j )
Exemple #3
0
def initialize_W(Xhat, Yhat, scale_by=0.2, allow_s2=True):
    nP = Xhat[0][0].shape[1]
    nQ = Yhat[0][0].shape[1]
    nN = Yhat[0][0].shape[0]
    YYhat = calnet.utils.flatten_nested_list_of_2d_arrays(Yhat)
    XXhat = calnet.utils.flatten_nested_list_of_2d_arrays(Xhat)
    Wmy0 = np.zeros((nQ, nQ))
    Wmx0 = np.zeros((nP, nQ))
    #Ymatrix_pred = np.zeros((nN,nQ))
    Ymatrix = np.zeros((nN, nQ))
    for itype in range(nQ):
        if allow_s2:
            Ymatrix[:, itype] = invert_f_mt(YYhat[:, itype])  # nN
        else:
            Ymatrix[:, itype] = invert_f_mt(YYhat[:, itype], s02=0)  # nN
        others = np.setdiff1d(np.arange(nQ), itype)  # nQ
        Xmatrix = np.concatenate((XXhat[:, :nP], YYhat[:, others]),
                                 axis=1)  # nN,nP+(nQ-1)
        Bmatrix = np.linalg.pinv(
            Xmatrix
        ) @ Ymatrix[:,
                    itype]  # B = X^+Y, where X is (X,Y), Y is Eta, and B is W
        # solution to Y = XB
        Wmx0[:, itype] = Bmatrix[:nP]
        Wmy0[others, itype] = Bmatrix[nP:]
        #Ymatrix_pred[:,itype] = Xmatrix @ Bmatrix
    return scale_by * Wmx0, scale_by * Wmy0
Exemple #4
0
    def m_step(self,
               expectations,
               datas,
               inputs,
               masks,
               tags,
               optimizer="adam",
               num_iters=10,
               **kwargs):
        """
        Fit a logistic regression for the transitions.
        
        Technically, this is a stochastic M-step since the states 
        are sampled from their posterior marginals.
        """
        K, M, D = self.K, self.M, self.D

        zps, zns = [], []
        for Ez, _, _ in expectations:
            z = np.array([np.random.choice(K, p=p) for p in Ez])
            zps.append(z[:-1])
            zns.append(z[1:])

        X = np.vstack([
            np.hstack((input[1:], data[:-1]))
            for input, data in zip(inputs, datas)
        ])
        y = np.concatenate(zns)

        # Identify used states
        used = np.unique(y)
        K_used = len(used)
        unused = np.setdiff1d(np.arange(K), used)

        # Reset parameters before filling in
        self.Ws = np.zeros((K, M))
        self.Rs = np.zeros((K, D))
        self.r = np.zeros((K, ))

        if K_used == 1:
            warn(
                "RecurrentOnlyTransitions: Only using 1 state in expectation. "
                "M-step cannot proceed. Resetting transition parameters.")
            return

        # Fit the logistic regression
        self._lr.fit(X, y)

        # Extract the coefficients
        assert self._lr.coef_.shape[0] == (K_used if K_used > 2 else 1)
        if K_used == 2:
            # lr thought there were only two classes
            self.Ws[used[1]] = self._lr.coef_[0, :M]
            self.Rs[used[1]] = self._lr.coef_[0, M:]
        else:
            self.Ws[used] = self._lr.coef_[:, :M]
            self.Rs[used] = self._lr.coef_[:, M:]

        # Set the intercept
        self.r[used] = self._lr.intercept_
Exemple #5
0
def scatter1d(nonzero_values, nonzero_indices, array_len):
    all_indices = np.arange(array_len, dtype=anp.int64)
    zero_indices = anp.setdiff1d(all_indices,
                                 nonzero_indices,
                                 assume_unique=True)
    index_map = inverse_permutation(
        anp.concatenate([nonzero_indices, zero_indices]))
    u_values = anp.concatenate([nonzero_values, anp.zeros(len(zero_indices))])
    return u_values[index_map]
    def initialProb(self, node):
        pi = np.copy(self.pi0)
        if (int(node) in self.possible_latent_states):
            states = self.possible_latent_states[int(node)]
            impossible_states = np.setdiff1d(np.arange(pi.shape[-1]), states)
            for state in impossible_states:
                pi[state] = np.NINF
            pi[states] -= logsumexp(pi)

        return pi
Exemple #7
0
    def m_step(self, expectations, datas, inputs, masks, tags, optimizer="adam", num_iters=10, **kwargs):
        """
        Fit a logistic regression for the transitions.
        
        Technically, this is a stochastic M-step since the states 
        are sampled from their posterior marginals.
        """
        from sklearn.linear_model import LogisticRegression
        K, M, D = self.K, self.M, self.D

        zps, zns = [], []
        for Ez, _ in expectations:
            z = np.array([np.random.choice(K, p=p) for p in Ez])
            zps.append(z[:-1])
            zns.append(z[1:])


        X = np.vstack([np.hstack((one_hot(zp, K), input[1:], data[:-1])) 
                       for zp, input, data in zip(zps, inputs, datas)])
        y = np.concatenate(zns)

        # Determine the number of states used
        used = np.unique(y)
        K_used = len(used)
        unused = np.setdiff1d(np.arange(K), used)
        
        # Reset parameters before filling in
        self.log_Ps = np.zeros((K, K))
        self.Ws = np.zeros((K, M))
        self.Rs = np.zeros((K, D))

        if K_used == 1:
            warn("RecurrentTransitions: Only using 1 state in expectation. "
                 "M-step cannot proceed. Resetting transition parameters.")
            return

        # Fit the logistic regression
        lr = LogisticRegression(fit_intercept=False, multi_class="multinomial", solver="sag")
        lr.fit(X, y)

        # Extract the coefficients
        assert lr.coef_.shape[0] == (K_used if K_used > 2 else 1)
        log_P = lr.coef_[:, :K]
        W = lr.coef_[:, K:K+M]
        R = lr.coef_[:, K+M:]
            
        if K_used == 2:
            # lr thought there were only two classes
            self.log_Ps[:,used[1]] = lr.coef_[0, :K]
            self.Ws[used[1]] = lr.coef_[0,K:K+M]
            self.Rs[used[1]] = lr.coef_[0,K+M:]
        else:
            self.log_Ps[:, used] = log_P.T
            self.Ws[used] = W
            self.Rs[used] = R
Exemple #8
0
def get_percentile_calibration_likelihood(filenames, model,
                                          interval_coverage=90,
                                          method='IJ',
                                          inds=None):
  '''
  Currently checks percentile estimates over each dimension of the parameters
  independently (so we only have to compute precentiles over 1-D things)

  true_params should be a D dimensional array

  interval_coverage specifies the size of the interval around the median;
    i.e. 95 corresponds to the interval [2.5%, 97.5%]
  '''
  nExp = len(filenames)
  in_range = np.zeros(nExp, dtype=np.bool)
  for n in range(nExp):
    bs_run = load_run(filenames[n])
    true_params = bs_run['multinomial']['truth']['theta']
    
    if method == 'linear_approx':
      bs_samples = bs_run['multinomial']['bootstrap_params_appx'].copy()
    elif method == 'exact':
      bs_samples = bs_run['multinomial']['bootstrap_params_exact'].copy()

    model.training_data = bs_run['train_data']

    if inds is not None:
      fixed_inds = np.setdiff1d(np.arange(true_params.shape[0]), inds)
      bs_samples[:,fixed_inds] = np.mean(bs_samples, axis=0)[fixed_inds]

    true_like = model.eval_objective(true_params)
    likelihood_interval = get_likelihood_based_interval(bs_samples,
                                                        interval_coverage,
                                                        model)
    if (likelihood_interval.min() <= true_like and
        true_like <= likelihood_interval.max()):
      in_range[n] = True
    else:
      in_range[n] = False
      

    '''
    if inds is None:
      conv_hull = scipy.spatial.Delaunay(params_in_interval)
      in_range[n] = conv_hull.find_simplex(true_params) > 0
    else:
      if len(inds) > 1:
        conv_hull = scipy.spatial.Delaunay(params_in_interval[:,inds])
        in_range[n] = conv_hull.find_simplex(true_params[inds]) > 0
      else:
        in_range[n] = ((params_in_interval[:,inds].min() < true_params[inds][0]) and
                       (params_in_interval[:,inds].max() > true_params[inds][0]))

    '''
  return in_range
    def initialProb(self, node, is_partial_graph_index=False):
        pi = np.copy(self.pi0)
        node_full = self.partialGraphIndexToFullGraphIndex(
            node) if is_partial_graph_index == True else node
        if (int(node_full) in self.possible_latent_states):
            states = self.possible_latent_states[int(node_full)]
            impossible_states = np.setdiff1d(np.arange(pi.shape[-1]), states)
            for state in impossible_states:
                pi[impossible_states] = np.NINF
            pi[states] -= logsumexp(pi)

        return fbsData(pi, -1)
Exemple #10
0
def fbsTests():
    graphs = [
        graph1(),
        graph2(),
        graph3(),
        graph4(),
        graph5(),
        graph6(),
        graph7(),
        cycleGraph1(),
        cycleGraph2(),
        cycleGraph3(),
        cycleGraph7(),
        cycleGraph8(),
        cycleGraph9(),
        cycleGraph10(),
        cycleGraph11(),
        cycleGraph12()
    ]
    # graphs = [ cycleGraph12() ]

    msg = GraphMessagePasserFBS()
    msg.updateGraphs(graphs)
    msg.draw(styles={0: dict(style='filled', color='red')},
             node_to_style_key=dict([(n, 0) for n in msg.fbs]))

    def nothing(is_base_case, node_list):
        return

    count = 0

    def loopyHasConverged():
        nonlocal count
        count += 1
        return count > 3

    msg.upDown(nothing, nothing, loopyHasConverged=loopyHasConverged)

    class worker():
        def __init__(self):
            self.visited = []

        def __call__(self, node_list):
            self.visited.append(node_list)

    work = worker()
    msg.forwardPass(work)

    visited = np.hstack(work.visited)
    diff = np.setdiff1d(msg.nodes, visited)
    assert diff.size == 0

    print('Done with the improved fbs message passing tests!')
Exemple #11
0
    def transitionProb(self, child):
        parents, parent_order = self.getParents(child, get_order=True)
        ndim = len(parents) + 1
        pi = np.copy(self.pis[ndim])

        # If we know the latent state for child, then ensure that we
        # transition there.  Also make sure we're only using the possible
        # parent latent states!!!!
        modified = False
        for parent, order in zip(parents, parent_order):
            if (int(parent) in self.possible_latent_states):
                parent_states = self.possible_latent_states[int(parent)]
                impossible_parent_axes = np.setdiff1d(
                    np.arange(pi.shape[order]), parent_states)
                index = [slice(0, s) for s in pi.shape]
                index[order] = impossible_parent_axes
                pi[tuple(index)] = np.NINF
                modified = True

        if (int(child) in self.possible_latent_states):
            child_states = self.possible_latent_states[int(child)]
            impossible_child_axes = np.setdiff1d(np.arange(pi.shape[-1]),
                                                 child_states)
            pi[..., impossible_child_axes] = np.NINF
            modified = True

        if (modified == True):
            with np.errstate(invalid='ignore'):
                pi[..., :] -= logsumexp(pi, axis=-1)[..., None]

        # In case entire rows summed to -inf
        pi[np.isnan(pi)] = np.NINF

        # Reshape pi's axes to match parent order
        assert len(parents) + 1 == pi.ndim
        assert parent_order.shape[0] == parents.shape[0]
        pi = np.moveaxis(pi, np.arange(ndim),
                         np.hstack((parent_order, ndim - 1)))
        return pi
Exemple #12
0
  def compute_restricted_hessian_and_dParamsdWeights(self, dims, weights,
                                                     comp_dParams_dWeights=True):
    '''
    Computes the dims.shape[0] by dims.shape[0] Hessian only along the entries
    in dims (used when using l_1 regularization)
    '''
    theta0 = self.params.get_free()

    # Objective to differentiate just along the dimensions specified
    def lowDimObj(weights, thetaOnDims, thetaOffDims, invPerm):
      allDims = np.append(dims, offDims)
      thetaFull = np.append(thetaOnDims, thetaOffDims)[invPerm]
      return self.weighted_model_objective(weights, thetaFull)

    offDims = np.setdiff1d(np.arange(self.params.get_free().shape[0]), dims)
    thetaOnDims = theta0[dims]
    thetaOffDims = theta0[offDims]

    # lowDimObj will concatenate thetaOnDims, thetaOffDims, then needs to
    #  un-permute them into the original theta.
    allDims = np.append(dims, offDims)
    invPerm = np.zeros(theta0.shape[0], dtype=np.int32)
    for i, idx in enumerate(allDims):
      invPerm[idx] = i

    evalHess = autograd.hessian(lowDimObj, argnum=1)
    array_box_go_away = self.params.get_free().copy()

    restricted_hess = evalHess(weights,
                               thetaOnDims,
                               thetaOffDims,
                               invPerm)
    self.params.set_free(theta0)

    dObj_dParams = autograd.jacobian(lowDimObj, argnum=1)
    d2Obj_dParamsdWeights = autograd.jacobian(dObj_dParams, argnum=0)

    if comp_dParams_dWeights:
      restricted_dParamsdWeights = d2Obj_dParamsdWeights(weights,
                                                         thetaOnDims,
                                                         thetaOffDims,
                                                         invPerm)
      return restricted_hess, restricted_dParamsdWeights
    else:
      return restricted_hess
Exemple #13
0
def initialize_W(Xhat, Yhat, scale_by=0.2):
    nP = Xhat[0][0].shape[1]
    nQ = Yhat[0][0].shape[1]
    nN = Yhat[0][0].shape[0]
    YYhat = calnet.utils.flatten_nested_list_of_2d_arrays(Yhat)
    XXhat = calnet.utils.flatten_nested_list_of_2d_arrays(Xhat)
    Wmy0 = np.zeros((nQ, nQ))
    Wmx0 = np.zeros((nP, nQ))
    Ymatrix = np.zeros((nN, nQ))
    for itype in range(nQ):
        Ymatrix[:, itype] = invert_f_mt(YYhat[:, itype])
        others = np.setdiff1d(np.arange(nQ), itype)
        Xmatrix = np.concatenate((XXhat[:, :nP], YYhat[:, others]), axis=1)
        Bmatrix = np.linalg.pinv(Xmatrix) @ Ymatrix[:, itype]
        Wmx0[:, itype] = Bmatrix[:nP]
        Wmy0[others, itype] = Bmatrix[nP:]
        #Ymatrix_pred[:,itype] = Xmatrix @ Bmatrix
    return scale_by * Wmx0, scale_by * Wmy0
    def test_replace(self):
        dim = 10
        x = np.random.random(dim)
        x_orig = copy.deepcopy(x)

        inds = [1, 3, 5]
        x_sub = np.random.random(len(inds))

        non_inds = np.setdiff1d(np.arange(dim), inds)
        x_new = autograd_supplement_lib.replace(x_sub, x, inds)
        assert_array_almost_equal(x_new[inds], x_sub)
        assert_array_almost_equal(x_new[non_inds], x[non_inds])
        assert_array_almost_equal(x, x_orig)
        assert len(x_new) == len(x)

        # Apparnetly check grads doesn't check all the arguments?
        check_grads(
            lambda x_sub: autograd_supplement_lib.replace(x_sub, x, inds))(x_sub)
        check_grads(
            lambda x: autograd_supplement_lib.replace(x_sub, x, inds))(x)
def TrainingCurve(fig, config_file):
    args = GetTrainedEmulator(config_file)
    clf = args[0]
    prior = args[1]
    exp_Y = args[2]
    exp_Yerr = args[3]
    model_X = args[4].values
    model_Y = args[5].values
    training_idx = args[6]
    validation_idx = np.setdiff1d(np.arange(model_X.shape[0]), training_idx)
    history_para = args[7].fillna(method="ffill")

    clf.Fit(model_X, model_Y)
    axes = fig.subplots(1, 2)
    NumberOfPts(axes[0], clf, model_X, model_Y, training_idx, validation_idx)
    NumberOfSteps(
        axes[1],
        clf,
        model_X,
        model_Y,
        training_idx,
        validation_idx,
        history_para)
Exemple #16
0
    def nodeJointSingleNode( self, U, V, node, method='compute', is_partial_graph_index=False ):
        # P( x, Y )
        # Having different methods is more of a sanity check than anything

        not_in_fbs = not self.inFeedbackSet( node, is_partial_graph_index=is_partial_graph_index )

        if( not_in_fbs and method == 'integrate' ):
            # Can't use integrate method if node isn't in the fbs
            method = 'compute'

        # If the fbs node is a leaf, must use the integrate method
        if( not_in_fbs == False and self.nParents( node, is_partial_graph_index=is_partial_graph_index, use_partial_graph=False ) == 0 ):
            method = 'integrate'

        # Also if the fbs node has all fbs node parents, must use integrate method
        if( not_in_fbs == False and len( [ 1 for p in self.getFullParents( node, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=False ) if not self.inFeedbackSet( p, is_partial_graph_index=False ) ] ) == 0 ):
            method = 'integrate'

        if( method == 'compute' ):
            # Need to use the partial graph index from here
            node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node

            # If the node isn't in the fbs, compute the joint the normal way.
            if( not_in_fbs ):
                u = self.uData( U, V, node_partial )
                vs = self.vData( U, V, node_partial )
                vs = [ self.extendAxes( node_partial, v, 0, 1 ) for v in vs ]
                joint_fbs = self.multiplyTerms( terms=( u, *vs ) )
                int_axes = range( 1, joint_fbs.ndim )
            else:
                # Just computing u for the fbs should, by construction,
                # cover all of the nodes in the graph.  Still need to integrate
                # out other fbs nodes in this case
                joint_fbs = self.u( U, V, node_partial )
                fbs_index = self.fbsIndex( node, is_partial_graph_index=is_partial_graph_index, within_graph=True )
                keep_axis = fbs_index + joint_fbs.fbs_axis
                int_axes = np.setdiff1d( np.arange( joint_fbs.ndim ), keep_axis )
            return self.integrate( joint_fbs, axes=int_axes ).data

        elif( method == 'integrate' ):
            # If node is in the fbs, choose another node to get the joint with the fbs node with.
            # Otherwise, calculate the joint the regular way
            if( not_in_fbs ):
                node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node
            else:
                node_partial = self._anotherNode( node, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )

            # Compute the joint using the regular algorithm but on the partial_graph
            joint_fbs = self.nodeJointSingleNodeComputation( U, V, node_partial )

            if( not_in_fbs ):
                # Integrate out all of the parents and fbs nodes
                int_axes = range( 1, joint_fbs.ndim )
            else:
                # Integrate out all the nodes but this one, which is somewhere in the fbs axes
                fbs_index = self.fbsIndex( node, is_partial_graph_index=is_partial_graph_index, within_graph=True )
                keep_axis = fbs_index + joint_fbs.fbs_axis
                int_axes = np.setdiff1d( np.arange( joint_fbs.ndim ), keep_axis )

            # Integrate the joint and return only the data portion
            return self.integrate( joint_fbs, axes=int_axes ).data
        else:
            assert 0, 'Invalid method'
    def fit(self, X, Y, iterations, batch_size = False, learning_parameters = default_parameters, 
            show_it = 100, record_hist = False):
        
        learning_parameters = {**default_parameters, **learning_parameters}
        learning_rate = learning_parameters["LR"]
        type_epsilon = learning_parameters["type_epsilon"]
        reg = learning_parameters["reg"]
        learning_parameters["rate"] = learning_rate/iterations
        loss_name = learning_parameters["loss"]
        grad = grad_dic[loss_name]      
        batch_creation = sampling_dic[learning_parameters["sampling"]]
        
        # Create a copy of the parameters (so the original parameters aren't modified)
        self.LR = [learning_rate]
        self.type_epsilon = type_epsilon
        self.X_train = np.copy(X)
        self.Y_train = np.copy(Y)
        self.iteration = iterations
        self.points_hist.append(np.copy(X))
        parameters = self.parameters
        
        
        X = np.copy(X)
        self.X = X
        data_set_ind = np.arange(X.shape[0])
        perturbation = np.zeros(X.shape)
        for i in range(iterations):
            if type(show_it) == int and i % show_it == 0:
                print("Iteration ", i)

            # Create a batch and a sample
            sample_indices, batch_indices = batch_creation(X, batch_size)
            X_batch = X[batch_indices]
            Y_batch = Y[batch_indices]
            self.batch_hist.append(np.copy(X_batch))
            
            # The indices of all the elements not in the batch
            not_batch = np.setdiff1d(data_set_ind, batch_indices)
            
        
            # Compute the gradient
            rho, g = grad(self.parameters, X_batch, Y_batch, 
                                           sample_indices, self.kernel_keyword, reg = reg)
            g = -g
            if loss_name == "rho" and (rho >1.0001 or rho <-0.00001):
                    print ("Rho outside allowed bounds", rho)
            # Compute the perturbations by interpolation
            if batch_size == False:
                perturbation = g
                coeff = kernel_regression_coeff(X_batch, g, parameters, self.kernel_keyword, reg = reg)

            else:
                g_interpolate, coeff = kernel_regression(X_batch, X[not_batch], g, parameters, self.kernel_keyword, reg = reg)                
                perturbation[batch_indices] = g
                perturbation[not_batch] = g_interpolate

            #Find epsilon
            epsilon = compute_LR(learning_rate, X, perturbation, type_epsilon = type_epsilon)
            # Adjust the learning rate based on the learning parameters
            learning_rate = adjust_LR(i, learning_rate, learning_parameters)
            self.LR.append(learning_rate)

            
                
            #Update the points
            X += epsilon * perturbation
            
            # Recording the regression coefficients
            self.coeff.append(coeff)
            # Update the history
            self.rho_values.append(rho)
            self.epsilon.append(epsilon)
            self.perturbation.append(perturbation)

            
            if record_hist == True:
                self.points_hist.append(np.copy(X))
                                
        
        return X
Exemple #18
0
    def jointParentsSingleNode( self, U, V, node, method='compute', is_partial_graph_index=False ):
        # P( x_p1..pN, Y )

        not_in_fbs = not self.inFeedbackSet( node, is_partial_graph_index=is_partial_graph_index )

        if( method == 'integrate' ):
            if( not_in_fbs ):
                node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node
            else:
                node_partial = self._anotherNode( node, parents=False, mates=False, children=False, siblings=True, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )

            # Couldn't find a sibling, so use the compute method
            if( node_partial is None ):
                method = 'compute'

            # Can't use integrate method if node isn't in the fbs
            if( not_in_fbs ):
                method = 'compute'

        if( len( [ 1 for p in self.getFullParents( node, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=False ) if not self.inFeedbackSet( p, is_partial_graph_index=False ) ] ) == 0 ):
            if( not_in_fbs ):
                node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node
            else:
                # Find any node to run the nodeJoint algorithm on
                node_partial = self._anotherNode( node, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )
            joint_fbs = self.nodeJointSingleNodeComputation( U, V, node_partial )

        elif( method == 'compute' ):
            # Regular computation
            node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node
            joint_fbs = self.jointParentsSingleNodeComputation( U, V, node_partial )

        elif( method == 'integrate' ):
            # Find a sibling to pass
            node_partial = self._anotherNode( node, parents=False, mates=False, children=False, siblings=True, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )
            joint_fbs = self.jointParentsSingleNodeComputation( U, V, node_partial )

        else:
            assert 0, 'Invalid method'

        # Loop through the parents and find the axes that they are on so we can keep them
        parents, parent_order = self.getFullParents( node, get_order=True, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )
        keep_axes = []
        for p, o in zip( parents, parent_order ):
            if( self.inFeedbackSet( p, is_partial_graph_index=True ) ):
                keep_axes.append( joint_fbs.fbs_axis + self.fbsIndex( p, is_partial_graph_index=True, within_graph=True ) )
            else:
                keep_axes.append( o )
        keep_axes = np.array( keep_axes )

        # Integrate out all fbs nodes that aren't the parents
        int_axes = np.setdiff1d( np.arange( joint_fbs.ndim ), keep_axes )
        ans = self.integrate( joint_fbs, axes=int_axes ).data

        # Swap the order of the axes so that the answer has the correct parent order.
        # At the moment, all of the fbs indices are on the last indices sorted by
        # fbs index
        non_fbs_order = [ o for p, o in zip( parents, parent_order ) if not self.inFeedbackSet( p, is_partial_graph_index=True ) ]
        fbs_parents = [ ( p, o ) for p, o in zip( parents, parent_order ) if self.inFeedbackSet( p, is_partial_graph_index=True ) ]
        fbs_order = sorted( fbs_parents, key=lambda x: self.fbsIndex( x[ 0 ], is_partial_graph_index=True, within_graph=True ) )
        fbs_order = [ o for p, o in fbs_order ]

        true_order = non_fbs_order + fbs_order
        transpose_axes = [ true_order.index( i ) for i in range( len( true_order ) ) ]

        return np.transpose( ans, transpose_axes )
Exemple #19
0
    def jointParentChildSingleNode( self, U, V, node, method='compute', is_partial_graph_index=False ):
        # P( x_c, x_p1..pN, Y )

        not_in_fbs = not self.inFeedbackSet( node, is_partial_graph_index=is_partial_graph_index )

        if( method == 'integrate' ):
            # This fbs node has no siblings, so must compute
            if( not_in_fbs ):
                node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node
            else:
                node_partial = self._anotherNode( node, parents=False, mates=False, children=False, siblings=True, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )

            # Couldn't find a sibling, so use the compute method
            if( node_partial is None ):
                method = 'compute'

            # Can't use integrate method if node isn't in the fbs
            if( not_in_fbs ):
                method = 'compute'

        # If all of the parents are in the fbs and so is node, then use nodeJoint and integrate out the correct nodes.
        if( len( [ 1 for p in self.getFullParents( node, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True ) if not self.inFeedbackSet( p, is_partial_graph_index=True ) ] ) == 0 ):
            if( not_in_fbs ):
                node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node
            else:
                # Find any node to run the nodeJoint algorithm on
                node_partial = self._anotherNode( node, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )
            joint_fbs = self.nodeJointSingleNodeComputation( U, V, node_partial )

        elif( method == 'compute' ):
            node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node
            joint_fbs = self.jointParentChildSingleNodeComputation( U, V, node_partial )

        elif( method == 'integrate' ):
            if( not_in_fbs ):
                node_partial = self.fullGraphIndexToPartialGraphIndex( node ) if is_partial_graph_index == False else node
            else:
                # Find a sibling to run the algorithm on
                node_partial = self._anotherNode( node, parents=False, mates=False, children=False, siblings=True, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )
            joint_fbs = self.jointParentChildSingleNodeComputation( U, V, node_partial )

        else:
            assert 0, 'Invalid method'

        # Loop through the parents and find the axes that they are on so we can keep them
        parents, parent_order = self.getFullParents( node, get_order=True, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True )
        n_parents = self.nParents( node, is_partial_graph_index=is_partial_graph_index, use_partial_graph=False )
        keep_axes = []
        for p, o in zip( parents, parent_order ):
            if( self.inFeedbackSet( p, is_partial_graph_index=True ) ):
                keep_axes.append( joint_fbs.fbs_axis + self.fbsIndex( p, is_partial_graph_index=True, within_graph=True ) )
            else:
                keep_axes.append( o )

        # Keep the axis that node is on
        if( not_in_fbs ):
            n_fbs_parents = len( [ 1 for p in self.getFullParents( node, is_partial_graph_index=is_partial_graph_index, return_partial_graph_index=True ) if self.inFeedbackSet( p, is_partial_graph_index=True ) ] )
            if( n_fbs_parents == n_parents ):
                keep_axes.append( 0 )
            else:
                keep_axes.append( n_parents )
        else:
            keep_axes.append( joint_fbs.fbs_axis + self.fbsIndex( node, is_partial_graph_index=is_partial_graph_index, within_graph=True ) )
        keep_axes = np.array( keep_axes )

        # Integrate out all fbs nodes that aren't the parents
        int_axes = np.setdiff1d( np.arange( joint_fbs.ndim ), keep_axes )
        ans = self.integrate( joint_fbs, axes=int_axes ).data

        # Swap the order of the axes to that the answer has the correct parent order
        # and so that the node is on the last axis.  To do this, first find the true
        # axes that each of the current axes correspond to
        non_fbs_order = [ o for p, o in zip( parents, parent_order ) if not self.inFeedbackSet( p, is_partial_graph_index=True ) ]
        fbs_parents = [ ( p, o ) for p, o in zip( parents, parent_order ) if self.inFeedbackSet( p, is_partial_graph_index=True ) ]
        fbs_order = sorted( fbs_parents, key=lambda x: self.fbsIndex( x[ 0 ], is_partial_graph_index=True, within_graph=True ) )
        fbs_order = [ o for p, o in fbs_order ]

        # If node is in the fbs, then that means that its current axis is somewhere
        # after the fbs_axis.  So place the node's axis correctly
        if( self.inFeedbackSet( node, is_partial_graph_index=is_partial_graph_index ) ):
            insertion_index = self.fbsIndex( node, is_partial_graph_index=is_partial_graph_index, within_graph=True )
            true_order = non_fbs_order + fbs_order[ :insertion_index ] + [ len( parents ) ] + fbs_order[ insertion_index: ]
        else:
            true_order = non_fbs_order + [ len( parents ) ] + fbs_order

        # At the moment, true_order corresonds to the axis that each of the current
        # axes should map to.  np.transpose expects the opposite of this
        transpose_axes = [ true_order.index( i ) for i in range( len( true_order ) ) ]

        return np.transpose( ans, transpose_axes )
Exemple #20
0
    def transitionProb(self, child, is_partial_graph_index=False):
        parents, parent_order = self.getFullParents(
            child,
            get_order=True,
            is_partial_graph_index=is_partial_graph_index,
            return_partial_graph_index=True)
        child_full = self.partialGraphIndexToFullGraphIndex(
            child) if is_partial_graph_index == True else child
        ndim = len(parents) + 1
        group = self.node_groups[int(child_full)]
        shape = []
        for p, _ in sorted(zip(parents, parent_order), key=lambda po: po[1]):
            full_p = int(self.partialGraphIndexToFullGraphIndex(p))
            shape.append(self.getNodeDim(full_p))
        shape.append(self.getNodeDim(int(child_full)))
        shape = tuple(shape)

        pi = np.copy(self.pis[group][shape])
        # Reshape pi's axes to match parent order
        assert len(parents) + 1 == pi.ndim
        assert parent_order.shape[0] == parents.shape[0]

        # Sort the parent dimensions by parent order
        pi = np.moveaxis(pi, np.arange(ndim),
                         np.hstack((parent_order, ndim - 1)))

        # If we know the latent state for child, then ensure that we
        # transition there. This is intervention!
        modified = False
        for parent, order in zip(parents, parent_order):
            parent_full = self.partialGraphIndexToFullGraphIndex(parent)
            if (int(parent_full) in self.possible_latent_states):
                parent_states = self.possible_latent_states[int(parent_full)]
                impossible_parent_axes = np.setdiff1d(
                    np.arange(pi.shape[order]), parent_states)
                index = [slice(0, s) for s in pi.shape]
                index[order] = impossible_parent_axes
                pi[tuple(index)] = np.NINF
                modified = True

        if (int(child_full) in self.possible_latent_states):
            states = self.possible_latent_states[int(child_full)]
            impossible_axes = np.setdiff1d(np.arange(pi.shape[-1]), states)
            pi[..., impossible_axes] = np.NINF
            modified = True

        # In case entire rows summed to -inf
        pi[np.isnan(pi)] = np.NINF

        # Check if there are nodes in [ child, *parents ] that are in the fbs.
        # If there are, then move their axes
        fbsOffset = lambda x: self.fbsIndex(
            x, is_partial_graph_index=True, within_graph=True) + 1
        fbs_indices = [
            fbsOffset(parent) for parent in parents
            if self.inFeedbackSet(parent, is_partial_graph_index=True)
        ]

        if (self.inFeedbackSet(child,
                               is_partial_graph_index=is_partial_graph_index)):
            fbs_indices.append(
                self.fbsIndex(child,
                              is_partial_graph_index=is_partial_graph_index,
                              within_graph=True) + 1)

        if (len(fbs_indices) > 0):
            expand_by = max(fbs_indices)
            for _ in range(expand_by):
                pi = pi[..., None]

            # If there are parents in the fbs, move them to the appropriate axes
            for i, parent in enumerate(parents):
                if (self.inFeedbackSet(parent, is_partial_graph_index=True)):
                    pi = np.swapaxes(pi, i, fbsOffset(parent) + ndim - 1)

            if (self.inFeedbackSet(
                    child, is_partial_graph_index=is_partial_graph_index)):
                # If the child is in the fbs, then move it to the appropriate axis
                pi = np.swapaxes(pi, ndim - 1, fbsOffset(child) + ndim - 1)

            return fbsData(pi, ndim)
        return fbsData(pi, -1)
# 10-fold cross-validation setup
nt = np.floor(cvind.shape[0] / 10).astype(int)
cvind = np.reshape(cvind[:10 * nt], (10, nt))

# Array of NLPDs
nlpd = []

# Run for each fold
for fold in np.arange(10):

    print(100 * '-')
    print('Fold %d' % fold)
    print(100 * '-')

    # Get training and test indices
    test = cvind[fold, :]
    train = np.setdiff1d(cvind, test)

    # Set training and test data
    X = Xall[train, :]
    y = yall[train, :]
    Xt = Xall[test, :]
    yt = yall[test, :]

    #. Run results
    res = run_fold(X, y, Xt, yt)
    nlpd.append(res)
    print(res)

print(np.mean(nlpd), np.std(nlpd))
    def run( self ):
        initial_dist, transition_dists, emission_dist = self.generateDists()
        graphs = self.graphs

        msg = self.msg
        msg.updateParams( initial_dist, transition_dists, emission_dist, graphs )
        msg.draw()
        U, V = msg.filter()
        assert 0
        # for node, elt in enumerate( U ):
        #     node = msg.partialGraphIndexToFullGraphIndex( node )
        #     print( 'node', node, 'elt.shape', elt.shape, 'elt.fbs_axis', elt.fbs_axis )

        # for node, edge, elt in zip( *V ):
        #     node = msg.partialGraphIndexToFullGraphIndex( node )
        #     print( 'node', node, 'edge', edge, 'elt.shape', elt.shape, 'elt.fbs_axis', elt.fbs_axis )
        # assert 0

        ####################################################

        print( '\nJoint' )
        for n, probs in msg.nodeJoint( U, V, msg.nodes ):
            reduced = msg.integrate( probs, axes=range( probs.ndim ) )
            print( 'P( x_%d, Y )'%( n ), ':', probs, '->', reduced )

        ####################################################

        print( '\nJoint parents should marginalize out to joint probs' )
        for n, probs in msg.jointParents( U, V, msg.nodes ):
            parents, parent_order = msg.getParents( n, get_order=True )
            joints = msg.nodeJoint( U, V, parents )
            for i, ( ( p, j ), o ) in enumerate( zip( joints, parent_order ) ):
                # Marginalize out the other parents from probs
                int_axes = np.setdiff1d( parent_order, o )
                reduced = msg.integrate( probs, axes=int_axes )
                print( 'sum_{ parents except %d }P( x_p1..pN, Y ) for node %d - P( x_%d, Y ) : ->'%( p, n, p ), ( j - reduced ).sum() )
                assert np.allclose( reduced, j ), 'reduced: %s, j: %s'%( reduced, j )

        ####################################################

        print( '\nJoint parent child should marginalize out to joint probs' )
        for n, probs in msg.jointParentChild( U, V, msg.nodes ):
            parents, parent_order = msg.getParents( n, get_order=True )
            n_parents = parents.shape[ 0 ]

            joints = msg.nodeJoint( U, V, parents )
            for i, ( ( p, j ), o ) in enumerate( zip( joints, parent_order ) ):
                # Marginalize out the other parents from probs
                int_axes = np.setdiff1d( np.hstack( ( n_parents, parent_order ) ), o )
                reduced = msg.integrate( probs, axes=int_axes )
                print( 'sum_{ parents except %d }P( x_%d, x_p1..pN, Y ) for node %d - P( x_%d, Y ) : ->'%( p, p, n, p ), ( j - reduced ).sum() )
                assert np.allclose( reduced, j ), 'reduced: %s, j: %s'%( reduced, j )

            ( _, joint ), = msg.nodeJoint( U, V, [ n ] )
            # Marginalize out all of the parents
            reduced = msg.integrate( probs, axes=parent_order )
            print( 'sum_{ parents }P( x_%d, x_p1..pN, Y ) - P( x_%d, Y ) : ->'%( n, n ), ( joint - reduced ).sum() )
            assert np.allclose( reduced, joint ), 'reduced: %s, j: %s'%( reduced, j )

        ####################################################

        print( '\nSmoothed' )
        for n, probs in msg.nodeSmoothed( U, V, msg.nodes ):
            # If we reduce over the last axis, we should have everything sum to 1
            reduced = msg.integrate( probs, axes=[ -1 ] )
            print( 'P( x_%d | Y )'%( n ), ':', probs, '->', probs.shape, reduced )
            assert np.allclose( reduced, 0.0 ), 'Failed test!'

        ####################################################

        print( '\nChild given parents' )
        for n, probs in msg.conditionalParentChild( U, V, msg.nodes ):
            # If we reduce over the last axis, we should have everything sum to 1
            reduced = msg.integrate( probs, axes=[ -1 ] )
            print( 'P( x_%d | x_p1..pN, Y )'%( n ), '->', probs.shape, reduced )
            assert np.allclose( reduced, 0.0 ), 'Failed test!'