def gmm(X,C,eps): import numpy as np from norm_density import norm_density from copy import deepcopy # Initialisations counter = 0; mu_est = 2*np.mean(X) * np.sort(np.random.uniform(0,1,C)); sigma_est = np.ones(C)*np.std(X); p_est = np.ones(C)/C; difference = eps; dens = np.tile(np.zeros(len(X)),(C,1)) # Perform EM algorithm to find means and sigmas while (difference >= eps) & (counter < 25000): # E step: soft densification of the X into one of the mixtures for j in range(0,C): dens[j] = p_est[j] * norm_density(X, mu_est[j], sigma_est[j]); #normalize dens = dens / np.tile(sum(dens), (C, 1)); #M step: ML estimate the parameters of each dens (i.e., p, mu, sigma) mu_est_old = deepcopy(mu_est); sigma_est_old = deepcopy(sigma_est); p_est_old = deepcopy(p_est); # Get next values for all means, sigmas and pis for j in range(0,C): mu_est[j] = sum( dens[j,:]*X ) / sum(dens[j,:]); sigma_est[j] = np.sqrt( sum(dens[j,:]*(X - mu_est[j])**2) / sum(dens[j,:]) ); p_est[j] = np.mean(dens[j,:]); # Compute Mean square errors of all estimates difference = sum(abs(np.array(mu_est_old)-np.array(mu_est))) + sum(abs(np.array(sigma_est_old)-np.array(sigma_est))) + sum(abs(np.array(p_est_old)-np.array(p_est))) counter = counter + 1; return mu_est, sigma_est, p_est, counter, difference
print('------Means--------') print('mu_1=%1.4f'%mu_est[0]) print('mu_2=%1.4f'%mu_est[1]) print('mu_3=%1.4f'%mu_est[2]) print('------Variance--------') print('sigma_1=%1.4f'%sigma_est[0]) print('sigma_2=%1.4f'%sigma_est[1]) print('sigma_3=%1.4f'%sigma_est[2]) print('------Weights-------') print('W_1=%1.4f'%p_est[0]) print('W_2=%1.4f'%p_est[1]) print('W_3=%1.4f'%p_est[2]) x = np.linspace(min(mu_est)-4*max(sigma_est),max(mu_est)+4*max(sigma_est),1000); pdf = np.tile(np.zeros(1000),(C,1)) for i in range(0,C): pdf[i] = p_est[i]*norm_density(x,mu_est[i],sigma_est[i]) # plt.plot(x,pdf[i]) plt.hist(ib, bins=60, normed=True,histtype='step', color='grey',label='2014 Data') plt.plot(x, sum(pdf), lw=1.5, color='black',label='fit'); plt.xlabel('$I_{base}$') plt.ylim((0.0,0.17)) plt.xlim((-2,35)) plt.ylabel('fraction') plt.legend() plt.title('Prior distribution of baseline magnification') plt.show()