混合高斯模型的EM求解(Mixtures of Gaussians)及Python实现源码

来源:互联网 发布:美甲软件 编辑:程序博客网 时间:2024/05/16 17:11

今天为大家带来混合高斯模型的EM推导求解过程。








全部代码如下!

[python] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. def NDimensionGaussian(X_vector,U_Mean,CovarianceMatrix):  
  2.     #X=numpy.mat(X_vector)  
  3.     X=X_vector  
  4.     D=numpy.shape(X)[0]  
  5.     #U=numpy.mat(U_Mean)  
  6.     U=U_Mean  
  7.     #CM=numpy.mat(CovarianceMatrix)  
  8.     CM=CovarianceMatrix  
  9.     Y=X-U  
  10.     temp=Y.transpose() * CM.I * Y  
  11.     result=(1.0/((2*numpy.pi)**(D/2)))*(1.0/(numpy.linalg.det(CM)**0.5))*numpy.exp(-0.5*temp)  
  12.     return result  
  13.   
  14. def CalMean(X):  
  15.     D,N=numpy.shape(X)  
  16.     MeanVector=numpy.mat(numpy.zeros((D,1)))  
  17.     for d in range(D):  
  18.         for n in range(N):  
  19.             MeanVector[d,0] += X[d,n]  
  20.         MeanVector[d,0] /= float(N)  
  21.     return MeanVector  
  22.   
  23. def CalCovariance(X,MV):  
  24.     D,N=numpy.shape(X)  
  25.     CoV=numpy.mat(numpy.zeros((D,D)))  
  26.     for n in range(N):  
  27.         Temp=X[:,n]-MV  
  28.         CoV += Temp*Temp.transpose()  
  29.     CoV /= float(N)    
  30.     return CoV  
  31.   
  32. def CalEnergy(Xn,Pik,Uk,Cov):  
  33.     D,N=numpy.shape(Xn)  
  34.     D_k,K=numpy.shape(Uk)  
  35.     if D!=D_k:  
  36.         print ('dimension not equal, break')  
  37.         return  
  38.       
  39.     energy=0.0  
  40.     for n_iter in range(N):  
  41.         temp=0   
  42.         for k_iter in range(K):  
  43.             temp += Pik[0,k_iter] * NDimensionGaussian(Xn[:,n_iter],Uk[:,k_iter],Cov[k_iter])  
  44.         energy += numpy.log(temp)  
  45.     return float(energy)  
  46.   
  47. def SequentialEMforMixGaussian(InputData,K):  
  48.     #初始化piK  
  49.     pi_Cof=numpy.mat(numpy.ones((1,K))*(1.0/float(K)))  
  50.     X=numpy.mat(InputData)  
  51.     X_mean=CalMean(X)  
  52.     print (X_mean)  
  53.     X_cov=CalCovariance(X,X_mean)  
  54.     print (X_cov)  
  55.     #初始化uK,其中第k列表示第k个高斯函数的均值向量  
  56.     #X为D维,N个样本点  
  57.     D,N=numpy.shape(X)  
  58.     print (D,N)  
  59.     UK=numpy.mat(numpy.zeros((D,K)))  
  60.     for d_iter in range(D):  
  61.         for k_iter in range(K):  
  62.             UK[d_iter,k_iter] = X_mean[d_iter,0] + (-1)**k_iter + (-1)**d_iter   
  63.     print (UK)  
  64.     #初始化k个协方差矩阵的列表  
  65.     List_cov=[]  
  66.       
  67.     for k_iter in range(K):  
  68.         List_cov.append(numpy.mat(numpy.eye(X[:,0].size)))  
  69.     print (List_cov)  
  70.       
  71.     List_cov_new=copy.deepcopy(List_cov)  
  72.     rZnk=numpy.mat(numpy.zeros((N,K)))  
  73.     denominator=numpy.mat(numpy.zeros((N,1)))  
  74.     rZnk_new=numpy.mat(numpy.zeros((N,K)))  
  75.       
  76.     Nk=0.5*numpy.mat(numpy.ones((1,K)))  
  77.     print (Nk)  
  78.     Nk_new=numpy.mat(numpy.zeros((1,K)))  
  79.     UK_new=numpy.mat(numpy.zeros((D,K)))  
  80.     pi_Cof_new=numpy.mat(numpy.zeros((1,K)))  
  81.       
  82.     for n_iter in range(1,N):  
  83.         #rZnk=pi_k*Gaussian(Xn|uk,Cov_k)/sum(pi_j*Gaussian(Xn|uj,Cov_j))  
  84.         for k_iter in range(K):  
  85.             rZnk_new[n_iter,k_iter] = pi_Cof[0,k_iter] * NDimensionGaussian(X[:,n_iter],UK[:,k_iter],List_cov[k_iter])  
  86.             denominator[n_iter,0] += rZnk_new[n_iter,k_iter]       
  87.         for k_iter in range(K):  
  88.             rZnk_new[n_iter,k_iter] /= denominator[n_iter,0]  
  89.             print ('rZnk_new', rZnk_new[n_iter,k_iter],'\n')             
  90.         for k_iter in range(K):  
  91.             Nk_new[0,k_iter] = Nk[0,k_iter] + rZnk_new[n_iter,k_iter] - rZnk[n_iter,k_iter]  
  92.             print ('Nk_new',Nk_new,'\n')  
  93.             ##############当前有(n_iter+1)样本###########################    
  94.             pi_Cof_new[0,k_iter] = Nk_new[0,k_iter]/float(n_iter+1)  
  95.             print ('pi_Cof_new',pi_Cof_new,'\n')  
  96.             UK_new[:,k_iter] = UK[:,k_iter] + ( (rZnk_new[n_iter,k_iter] - rZnk[n_iter,k_iter])/float(Nk_new[0,k_iter]) ) * (X[:,n_iter]-UK[:,k_iter])            
  97.             print ('UK_new',UK_new,'\n')  
  98.             Temp = X[:,n_iter] - UK_new[:,k_iter]  
  99.             List_cov_new[k_iter] = List_cov[k_iter] + ((rZnk_new[n_iter,k_iter] - rZnk[n_iter,k_iter])/float(Nk_new[0,k_iter]))*(Temp*Temp.transpose()-List_cov[k_iter])        
  100.             print ('List_cov_new',List_cov_new,'\n')  
  101.           
  102.         rZnk=copy.deepcopy(rZnk_new)  
  103.         pi_Cof=copy.deepcopy(pi_Cof_new)  
  104.         UK_new=copy.deepcopy(UK)  
  105.         List_cov=copy.deepcopy(List_cov_new)  
  106.     print (pi_Cof,UK_new,List_cov)  
  107.     return pi_Cof,UK_new,List_cov  
  108.   
  109. def BatchEMforMixGaussian(InputData,K,MaxIter):  
  110.     #初始化piK  
  111.     pi_Cof=numpy.mat(numpy.ones((1,K))*(1.0/float(K)))  
  112.     X=numpy.mat(InputData)  
  113.     X_mean=CalMean(X)  
  114.     print (X_mean)  
  115.     X_cov=CalCovariance(X,X_mean)  
  116.     print (X_cov)  
  117.     #初始化uK,其中第k列表示第k个高斯函数的均值向量  
  118.     #X为D维,N个样本点  
  119.     D,N=numpy.shape(X)  
  120.     print (D,N)  
  121.     UK=numpy.mat(numpy.zeros((D,K)))  
  122.     for d_iter in range(D):  
  123.         for k_iter in range(K):  
  124.             UK[d_iter,k_iter] = X_mean[d_iter,0] + (-1)**k_iter + (-1)**d_iter   
  125.     print (UK)  
  126.     #初始化k个协方差矩阵的列表  
  127.     List_cov=[]  
  128.       
  129.     for k_iter in range(K):  
  130.         List_cov.append(numpy.mat(numpy.eye(X[:,0].size)))  
  131.     print (List_cov)  
  132.       
  133.     energy_new=0  
  134.     energy_old=CalEnergy(X,pi_Cof,UK,List_cov)  
  135.     print (energy_old)  
  136.     currentIter=0  
  137.     while True:  
  138.         currentIter += 1  
  139.           
  140.         List_cov_new=[]  
  141.         rZnk=numpy.mat(numpy.zeros((N,K)))  
  142.         denominator=numpy.mat(numpy.zeros((N,1)))  
  143.         Nk=numpy.mat(numpy.zeros((1,K)))  
  144.         UK_new=numpy.mat(numpy.zeros((D,K)))  
  145.         pi_new=numpy.mat(numpy.zeros((1,K)))  
  146.           
  147.         #rZnk=pi_k*Gaussian(Xn|uk,Cov_k)/sum(pi_j*Gaussian(Xn|uj,Cov_j))  
  148.         for n_iter in range(N):   
  149.             for k_iter in range(K):  
  150.                 rZnk[n_iter,k_iter] = pi_Cof[0,k_iter] * NDimensionGaussian(X[:,n_iter],UK[:,k_iter],List_cov[k_iter])  
  151.                 denominator[n_iter,0] += rZnk[n_iter,k_iter]       
  152.             for k_iter in range(K):  
  153.                 rZnk[n_iter,k_iter] /= denominator[n_iter,0]  
  154.                 #print 'rZnk', rZnk[n_iter,k_iter]  
  155.           
  156.         #pi_new=sum(rZnk)          
  157.         for k_iter in range(K):  
  158.             for n_iter in range(N):  
  159.                 Nk[0,k_iter] += rZnk[n_iter,k_iter]  
  160.             pi_new[0,k_iter] = Nk[0,k_iter]/(float(N))  
  161.             #print 'pi_k_new',pi_new[0,k_iter]  
  162.           
  163.         #uk_new= (1/sum(rZnk))*sum(rZnk*Xn)      
  164.         for k_iter in range(K):  
  165.             for n_iter in range(N):  
  166.                 UK_new[:,k_iter] += (1.0/float(Nk[0,k_iter]))*rZnk[n_iter,k_iter]*X[:,n_iter]  
  167.             #print 'UK_new',UK_new[:,k_iter]  
  168.               
  169.         for k_iter in range(K):  
  170.             X_cov_new=numpy.mat(numpy.zeros((D,D)))  
  171.             for n_iter in range(N):  
  172.                 Temp = X[:,n_iter] - UK_new[:,k_iter]  
  173.                 X_cov_new += (1.0/float(Nk[0,k_iter]))*rZnk[n_iter,k_iter] * Temp * Temp.transpose()  
  174.             #print 'X_cov_new',X_cov_new  
  175.             List_cov_new.append(X_cov_new)  
  176.           
  177.         energy_new=CalEnergy(X,pi_new,UK_new,List_cov)  
  178.         print ('energy_new',energy_new)  
  179.         #print pi_new  
  180.         #print UK_new  
  181.         #print List_cov_new  
  182.         if energy_old>=energy_new or currentIter>MaxIter:  
  183.             UK=copy.deepcopy(UK_new)  
  184.             pi_Cof=copy.deepcopy(pi_new)  
  185.             List_cov=copy.deepcopy(List_cov_new)  
  186.             break  
  187.         else:  
  188.             UK=copy.deepcopy(UK_new)  
  189.             pi_Cof=copy.deepcopy(pi_new)  
  190.             List_cov=copy.deepcopy(List_cov_new)  
  191.             energy_old=energy_new  
  192.   
  193.           
  194. return pi_Cof,UK,List_cov  
0 0
原创粉丝点击