Esempio n. 1
0
def bp_update_params_new(args):
    lmds, pis = args.lmds, args.pis
    vert_parent, vert_children = args.vert_parent, args.vert_children
    #print  pis[0].shape
    I, T, L = args.X.shape
    K = args.gamma.shape[0]
    theta, alpha, beta, gamma, emit_probs, X = (args.theta, args.alpha, args.beta, args.gamma, args.emit_probs,
                                        args.X)
    evidence = args.evidence #evid_allchild(lmds, vert_children)
    emit_probs_mat = sp.exp(args.log_obs_mat)
    #emit_probs_mat /= emit_probs_mat.max(axis=2).reshape(I, T, 1)
    gamma_p = copy.copy(gamma)
    alpha_p = copy.copy(alpha)
    beta_p =  copy.copy(beta)
    theta_p = copy.copy(theta)
    emit_probs_p = copy.copy(emit_probs)
    
    theta[:] = args.pseudocount
    alpha[:] = args.pseudocount
    beta[:] = args.pseudocount
    gamma[:] = args.pseudocount
    emit_probs[:] = args.pseudocount

    #evidence = evid_allchild(lmds, args.vert_children)
    ##support = casual_support(pis)
    
    emit_sum = sp.zeros(K)
    for i in xrange(I):
        vp = vert_parent[i]
        for t in xrange(T):
            if i==0 and t==0:
                gamma += emit_probs_mat[i, t, :]*evidence[i,t,:]
                Q = emit_probs_mat[i, t, :]*evidence[i,t,:]
            else:
                if i == 0:
                    tmp1, tmp2 = sp.ix_(pis[i][-1,t-1,:], emit_probs_mat[i, t, :]*evidence[i,t,:])
                    tmp = alpha_p * (tmp1*tmp2)
                    #tmp /= tmp.sum()
                    Q = tmp.sum(axis=0)
                    alpha += tmp/tmp.sum()
                elif t == 0:
                    tmp1, tmp2 = sp.ix_(pis[vp][i-1,t,:], emit_probs_mat[i, t, :]*evidence[i,t,:])
                    tmp = beta_p *(tmp1*tmp2)
                    Q = tmp.sum(axis=0)
                    beta += tmp/tmp.sum()
                else:
                    tmp1, tmp2, tmp3 = sp.ix_(pis[vp][i-1,t,:], pis[i][-1, t-1,:], emit_probs_mat[i, t, :]*evidence[i,t,:])
                    tmp = theta_p *(tmp1*tmp2 *tmp3)
                    Q = (tmp.sum(axis=0)).sum(axis=0)
                    theta += tmp/tmp.sum()
                
            Q /= Q.sum()
            for l in xrange(L):
                if X[i,t,l]:
                    emit_probs[:, l] += Q
            emit_sum += Q
    normalize_trans(theta, alpha, beta, gamma)
    emit_probs[:] = sp.dot(sp.diag(1./emit_sum), emit_probs)
    args.emit_sum = emit_sum
    make_log_obs_matrix(args)
Esempio n. 2
0
def params_from_clique_marginals(theta, alpha, beta, gamma, emit_probs, clq_Q,
                                 clq_Q_pairs, X, args):
    """Recompute parameters using marginal probabilities"""
    I, T, L = X.shape
    K = gamma.shape[0]
    vp = 0
    pc = 1e-10  # pseudocount
    theta[:] = pc
    alpha[:] = pc
    beta[:] = pc
    gamma[:] = pc
    emit_probs[:] = pc
    #theta[:] = 0; alpha[:] = 0; beta[:] = 0; gamma[:] = 0; emit_probs[:] = 0
    global combinations
    combinations = list(enumerate(itertools.product(range(K), repeat=I)))
    #e_sum = sp.ones(emit_probs.shape[0]) * pc
    e_sum = sp.ones_like(emit_probs) * pc
    #e_sum = sp.ones(emit_probs.shape[1]) * 0
    t = 0
    for k_to, to_val in combinations:
        for i in xrange(I):
            for l in xrange(L):
                if X[i, t, l]:
                    emit_probs[to_val[i], l] += clq_Q[t, k_to]
                #e_sum[to_val[i]] += clq_Q[t, k_to]
                e_sum[to_val[i], l] += clq_Q[t, k_to]
        gamma[to_val[vp]] += clq_Q[t, k_to]
        for i in xrange(1, I):
            beta[to_val[vp], to_val[i]] += clq_Q[t, k_to]

    #import ipdb; ipdb.set_trace()
    for t in xrange(1, T):
        for k_to, to_val in combinations:
            for i in xrange(I):
                for l in xrange(L):
                    if X[i, t, l]:
                        #import ipdb; ipdb.set_trace()
                        emit_probs[to_val[i], l] += clq_Q[t, k_to]
                    #e_sum[to_val[i]] += clq_Q[t, k_to]
                    e_sum[to_val[i], l] += clq_Q[t, k_to]
            for k_from, from_val in combinations:
                alpha[from_val[vp], to_val[vp]] += clq_Q_pairs[t, k_from, k_to]
                for i in xrange(1, I):
                    theta[to_val[vp], from_val[i],
                          to_val[i]] += clq_Q_pairs[t, k_from, k_to]
    #import ipdb; ipdb.set_trace()

    #theta, alpha, beta, gamma = theta+pc*theta.max(), alpha+pc*alpha.max(),beta+pc*beta.max(),gamma+pc*gamma.max()
    normalize_trans(theta, alpha, beta, gamma)
    #emit_probs[:] = sp.dot(sp.diag(1./e_sum), emit_probs)
    #emit_probs[:] = sp.dot(emit_probs, sp.diag(1./e_sum * L))
    emit_probs[:] = emit_probs / e_sum
    #emit_probs[:] = sp.dot(emit_probs + pc*emit_probs.max(), sp.diag(1./(e_sum + pc*emit_probs.max())))
    args.emit_sum = e_sum
Esempio n. 3
0
def params_from_clique_marginals(theta, alpha, beta, gamma, emit_probs, clq_Q, clq_Q_pairs, X, args):
    """Recompute parameters using marginal probabilities"""
    I,T,L = X.shape
    K = gamma.shape[0]
    vp = 0
    pc = 1e-10 # pseudocount
    theta[:] = pc; alpha[:] = pc; beta[:] = pc; gamma[:] = pc; emit_probs[:] = pc
    #theta[:] = 0; alpha[:] = 0; beta[:] = 0; gamma[:] = 0; emit_probs[:] = 0
    global combinations
    combinations = list(enumerate(itertools.product(range(K), repeat=I)))
    #e_sum = sp.ones(emit_probs.shape[0]) * pc
    e_sum = sp.ones_like(emit_probs) * pc
    #e_sum = sp.ones(emit_probs.shape[1]) * 0
    t = 0
    for k_to, to_val in combinations:
        for i in xrange(I):
            for l in xrange(L):
                if X[i,t,l]:
                    emit_probs[to_val[i], l] += clq_Q[t, k_to]
                #e_sum[to_val[i]] += clq_Q[t, k_to]
                e_sum[to_val[i], l] += clq_Q[t, k_to]
        gamma[to_val[vp]] += clq_Q[t,k_to]
        for i in xrange(1, I):
            beta[to_val[vp], to_val[i]] += clq_Q[t,k_to]
    
    #import ipdb; ipdb.set_trace()
    for t in xrange(1, T):
        for k_to, to_val in combinations:
            for i in xrange(I):
                for l in xrange(L):
                    if X[i,t,l]:
                        #import ipdb; ipdb.set_trace()
                        emit_probs[to_val[i], l] += clq_Q[t, k_to]
                    #e_sum[to_val[i]] += clq_Q[t, k_to]
                    e_sum[to_val[i], l] += clq_Q[t, k_to]
            for k_from, from_val in combinations:    
                alpha[from_val[vp], to_val[vp]] += clq_Q_pairs[t,k_from, k_to]
                for i in xrange(1, I):
                    theta[to_val[vp], from_val[i], to_val[i]] += clq_Q_pairs[t,k_from, k_to]
    #import ipdb; ipdb.set_trace()
    
    #theta, alpha, beta, gamma = theta+pc*theta.max(), alpha+pc*alpha.max(),beta+pc*beta.max(),gamma+pc*gamma.max()
    normalize_trans(theta, alpha, beta, gamma)
    #emit_probs[:] = sp.dot(sp.diag(1./e_sum), emit_probs)
    #emit_probs[:] = sp.dot(emit_probs, sp.diag(1./e_sum * L))
    emit_probs[:] = emit_probs / e_sum
    #emit_probs[:] = sp.dot(emit_probs + pc*emit_probs.max(), sp.diag(1./(e_sum + pc*emit_probs.max())))
    args.emit_sum = e_sum
Esempio n. 4
0
def do_parallel_inference(args):
    """Perform inference in parallel on several observations matrices with
    joint parameters
    """
    from histone_tree_hmm import random_params, do_inference, plot_params, plot_energy, load_params
    from vb_mf import normalize_trans
    
    args.I, _, args.L = sp.load(args.observe_matrix[0]).shape
    K = args.K
    L = args.L
    args.T = 'all'
    args.free_energy = []
    args.observe = 'all.npy'
    args.last_free_energy = 0
    args.emit_sum = 0

    args.out_dir = args.out_dir.format(timestamp=time.strftime('%x_%X').replace('/','-'), **args.__dict__)
    try:
        print 'making', args.out_dir
        os.makedirs(args.out_dir)
    except OSError:
        pass

    if args.warm_start:
        #args.last_free_energy, args.theta, args.alpha, args.beta, args.gamma, args.emit_probs, args.emit_sum = load_params(args)
        #args.warm_start = False
        print '# loading previous params for warm start from %s' % args.warm_start
        tmpargs = copy.deepcopy(args)
        tmpargs.out_dir = args.warm_start
        tmpargs.observe = 'all.npy'
        args.free_energy, args.theta, args.alpha, args.beta, args.gamma, args.emit_probs, args.emit_sum = load_params(tmpargs)
        
        try:
            args.free_energy = list(args.free_energy)
        except TypeError: # no previous free energy
            args.free_energy = []
        print 'done'
        args.warm_start = False
    else:
        (args.theta, args.alpha, args.beta, args.gamma, args.emit_probs) = \
                                                    random_params(args.K,args.L)
        for p in ['free_energy', 'theta', 'alpha', 'beta', 'gamma', 'emit_probs', 'last_free_energy', 'emit_sum']:
            sp.save(os.path.join(args.out_dir, args.out_params.format(param=p, **args.__dict__)),
                args.__dict__[p])
    
    print '# setting up job arguments'
    # set up new versions of args for other jobs
    job_args = [copy.copy(args) for i in range(len(args.observe_matrix))]
    for j, a in enumerate(job_args):
        a.observe_matrix = args.observe_matrix[j]
        a.observe = os.path.split(args.observe_matrix[j])[1]
        a.subtask = True
        a.func = None
        a.iteration = 0
        a.max_iterations = 1
        a.quiet_mode = True
        if j % 1000 == 0:
            print j
    
    if args.run_local:
        pool = multiprocessing.Pool()
    else:
        pool = sge.SGEPool()
        job_handle = pool.imap_unordered(do_inference, job_args)

    converged = False
    for args.iteration in range(args.max_iterations):
        #import ipdb; ipdb.set_trace()
        # fresh parameters-- to be aggregated after jobs are run
        print 'iteration', args.iteration
        total_free = 0
        args.theta = sp.zeros((K,K,K), dtype=sp.float64)
        args.alpha = sp.zeros((K,K), dtype=sp.float64)
        args.beta = sp.zeros((K,K), dtype=sp.float64)
        args.gamma = sp.zeros((K), dtype=sp.float64)
        args.emit_probs = sp.zeros((K,L), dtype=sp.float64)
        args.emit_sum = sp.zeros(K, sp.float64)
        
        if args.run_local:
            iterator = pool.imap_unordered(do_inference, job_args)
            # wait for jobs to finish
            for result in iterator:
                pass
        else:
            jobs_handle = pool.map_async(do_inference, job_args, chunksize=100)
            # wait for all jobs to finish
            for j in jobs_handle:
                j.wait()

        # sum free energies and parameters from jobs
        for a in job_args:
            #print '# loading from %s' % a.observe
            free_energy, theta, alpha, beta, gamma, emit_probs, emit_sum = load_params(a)
            if len(free_energy) > 0:
                last_free_energy = free_energy[-1]
            else:
                last_free_energy = 0
            total_free += last_free_energy
            args.theta += theta
            args.alpha += alpha
            args.beta += beta
            args.gamma += gamma
            args.emit_probs += emit_probs
            args.emit_sum += emit_sum

        # renormalize and plot
        print 'normalize aggregation... total free energy is:', total_free
        args.free_energy.append(total_free)
        if len(args.free_energy) > 1 and args.free_energy[-1] != 0 and args.free_energy[-2] != 0 \
            and abs(args.free_energy[-2] - args.free_energy[-1]) / args.free_energy[-2] < args.epsilon:
            converged = True
        normalize_trans(args.theta, args.alpha, args.beta, args.gamma)
        args.emit_probs[:] = sp.dot(sp.diag(1./args.emit_sum), args.emit_probs)

        for a in job_args:
            a.theta, a.alpha, a.beta, a.gamma, a.emit_probs = args.theta, args.alpha, args.beta, args.gamma, args.emit_probs

        for p in ['free_energy', 'theta', 'alpha', 'beta', 'gamma', 'emit_probs']:
            sp.save(os.path.join(args.out_dir, args.out_params.format(param=p, **args.__dict__)),
                args.__dict__[p])
        plot_params(args)
        plot_energy(args)
        
        if args.save_Q >= 3:
            print '# reconstructing chromosomes from *chunk*',
            in_order = {}
            # Q_chr16_all.trimmed.chunk*.npy => Q_chr16_all.trimmed.npy
            all_chunks = glob.glob(os.path.join(args.out_dir, '*_Q_*chunk*.npy'))
            for chunk in all_chunks:
                print chunk
                chunk_num = int(re.search(r'chunk(\d+)', chunk).groups()[0])
                chrom_out = re.sub('chunk(\d+)\.', '', chunk)
                if chrom_out not in in_order:
                    in_order[chrom_out] = {}
                in_order[chrom_out][chunk_num] = sp.load(chunk)
            for chrom_out in in_order:
                print 'reconstructing chromosomes from', in_order[chrom_out]
                if len(in_order[chrom_out]) > 1:
                    final_array = sp.concatenate((in_order[chrom_out][0], in_order[chrom_out][1]), axis=1)
                    for i in range(2, max(in_order[chrom_out])):
                        final_array = sp.concatenate((final_array, in_order[chrom_out][i]), axis=1)
                else:
                    final_array = in_order[chrom_out][0]
                sp.save(chrom_out, final_array)

        if converged:
            break
Esempio n. 5
0
def independent_update_params(args, renormalize=True):
    X = args.X
    Q, Q_pairs, theta, alpha, beta, gamma, vert_parent, vert_children, log_obs_mat, pseudocount = (
                                                   args.Q, args.Q_pairs, args.theta,
                                                   args.alpha, args.beta,
                                                   args.gamma, args.vert_parent, args.vert_children, args.log_obs_mat, args.pseudocount)
    I, T, K = Q.shape
    L = X.shape[2]

    if args.continuous_observations:
        new_means = np.zeros_like(args.means)
        new_variances = np.zeros_like(args.variances)
        total_q = np.zeros_like(args.variances)
    else:
        emit_probs = args.emit_probs
        emit_probs[:] = pseudocount

    theta[:] = pseudocount
    alpha[:] = pseudocount
    beta[:] = pseudocount
    gamma[:] = pseudocount


    for i in xrange(I):
        vp = vert_parent[i]
        for t in xrange(T):
            for k in xrange(K):
                if i==0 and t==0:
                    gamma[k] += Q[i, t, k]
                else:
                    for v in xrange(K):
                        if t == 0:
                            beta[v,k] += Q[vp,t,v] * Q[i,t,k]
                        else:
                            alpha[v,k] += Q_pairs[i,t,v,k]
                if not args.continuous_observations:
                    for l in xrange(L):
                        if X[i,t,l]:
                            emit_probs[k, l] += Q[i, t, k]
    if args.continuous_observations:
        for i in xrange(I):
            for t in xrange(T):
                for k in xrange(K):
                    for l in xrange(L):
                        new_means[k,l] += Q[i, t, k] * X[i,t,l]  # expectation of X wrt Q
                        total_q[k,l] += Q[i,t,k]

        args.means[:] = new_means = new_means / total_q + 1e-50

        np.seterr(under='ignore')
        for i in xrange(I):
            for t in xrange(T):
                for k in xrange(K):
                    for l in xrange(L):
                        new_variances[k,l] += Q[i, t, k] * (X[i,t,l] - new_means[k,l]) * (X[i,t,l] - new_means[k,l])
        np.seterr(under='print')
        args.variances[:] = new_variances / total_q  # 1 / N_k
        args.variances += pseudocount
    else:
        normalize_emit(Q, emit_probs, pseudocount, args, renormalize)

    if renormalize:
        theta += theta.max() * (pseudocount * 1e-20)
        alpha += alpha.max() * (pseudocount * 1e-20)
        beta += beta.max() * (pseudocount * 1e-20)
        gamma += gamma.max() * (pseudocount * 1e-20)
        normalize_trans(theta, alpha, beta, gamma)

    if args.continuous_observations:
        make_log_obs_matrix_gaussian(args)
    else:
        make_log_obs_matrix(args)
Esempio n. 6
0
def independent_update_params(args, renormalize=True):
    X = args.X
    Q, Q_pairs, theta, alpha, beta, gamma, vert_parent, vert_children, log_obs_mat, pseudocount = (
        args.Q, args.Q_pairs, args.theta, args.alpha, args.beta, args.gamma,
        args.vert_parent, args.vert_children, args.log_obs_mat,
        args.pseudocount)
    I, T, K = Q.shape
    L = X.shape[2]

    if args.continuous_observations:
        new_means = np.zeros_like(args.means)
        new_variances = np.zeros_like(args.variances)
        total_q = np.zeros_like(args.variances)
    else:
        emit_probs = args.emit_probs
        emit_probs[:] = pseudocount

    theta[:] = pseudocount
    alpha[:] = pseudocount
    beta[:] = pseudocount
    gamma[:] = pseudocount

    for i in xrange(I):
        vp = vert_parent[i]
        for t in xrange(T):
            for k in xrange(K):
                if i == 0 and t == 0:
                    gamma[k] += Q[i, t, k]
                else:
                    for v in xrange(K):
                        if t == 0:
                            beta[v, k] += Q[vp, t, v] * Q[i, t, k]
                        else:
                            alpha[v, k] += Q_pairs[i, t, v, k]
                if not args.continuous_observations:
                    for l in xrange(L):
                        if X[i, t, l]:
                            emit_probs[k, l] += Q[i, t, k]
    if args.continuous_observations:
        for i in xrange(I):
            for t in xrange(T):
                for k in xrange(K):
                    for l in xrange(L):
                        new_means[k,
                                  l] += Q[i, t,
                                          k] * X[i, t,
                                                 l]  # expectation of X wrt Q
                        total_q[k, l] += Q[i, t, k]

        args.means[:] = new_means = new_means / total_q + 1e-50

        np.seterr(under='ignore')
        for i in xrange(I):
            for t in xrange(T):
                for k in xrange(K):
                    for l in xrange(L):
                        new_variances[k, l] += Q[i, t, k] * (
                            X[i, t, l] - new_means[k, l]) * (X[i, t, l] -
                                                             new_means[k, l])
        np.seterr(under='print')
        args.variances[:] = new_variances / total_q  # 1 / N_k
        args.variances += pseudocount
    else:
        normalize_emit(Q, emit_probs, pseudocount, args, renormalize)

    if renormalize:
        theta += theta.max() * (pseudocount * 1e-20)
        alpha += alpha.max() * (pseudocount * 1e-20)
        beta += beta.max() * (pseudocount * 1e-20)
        gamma += gamma.max() * (pseudocount * 1e-20)
        normalize_trans(theta, alpha, beta, gamma)

    if args.continuous_observations:
        make_log_obs_matrix_gaussian(args)
    else:
        make_log_obs_matrix(args)
Esempio n. 7
0
def bp_update_params_new(args, renormalize=True):
    lmds, pis = args.lmds, args.pis
    vert_parent, vert_children = args.vert_parent, args.vert_children
    #print  pis[0].shape
    I, T, L = args.X.shape
    K = args.gamma.shape[0]
    theta, alpha, beta, gamma, emit_probs, X = (args.theta, args.alpha,
                                                args.beta, args.gamma,
                                                args.emit_probs, args.X)
    evidence = args.evidence  #evid_allchild(lmds, vert_children)
    emit_probs_mat = sp.exp(args.log_obs_mat)
    #emit_probs_mat /= emit_probs_mat.max(axis=2).reshape(I, T, 1)
    gamma_p = copy.copy(gamma)
    alpha_p = copy.copy(alpha)
    beta_p = copy.copy(beta)
    theta_p = copy.copy(theta)
    #    emit_probs_p = copy.copy(emit_probs)

    theta[:] = args.pseudocount
    alpha[:] = args.pseudocount
    beta[:] = args.pseudocount
    gamma[:] = args.pseudocount
    emit_probs[:] = args.pseudocount

    #evidence = evid_allchild(lmds, args.vert_children)
    ##support = casual_support(pis)

    emit_sum = sp.zeros((K, L))
    for i in xrange(I):
        vp = vert_parent[i]
        if i != 0:
            idx_i = vert_children[vp].tolist().index(i)
        for t in xrange(T):
            if i == 0 and t == 0:
                gamma += emit_probs_mat[i, t, :] * evidence[i, t, :]
                Q = emit_probs_mat[i, t, :] * evidence[i, t, :]
            elif i == 0:
                tmp1, tmp2 = sp.ix_(
                    pis[i][-1, t - 1, :],
                    emit_probs_mat[i, t, :] * evidence[i, t, :])
                tmp = alpha_p * (tmp1 * tmp2)  # belief
                #tmp /= tmp.sum()
                Q = tmp.sum(axis=0)
                alpha += tmp / tmp.sum()
            elif t == 0:
                tmp1, tmp2 = sp.ix_(pis[vp][idx_i,
                                            t, :], emit_probs_mat[i, t, :] *
                                    evidence[i, t, :])  # i-1->0
                tmp = beta_p * (tmp1 * tmp2)  # belief
                Q = tmp.sum(axis=0)
                beta += tmp / tmp.sum()
            else:
                tmp1, tmp2, tmp3 = sp.ix_(
                    pis[vp][idx_i, t, :], pis[i][-1, t - 1, :],
                    emit_probs_mat[i, t, :] * evidence[i, t, :])
                tmp = theta_p * (tmp1 * tmp2 * tmp3)
                Q = (tmp.sum(axis=0)).sum(axis=0)
                theta += tmp / tmp.sum()

            Q /= Q.sum()
            for l in xrange(L):
                if args.mark_avail[i, l] and X[i, t, l]:
                    emit_probs[:, l] += Q
                emit_sum[:, l] += Q
    if renormalize:
        normalize_trans(theta, alpha, beta, gamma)
        emit_probs[:] = sp.dot(sp.diag(1. / emit_sum), emit_probs)
    args.emit_sum = emit_sum
    make_log_obs_matrix(args)