Problème de Em

essafi -  
 Essafi -
Bonjour,
En tournant l'algorithme de EM dans la première inversion de matrice il donne une ligne nule .
Pouvez - vous svp nous exliquer le problème :)

2 réponses

  1. ngounou25 Messages postés 110 Statut Membre 4
     
    C'est laquelle des lignes qui est nulle ? La première ? La dernière ? Ou une ligne quelconque intermédiaire entre la première et la dernière ?
    0
    1. essafi
       
      Salut
      C'est la dernière ligne qui est nulle .
      Merci
      0
    2. ngounou25 Messages postés 110 Statut Membre 4
       
      Si tu utilise des boucles "for" imbriquées en parcourant ta matrice ligne après ligne, alors vérifie la condition de la boucle "for" la plus externe. Sinon, tu peut toujours poster ton code ici afin qu'on le regarde ensemble. ;-)
      0
    3. Essafi
       
      Bonjour ; Pouvez vous m'envoyer un code qui fonctionne bien svp . Et merci d'avance
      0
    4. ngounou25 Messages postés 110 Statut Membre 4
       
      Bonjour Essafi.

      Mets ton code en ligne et nous le regarderons ensemble.
      0
    5. Essafi
       
      Le voila mon code
      // ???????????????le problème c'est dans la fonction lvs qui calcul le test d'arret "log vraisemblance complétée"
      //??????????????le calcul de log() dans cette fonction me donne une valeur indeterminée et c'est cela le grand problème
      #include<stdio.h>
      #include<stdlib.h>
      #include<math.h>
      #include<conio.h>
      #include<time.h>
      #define n 4
      #define m 150
      //#define t 3
      struct maxi{
      int xi;
      int yi;
      };
      struct mat{
      int d;
      float** x;
      };
      struct matt{
      int d;
      int** x;
      };
      struct tmat{
      mat *t;
      } ;
      struct fli{
      float f;
      int z;
      };
      //la fonction qui lit un fichier
      mat M,N;
      mat lire(char *nom1)
      {
      M.x=(float **) malloc(m*sizeof(float*));
      for(int i=0;i<m;i++)
      {M.x[i]=(float *) malloc(n*sizeof(float));
      }
      FILE *f1;
      char ca[10];
      f1=fopen(nom1,"r");
      if ((f1!=NULL))
      {
      for(int i=0;i<m;i++)
      {for(short j=0;j<n;j++)
      {
      fscanf(f1,"%s",&ca);
      M.x[i][j]=atof(ca);
      }}
      }
      else
      {
      printf("\nErreur d'ouverture\n");
      system("pause");
      exit(0);
      }
      return M;
      }
      mat normalisermat(mat M)
      {float norme;
      for(int i=0;i<m;i++)
      {norme=0;
      for(int j=0;j<n;j++)
      norme=norme+M.x[i][j];
      norme=norme*1./n;
      for(int j=0;j<n;j++)
      M.x[i][j]=M.x[i][j]*1./norme;
      }
      return M;
      }
      //la fonction d'affichage d'une matrice//
      void affimat(mat M, int k, int l)
      {
      for(int i=0;i<k;i++)
      {for(int j=0;j<l;j++)
      {
      printf("%f\t",(M.x[i][j]));
      }
      printf("\n");
      }
      printf("\n");
      }
      // la fonction d'affichage de sigma
      void affitmat(tmat M, int d)
      {
      for(int k=0;k<d;k++)
      {
      for(int i=0;i<n;i++)
      {for(int j=0;j<n;j++)
      printf("%f\t",M.t[k].x[i][j]);
      printf("\n");
      }
      printf("\n\n");
      }
      }
      // la fonction qui determine la valeur maximale parmi les elts d'une matice
      float maxmat(mat A,int nbl)
      {float max=A.x[0][0];
      for(int i=0;i<nbl;i++)
      {for(int j=0;j<n;j++)
      {if(A.x[i][j]>max)
      {max=A.x[i][j];
      }
      }
      }
      return max;
      }
      /////////////////////////////////////////////////les fonctions necessaires pour inverser une matrice////////////////////////////////
      void afficherMatrice(mat mat1)
      {
      int i,j;
      for (i=0;i<n;i++)
      {
      for (j=0;j<n;j++)
      {
      printf("%f ",mat1.x[i][j]);
      }
      printf("\n" );
      }
      }
      mat initialiser(mat mat1)
      {
      mat1.x=(float **) malloc(n*sizeof(float*));
      for(int i=0;i<n;i++)
      {mat1.x[i]=(float *) malloc(n*sizeof(float));
      }
      for (int i=0;i<n;i++)
      {
      for (int j=0;j<n;j++)
      { if(i==j)
      mat1.x[i][j]=1;
      else
      mat1.x[i][j]=2;
      } }
      return mat1;
      }
      void afficherMatriceIdentite(mat matId)
      {
      int i,j;
      for (i=0;i<n;i++)
      {
      for (j=0;j<n;j++)
      {
      printf("%f ",matId.x[i][j]);
      }
      printf("\n" );
      }
      }
      void afficherMatriceInverse(mat NewMat)
      {
      int i,j;
      float elem;
      for (i=0;i<n;i++)
      {
      for (j=0;j<2*n;j++)
      {
      printf("%f ",NewMat.x[i][j]);
      }
      printf("\n" );
      }
      }
      mat creerMatriceId(mat matId)
      {
      matId.x=(float **) malloc(n*sizeof(float*));
      for(int i=0;i<n;i++)
      {matId.x[i]=(float *) malloc(n*sizeof(float));
      }
      int i,j;
      for (i=0;i<n;i++)
      {
      for (j=0;j<n;j++)
      {
      if (i==j)
      {
      matId.x[i][j] = 1;
      }
      else
      {
      matId.x[i][j] = 0;
      }
      }
      }
      return matId;}
      mat definirNouvelleMatrice(mat mat1,mat matId)
      {mat NewMat;
      NewMat.x=(float **) malloc(n*sizeof(float*));
      for(int i=0;i<n;i++)
      {NewMat.x[i]=(float *) malloc(2*n*sizeof(float));
      }
      int i,j;
      i=j=0;
      for (i=0;i<n;i++)
      {
      for (j=0;j<2*n;j++)
      {
      if (j<n)
      {
      NewMat.x[i][j] = mat1.x[i][j];
      }
      else
      {
      NewMat.x[i][j] = matId.x[i][j-n];
      }
      }
      }
      return NewMat;
      }
      int MethodeGauss(mat NewMat)
      {
      int inversible = 1;
      int k,i,colonne,colonnebis;
      float var,var1;
      k=0;
      while((inversible == 1)&&(k<n))
      {
      if (NewMat.x[k][k] != 0)
      {
      var = NewMat.x[k][k];
      for (colonne=0;colonne<2*n;colonne++)
      {
      NewMat.x[k][colonne] = NewMat.x[k][colonne]/var; //Normalisation de la ligne contenant l'élément diagonal
      }
      for (i=0;i<n;i++)
      {
      if (i!=k)
      {
      var1=NewMat.x[i][k];
      for (colonnebis=0;colonnebis<2*n;colonnebis++)
      {
      NewMat.x[i][colonnebis] = NewMat.x[i][colonnebis] - NewMat.x[k][colonnebis]*var1;
      }
      }
      printf("\n\n");
      //afficherMatriceInverse(NewMat);
      //getch();
      }
      k++;
      }
      else
      {
      inversible = 0;
      }
      }
      return inversible;
      }
      mat modifierMatrice(mat NewMat,mat mat1)
      {mat matId;
      afficherMatrice(mat1);
      matId=creerMatriceId(matId);
      NewMat=definirNouvelleMatrice(mat1,matId);
      return NewMat;
      }
      void multiplication(mat mat1,mat NewMat)
      { mat multiple;
      multiple.x=(float **) malloc(n*sizeof(float*));
      for(int i=0;i<n;i++)
      {multiple.x[i]=(float *) malloc(n*sizeof(float));
      }
      for (int i=0;i<n;i++)
      {
      for (int j=0;j<n;j++)
      {multiple.x[i][j]=0;
      for (int k=0;k<n;k++)
      {multiple.x[i][j]=multiple.x[i][j]+mat1.x[i][k]*NewMat.x[k][j+n];
      }
      }}
      printf("la matrice multiple est:\n");
      for (int i=0;i<n;i++)
      {
      for (int j=0;j<n;j++)
      {printf("%f\t",multiple.x[i][j]);
      }
      printf("\n");}
      }
      mat inverse(mat mat1)
      { mat NewMat,inv;
      inv.x=(float **) malloc(n*sizeof(float*));
      for(int i=0;i<n;i++)
      {inv.x[i]=(float *) malloc(n*sizeof(float));
      }
      NewMat=modifierMatrice(NewMat,mat1);
      if (MethodeGauss(NewMat) == 1)
      {
      /* printf("Matrice inverse, le %d:\n",MethodeGauss(NewMat) );
      afficherMatriceInverse(NewMat);*/
      for (int i=0;i<n;i++)
      { for (int j=0;j<n;j++)
      {inv.x[i][j]=NewMat.x[i][j+n];
      }}
      }
      else
      {
      printf("La matrice n'est pas inversible\n" );
      }
      multiplication(mat1,NewMat);
      printf("tout c'est bien termine\n" );
      return inv;
      }
      ////////////////////////////////////////////la fin de des fonctions pour inverser une matrice/////////////////////////////////////
      // determination de la loi normale
      float lnormale(float* t,mat A)
      {float *S;
      float result=0;
      mat N;
      S=(float *)malloc(n*sizeof(float));
      N=inverse(A);
      printf("la matrice inverse est :\n");
      afficherMatrice(N);
      printf("\n\n");
      //getch();
      printf("je suis dans la fonction lnormale\n");
      for(int k=0;k<n;k++)
      {S[k]=0;
      for(int l=0;l<n;l++)
      {S[k]=S[k]+A.x[k][l]*t[l];
      }}
      printf("le vecteur S est : \n");
      for(int o=0;o<n;o++)
      printf("%f\t",S[o]);
      printf("\n\n");
      for(int k=0;k<n;k++)
      {result=result+(S[k]*t[k]);
      printf("le resultat de la multip est %f \n",result);
      }
      result=exp(result*(-0.5));
      printf("le resultat de exp est %f \n",result);
      result=result*49*(1./(4*441*sqrt(maxmat(A,n))));
      printf("le max est %f\n",maxmat(A,n));
      printf("la racine est %f\n",sqrt(maxmat(A,n)));
      printf("result est %f \n",result);
      //getch();
      return result;
      }
      // le calcul de la vrai semblance complétée
      float lvs(tmat sigma,mat mu,float *t,int d,mat z)
      {
      float *aide;
      float lvs=0,p=0;
      aide=(float *)malloc(n*sizeof(float));
      printf("je suis dans la fonction lvs\n");
      /*for(int i=0;i<m;i++)
      {
      for(int k=0;k<d;k++)
      {for(int l=0;l<n;l++)
      {aide[l]=M.x[i][l]-mu.x[k][l];
      printf("aide est%f\n",aide[l]);
      }
      p=p+t[k]*lnormale(aide,sigma.t[k]);
      }
      printf("p est %f\n",p);
      lvs=lvs+log(p);
      printf("lvs est %f\n",lvs);
      getch();
      }*/
      for(int i=0;i<m;i++)
      {for(int k=0;k<d;k++)
      {for(int l=0;l<n;l++)
      {aide[l]=M.x[i][l]-mu.x[k][l];
      //printf("aide est %f\n",aide);
      }
      printf("le vecteur aide dans lvs est : \n");
      for(int o=0;o<n;o++)
      printf("%f\t",aide[o]);
      printf("\n\n");
      //getch();
      lvs=lvs+z.x[i][k]*log(t[k]*lnormale(aide,sigma.t[k]));
      printf("lvs[%d] est %f\n",k,lvs);
      //getch();
      }
      }
      printf("le test d'arret est %f\n",lvs);
      getch();
      return lvs;
      }
      //la fontion qui inverse une matrice
      /*mat inverse(mat M)
      {
      }*/
      //la fonction qui calcul la loi normale
      //la fonction EM
      int* EM(float *pi, mat mu, tmat sigma, int d)
      {
      mat tik,zik,H;
      float pi1=0;
      float *aide;
      float max;
      float *aide2;
      int *z;
      tik.x=(float **) malloc(m*sizeof(float*));
      for(int i=0;i<m;i++)
      {tik.x[i]=(float *)malloc(d*sizeof(float));
      }
      zik.x=(float **) malloc(m*sizeof(float*));
      for(int i=0;i<m;i++)
      {zik.x[i]=(float *)malloc(d*sizeof(float));
      }
      H.x=(float **) malloc(m*sizeof(float*));
      for(int i=0;i<m;i++)
      {H.x[i]=(float *)malloc(n*sizeof(float));
      }
      z=(int *)malloc(m*sizeof(int));
      aide=(float *)malloc(n*sizeof(float));
      aide2=(float *)malloc(n*sizeof(float));
      // initialisation
      pi[0]=0.612;
      pi[1]=0.398;
      /*for(int i=0;i<d;i++)
      {if(pi1<1)
      {pi[i]=(rand()*1.0)/RAND_MAX;
      pi1=pi1+pi[i];
      printf("p%d est %f\n",i,pi[i]);
      printf("pi1 est %f\n",pi1);
      continue;}
      else
      pi[i]=(rand()*1.0)/RAND_MAX;
      }*/
      for(int i=0;i<d;i++)
      printf("%f\t",pi[i]);
      printf("\n\n");
      getch();
      for(int i=0;i<d;i++)
      {for(int j=0;j<n;j++)
      mu.x[i][j]=(rand()*1.0)/RAND_MAX;
      }
      /*for(int i=0;i<m;i++)
      {for(int j=0;j<d;j++)
      zik.x[i][j]=100;
      } */
      affimat(mu,d,n);
      for(int k=0;k<d;k++)
      {
      for(int i=0;i<n;i++)
      {for(int j=0;j<n;j++)
      {if(i==j)
      sigma.t[k].x[i][j]=1;
      else
      sigma.t[k].x[i][j]=0;
      }
      }
      }
      affitmat(sigma,d);
      // fin de l'initialisation
      do
      {
      //E-step : Espérance
      // le calcul des tik
      float cpt=0;
      for(int k=0;k<d;k++)
      {for(int i=0;i<m;i++)
      {for(int l=0;l<d;l++)
      {for(int s=0;s<n;s++)
      { aide2[s]=M.x[i][s]-mu.x[l][s];
      }//fin de la bioucle s
      printf("le vecteur aide dans le calcul de tik est : \n");
      for(int o=0;o<n;o++)
      printf("%f\t",aide2[o]);
      printf("\n\n");
      //getch();
      cpt=cpt+pi[l]*lnormale(aide2,sigma.t[l]);
      printf("le cpt est : %f\n",cpt);
      //getch();
      }// la fin de la boucle l
      for(int s=0;s<n;s++)
      {aide[s]=M.x[i][s]-mu.x[k][s];
      }//fin de la bioucle s
      tik.x[i][k]=(pi[k]*lnormale(aide,sigma.t[k]))*(1./cpt);
      //printf("tik[%d][%d] est %f\n",i,k,tik.x[i][k]);
      //getch();
      }// la fin de la boucle i
      }// la fin de la boucle k

      //getch();
      printf("la matrice des tik est : \n");
      affimat(tik,m,d);
      //getch();
      // E-step : classification
      // le calcul de zik
      for(int k=0;k<m;k++)
      {max=tik.x[k][0];
      z[k]=0;
      for(int i=0;i<d;i++)
      {if(tik.x[k][i]>max)
      {max=tik.x[k][i];
      z[k]=i;
      }}
      for(int k=0;k<m;k++)
      {for(int i=0;i<d;i++)
      {if(z[k]==i)
      zik.x[k][i]=1;
      else
      zik.x[k][i]=0;
      }}}
      printf("la matrice des zik est : \n");
      affimat(zik,m,d);
      //getch();
      // E-step : maximisation
      //le calcul des pik
      for(int i=0;i<d;i++)
      {pi[i]=0;
      for(int j=0;j<m;j++)
      {pi[i]=pi[i]+tik.x[j][i];
      }
      pi[i]=pi[i]*(1./m);
      //printf("pi est %f\n",pi[i]);
      }
      printf("c'est ok\n");
      // l'affichage des pik
      printf("le vecteur des pik est : \n");
      for(int i=0;i<d;i++)
      printf("%f\t",pi[i]);
      printf("\n\n");
      //getch();
      //le calcul des muk
      for(int i=0;i<d;i++)
      {for(int k=0;k<n;k++)
      {mu.x[i][k]=0;
      for(int j=0;j<m;j++)
      {mu.x[i][k]=mu.x[i][k]+(tik.x[j][i]*M.x[j][k]);
      }
      // printf("mu[%d][%d] est %f\n",i,k,mu.x[i][k]);
      mu.x[i][k]=mu.x[i][k]*(1./(pi[i]*m));
      //printf("multiple %f\n",pi[i]*m);
      //printf("mu[%d][%d] est %f\n",i,k,mu.x[i][k]);
      //
      }}
      printf("la matrice des mu est : \n");
      affimat(mu,d,n);
      getch();
      //le cacul de sigmak
      for(int i=0;i<d;i++)
      {
      for(int j=0;j<m;j++)
      {for(int k=0;k<n;k++)
      {H.x[j][k]=M.x[j][k]-mu.x[i][k];
      }}
      printf("la matrice H aide est : \n");
      affimat(H,m,n);
      //getch();
      for(int l=0;l<n;l++)
      {for(int k=0;k<n;k++)
      {sigma.t[i].x[k][l]=0;
      for(int j=0;j<m;j++)
      {sigma.t[i].x[k][l]=sigma.t[i].x[k][l]+(tik.x[j][i]*H.x[j][k]*H.x[j][l]);
      //printf("sigma[%d][%d][%d]=%f*%f*%f avant la division est %f\n",i,k,l,tik.x[j][i],H.x[j][k],H.x[j][l],sigma.t[i].x[k][l]);
      //getch();
      }
      printf("sigma[%d][%d][%d] avant la division est %f\n",i,k,l,sigma.t[i].x[k][l]);
      sigma.t[i].x[k][l]=sigma.t[i].x[k][l]*(1./pi[i]*m);
      // printf("sigma[%d][%d][%d] est %f\n",i,k,l,sigma.t[i].x[k][l]);
      }
      }
      }
      printf("la matrice des sigma est :\n");
      affitmat(sigma,d);
      getch();
      /*mat K;
      K=inverse(sigma.t[2]);
      printf("la matrice inverse de la sigma 1 est :\n");
      afficherMatrice(K); */
      for(int k=0;k<m;k++)
      printf("%d\n",z[k]);
      getch();
      }
      while(lvs(sigma,mu,pi,d,zik)>0.01);
      return z;
      } // la fin de la fonction
      int main()
      {float *pi;
      mat mu;
      tmat sigma;
      //srand(time(0));
      pi=(float *)malloc(m*sizeof(float));

      mu.x=(float **) malloc(m*sizeof(float*));
      for(int i=0;i<m;i++)
      {mu.x[i]=(float *)malloc(n*sizeof(float));
      }
      sigma.t=(mat *)malloc(m*sizeof(mat*));
      for(int i=0;i<m;i++)
      {sigma.t[i].x=(float **)malloc(n*sizeof(float*));
      for(int j=0;j<n;j++)
      {sigma.t[i].x[j]=(float *)malloc(n*sizeof(float));
      } }
      lire("IRIS.txt");
      affimat(M,m,n);
      //M=normalisermat(M);
      EM(pi,mu,sigma,2);
      system("pause");
      return 0;
      }
      Merci
      0
  2. ngounou25 Messages postés 110 Statut Membre 4
     
    En fait, je te demandais de mettre juste la partie qui contient le bogue.

    Et aussi, essaye d'indenter, y a une balise prévue pour ça au-dessus de la zone d'édition.
    0
    1. Essafi
       
      Ok merci
      0