def calc_IDR(theta, r1, r2): """ idr <- 1 - e.z o <- order(idr) idr.o <- idr[o] idr.rank <- rank(idr.o, ties.method = "max") top.mean <- function(index, x) { mean(x[1:index]) } IDR.o <- sapply(idr.rank, top.mean, idr.o) IDR <- idr IDR[o] <- IDR.o """ mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p, EPS=1e-12) z2 = compute_pseudo_values(r2, mu, sigma, p, EPS=1e-12) localIDR = 1-calc_post_membership_prbs(numpy.array(theta), z1, z2) if idr.FILTER_PEAKS_BELOW_NOISE_MEAN: localIDR[z1 + z2 < 0] = 1 # it doesn't make sense for the IDR values to be smaller than the # optimization tolerance localIDR = numpy.clip(localIDR, idr.CONVERGENCE_EPS_DEFAULT, 1) local_idr_order = localIDR.argsort() ordered_local_idr = localIDR[local_idr_order] ordered_local_idr_ranks = rankdata( ordered_local_idr, method='max' ) IDR = [] for i, rank in enumerate(ordered_local_idr_ranks): IDR.append(ordered_local_idr[:rank].mean()) IDR = numpy.array(IDR)[local_idr_order.argsort()] return localIDR, IDR
def calc_IDR(theta, r1, r2): """ idr <- 1 - e.z o <- order(idr) idr.o <- idr[o] idr.rank <- rank(idr.o, ties.method = "max") top.mean <- function(index, x) { mean(x[1:index]) } IDR.o <- sapply(idr.rank, top.mean, idr.o) IDR <- idr IDR[o] <- IDR.o """ mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p, EPS=1e-12) z2 = compute_pseudo_values(r2, mu, sigma, p, EPS=1e-12) localIDR = 1 - calc_post_membership_prbs(numpy.array(theta), z1, z2) if idr.FILTER_PEAKS_BELOW_NOISE_MEAN: localIDR[z1 + z2 < 0] = 1 # it doesn't make sense for the IDR values to be smaller than the # optimization tolerance localIDR = numpy.clip(localIDR, idr.CONVERGENCE_EPS_DEFAULT, 1) local_idr_order = localIDR.argsort() ordered_local_idr = localIDR[local_idr_order] ordered_local_idr_ranks = rankdata(ordered_local_idr, method='max') IDR = [] for i, rank in enumerate(ordered_local_idr_ranks): IDR.append(ordered_local_idr[:rank].mean()) IDR = numpy.array(IDR)[local_idr_order.argsort()] return localIDR, IDR
def gradient_ascent(r1, r2, theta, gradient_magnitude, fix_mu=False, fix_sigma=False): for j in range(len(theta)): if fix_mu and j == 0: continue if fix_sigma and j == 1: continue prev_loss = calc_loss(r1, r2, theta) mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p) z2 = compute_pseudo_values(r2, mu, sigma, p) real_grad = calc_pseudo_log_lhd_gradient(theta, z1, z2, False, False) gradient = numpy.zeros(len(theta)) gradient[j] = gradient_magnitude if real_grad[j] < 0: gradient[j] = -gradient[j] min_step = 0 max_step = find_max_step_size( theta[j], gradient[j], (False if j in (0,1) else True)) if max_step < 1e-12: continue alpha = fminbound( lambda x: calc_loss( r1, r2, theta + x*gradient ), min_step, max_step) loss = calc_loss( r1, r2, theta + alpha*gradient ) if loss < prev_loss: theta += alpha*gradient return theta
def grid_search(r1, r2 ): res = [] best_theta = None max_log_lhd = -1e100 for mu in numpy.linspace(0.1, 5, num=10): for sigma in numpy.linspace(0.5, 3, num=10): for rho in numpy.linspace(0.1, 0.9, num=10): for pi in numpy.linspace(0.1, 0.9, num=10): z1 = compute_pseudo_values(r1, mu, sigma, pi) z2 = compute_pseudo_values(r2, mu, sigma, pi) log_lhd = calc_gaussian_mix_log_lhd((mu, sigma, rho, pi), z1, z2) if log_lhd > max_log_lhd: best_theta = ((mu,mu), (sigma,sigma), rho, pi) max_log_lhd = log_lhd return best_theta
def find_local_maximum_CA(r1, r2, theta, fix_mu=False, fix_sigma=False ): gradient_magnitude = 1e-2 for i in range(100): prev_loss = calc_loss(r1, r2, theta) # coordiante ascent step theta = coordinate_ascent( r1, r2, theta, gradient_magnitude, fix_mu=fix_mu, fix_sigma=fix_sigma) curr_loss = calc_loss(r1, r2, theta) log( "CA%i\t" % i, "%.2e" % gradient_magnitude, "%.2e" % (curr_loss-prev_loss), "%.8f\t" % curr_loss, "%.8f\t" % log_lhd_loss(r1, r2, theta), theta, level='VERBOSE' ) # find the em estimate mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p) z2 = compute_pseudo_values(r2, mu, sigma, p) em_theta = EM_step(z1, z2, theta ) for j in (3,2,1,0): tmp_theta = theta.copy() tmp_theta[j] = em_theta[j] if calc_loss(r1, r2, tmp_theta) < curr_loss: theta[j] = em_theta[j] mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p) z2 = compute_pseudo_values(r2, mu, sigma, p) grad = calc_pseudo_log_lhd_gradient(theta, z1, z2, False, False) #log( "GRAD", grad ) if abs(curr_loss-prev_loss) < 1e-12: if gradient_magnitude > 1e-6: gradient_magnitude /= 3 else: return ( theta, curr_loss ) else: gradient_magnitude = min(1e-2, gradient_magnitude*10) return theta, curr_loss
def EMP_with_pseudo_value_algorithm( r1, r2, theta_0, N=100, EPS=1e-4, fix_mu=False, fix_sigma=False): theta = theta_0 z1 = compute_pseudo_values(r1, theta[0], theta[1], theta[3]) z2 = compute_pseudo_values(r2, theta[0], theta[1], theta[3]) max_num_EM_iter = 30 for i in range(N): prev_theta = theta # EM only works in the unconstrained case if not fix_mu and not fix_sigma: theta, new_lhd, changed_params = EM_iteration( z1, z2, prev_theta, max_num_EM_iter, fix_mu=fix_mu, fix_sigma=fix_sigma, eps=EPS/10) if fix_mu or fix_sigma or changed_params: theta = prev_theta theta, new_lhd = CA_iteration( z1, z2, prev_theta, max_num_EM_iter, fix_mu=fix_mu, fix_sigma=fix_sigma, eps=EPS/10) sum_param_change = numpy.abs(theta - prev_theta).sum() prev_z1 = z1 z1 = compute_pseudo_values(r1, theta[0], theta[1], theta[3]) prev_z2 = z2 z2 = compute_pseudo_values(r2, theta[0], theta[1], theta[3]) mean_pseudo_val_change = ( numpy.abs(prev_z1-z1).mean() + numpy.abs(prev_z2-z2).mean()) log(("Iter %i" % i).ljust(12), "%.2e" % sum_param_change, "%.2e" % mean_pseudo_val_change, #"%.4e" % log_lhd_loss(r1, r2, theta), theta, level='VERBOSE') if i > 3 and (sum_param_change < EPS and mean_pseudo_val_change < EPS): break return theta, log_lhd_loss(r1, r2, theta)
def find_local_maximum_PV(r1, r2, theta, N=100, EPS=1e-6, fix_mu=False, fix_sigma=False ): for i in range(N): prev_loss = calc_loss(r1, r2, theta) curr_loss = prev_loss # find the em estimate mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p) z2 = compute_pseudo_values(r2, mu, sigma, p) em_theta = EM_step(z1, z2, theta ) # take a step in the EM direction for j in (3,2,1,0): tmp_theta = theta.copy() tmp_theta[j] = em_theta[j] new_loss = calc_loss(r1, r2, tmp_theta) if new_loss < curr_loss: theta[j] = em_theta[j] curr_loss = new_loss msg = " ".join(("CA%i\t" % i, "%.2e" % gradient_magnitude, "%.2e" % (curr_loss-prev_loss), "%.8f\t" % curr_loss, "%.8f\t" % log_lhd_loss(r1, r2, theta), theta)) log( msg, level='VERBOSE' ) mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p) z2 = compute_pseudo_values(r2, mu, sigma, p) grad = calc_gaussian_mix_log_lhd_gradient(theta, z1, z2, False, False) if abs(curr_loss-prev_loss) < EPS: return ( theta, curr_loss ) return theta, curr_loss
def sum_grad_sq_loss(r1, r2, theta): mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p) z2 = compute_pseudo_values(r2, mu, sigma, p) grad = calc_pseudo_log_lhd_gradient(theta, z1, z2, False, False) return (grad**2).sum()
def log_lhd_loss(r1, r2, theta): mu, sigma, rho, p = theta z1 = compute_pseudo_values(r1, mu, sigma, p) z2 = compute_pseudo_values(r2, mu, sigma, p) return -calc_gaussian_mix_log_lhd(theta, z1, z2)