Clustering efficace avec les divergences de bregman
-
Upload
medalith-estrada -
Category
Technology
-
view
818 -
download
1
Transcript of Clustering efficace avec les divergences de bregman
RAPPORT DE STAGE
CLUSTERING EFFICACE AVEC LES DIVERGENCES DE BREGMAN
Master 1 Sciences pour l’Ingénieur Mention Ingénierie Mathématiques et Image
Université de La Rochelle
MIMBELA, MEDALITH
TUTEUR : SAINT-JEAN, CHRISTOPHE
Clustering efficace avec les Divergences de Bregman 2011
2 Université de La Rochelle – M1 IMI
CONTENIDO
Objectifs du Stage .............................................................................................................. 3
Introduction ....................................................................................................................... 3
Contexte scientifique ......................................................................................................... 4
Algorithme K-Means ....................................................................................................... 4
Divergences de Bregman ................................................................................................. 5
Divergences de Bregman – Hard...................................................................................... 6
Divergences de Bregman – Soft ....................................................................................... 7
Implementation générique ................................................................................................. 8
Contexte ......................................................................................................................... 8
Schéma de Classes .......................................................................................................... 8
Classe Member ............................................................................................................ 9
Classe matrix_member .............................................................................................. 10
Classe vector_member ............................................................................................... 11
Fonction TEMPLATE<CLASS T> ALGBregman ................................................................ 12
Exécution du Programme Bregman.cpp - Résultats ..................................................... 14
Conclusions ..................................................................................................................... 15
Références Bibliographiques ............................................................................................ 16
ANNEXE 1- CODE C++/MEX ............................................................................................. 17
ANNEXE 2 – CODE MATLAB DEMO VECTEUR ..................................................................... 24
ANNEXE 3 – CODE MATLAB DEMO MATRICES ................................................................... 25
Clustering efficace avec les Divergences de Bregman 2011
3 Université de La Rochelle – M1 IMI
OBJECTIFS DU STAGE
L’objectif de ce stage est Produire des implémentations efficaces de deux algorithmes
de clustering disponibles dans le papier ”Clustering with Bregman Divergences” [5]. Il
s’agit de généralisations des algorithmes K-Means
INTRODUCTION
Le clustering décrit des méthodes de classification de données en sous ensembles que
correspondent les pus suivant à des notions de proximité que l'on définit en introduisant
des mesures et fonctions de distance entre objets.
Pour obtenir un bon partitionnement, il convient [8]:
- Minimiser l'inertie intra-classe pour obtenir des grappes (cluster en anglais) les
plus homogènes possibles.
- Maximiser l'inertie inter-classe afin d'obtenir des sous-ensembles bien
différenciés.
On peut trouver différents types de clustering [7] :
- Algorithmes hiérarchiques : décomposition/composition hiérarchique de clusters
(CURE, BIRCH)
- Algorithmes par partitionnement : regroupement itérative avec amélioration par
replacement des objets (k-means)
- Fonctions de densité (cluster avec forme arbitraire) : clusters grandissent aussi
longtemps que la densité des objets dans leur voisinage est supérieure à une
borne (DBSCAN, OPTICS)
- Grilles : l’espace est divisé en cellules qui forment une grille (STING, CLIQUE)
- Modèles : chaque cluster est supposé suivre un modèle : trouver la meilleure
correspondance entre les modèles et les données (COBWEB)
L’algorithme de partitionnement K-Means c’est l’algorithme de base pour ce projet, avec
une généricité pour qu’il soit exécuté avec les divergences de Bregman.
La Divergence est utilisée pour minimiser les différences entre un model donné et l’espace
observé. Les mesures de Divergence sont utilisées pour résoudre des problèmes
d’ingénierie pour montrer les différences entre deux objets et minimiser les coûts de la
fonction en utilisant des contraints.
Clustering efficace avec les Divergences de Bregman 2011
4 Université de La Rochelle – M1 IMI
Les Divergences de Bregman (dФ) sont un type de mesure de distorsion suivant utilisé
dans le domaine de l’optimisation et le traitement de signal.
Dans ce document on va traiter dans la première partie la théorie de base pour
l’algorithme K-Means et les divergences de Bregman dans ses deux implémentations :
Hard et Soft, aussi on va montrer les différents types de dФ par rapport à la nature des
objets à traiter. Dans la deuxième partie on va aborder la partie de programmation
C++/MEX dans laquelle on montrera le schéma de classes et le choix des structures de
données pour le classement des individus. Finalement les conclusions du travail réalisé
pendant le stage, des applications de l’algorithme et aussi des améliorations suggérées.
CONTEXTE SCIENTIFIQUE
ALGORITHME K-MEANS
Le principe de l'algorithme K-Means est repartir N objets en K ensembles disjoints.
La partition des classes est modifiée avec chaque affectation d'un individu xi de X.
Les individus sont géométriquement représentés dans l'espace vectoriel P muni d'une
distance notée d.
Entrées: X= {xi} i=1 … N, , {νi} i=1 … N, K
Initialiser {µk} k=1 … K
Répéter jusqu’à convergence
o Calcul des clusters
o Calcul des nouveaux centres:
o Retourner µk
*La Complexité du K-Means : K*N*Itérations
2tki
'i μxminargh
k
khi i
tk
i/ 1
1
1
tk
khi iitk
i
x
/
Clustering efficace avec les Divergences de Bregman 2011
5 Université de La Rochelle – M1 IMI
Options d’Initialisation de µk :
- Aléatoirement dans l'intervalle de définition des xi
- Aléatoirement dans l'ensemble des xi.
Des initialisations différentes de peuvent mener à des Clusters différents (problèmes
de minima locaux)
Méthode générale pour obtenir des clusters "stables" :
- On répète l'algorithme It fois (nombre des itérations)
- On regroupe ensemble les xi qui se retrouvent toujours dans les mêmes
clusters.
Critères d’arrêt:
- Lorsqu'on fixe un critère d'arrêt tel que le nombre maximal d'itérations.
- Lorsque les itérations successives conduisent à un même cluster.
DIVERGENCES DE BREGMAN
Les divergences de Bregman (1967) sont une mesure de distorsion correspondant à des
fonctions strictement convexes [3]
Dans le cas général les divergences Bregman est définie par [5]:
Par exemple pour la distance euclidienne la fonction est strictement
convexe et différentiable en Rd [5]:
Exemples des divergences de Bregman pour dimensions finies:
- Vecteur (distance euclidienne dimension n) :
- Perte exponentiel :
)(,)()(),( yyxyxyxd
)(x
xxx ,)(
2
2
yxyxyx
yyxyyxx
yyxyyxxyxd
,
,,,
)(,,,),(
,)(: 0SriSd
22yxyxdxx ),()(
yyxx eyxeeyxdex )(),()(
Clustering efficace avec les Divergences de Bregman 2011
6 Université de La Rochelle – M1 IMI
- Perte Logistique :
- Matrices (distance de Mahalanobis) : pour A définie positive
- Distance de Kullback-Leiber
DIVERGENCES DE BREGMAN – HARD
L’algorithme a la même structure que celui vu dans le K-means, seulement il y a deux
différences la divergence de Bregman pour le type d’objet mathématique et le calcul de
cluster avec dФ.
Dans les divergences de Bregman on doit noter les opérations qu’on a besoin de faire
entre les objets et aussi avec des scalaires pour le calcul de distances et des nouveaux
centres.
Il faut faire attention que µk est un objet du même type que Xi.
Entrées: X= {xi} i=1 … N, {νi} i=1 … N, K, dФ
Initialiser {µk} k=1 … K
Répéter jusqu’à convergence
o Calcul des clusters
o Calcul des nouveaux centres:
o Retourner µk
)()()( yxAyxdAxxx TT
j
jd
j jj
d
j jy
xxdxxx 2121
loglog)(
y
xx
y
xxyxd
xxxxx
1
11
11
log)(log),(
)log()(log)(
khi i
tk
i/ 1
1
1
tk
khi iitk
i
x
/
),(minarghitki
k
xd
Clustering efficace avec les Divergences de Bregman 2011
7 Université de La Rochelle – M1 IMI
DIVERGENCES DE BREGMAN – SOFT
Dans la version SOFT de l’algorithme des divergences de Bregman on a remplacé les poids
des individus pour la probabilité d’appartenance du Xi individu dans le cluster k.
Entrées: X= {xi} i=1 … N, {νi} i=1 … N, K, dФ
Initialiser {µk} k=1 … K
Répéter jusqu’à convergence
o Calcul des clusters
o Calcul des nouveaux centres:
o Retourner µk, πk
n
i i
i
n
i itk
xkp
xxkp
1
11
)(
)(
)),(exp(
)),(exp()(
'' 'tki
K
k
tk
tki
tk
ixd
xdxkp
1
n
i itk xkp
n 1
1 1)(
Clustering efficace avec les Divergences de Bregman 2011
8 Université de La Rochelle – M1 IMI
IMPLEMENTATION GENERIQUE
CONTEXTE
Notations :
- Type
o 0: vecteur double
o 1: matrice double
- D: taille de matrice ou vecteur, pour chaque individu
- K: nombre de clusters
- Xi: individu
- N: quantité des individus
- X: ensemble des individus
- UH: centres des clusters (sortie)
- Xh: clusters
- Pih: Poids des individus
- H_IN: Matrice (2xN) de groupe pour chaque individu (premier ligne : indice du
groupe, deuxième ligne: distance)
L’implémentation a été faite avec Borland C++ et Matlab. Le choix de C++ c’était surtout
pour avoir la possibilité d’avoir de classes virtuelles et fonctions Template.
SCHEMA DE CLASSES
Member
<virtual Class>
Private :
- Type
- D
matrix_Member
<Implementation>
Private :
- Double **Xi
vector_Member
<Implementation>
Private :
- Double *Xi
Clustering efficace avec les Divergences de Bregman 2011
9 Université de La Rochelle – M1 IMI
CLASSE MEMBER
Constructeurs:
- Member() {type=0; D=0;}
- Member(unsigned int type,unsigned int D) {this->type=type; this->D=D;}
Fonctions de conversion:
- double *returnXi();
o Fonction pour faire la conversion du type T en double *, cette fonction est
nécessaire pour retourner les centre après le calcul.
- void setObject(Member &O1);
- void setDouble(double *Xi_IN,unsigned int type,unsigned int D);
o Fonction pour faire la conversion d’un vecteur double * en type T.
Fonction distance:
- double dPhi(Member &O1);
o Fonction principale avec l’implémentation de la divergence de Bregman par
rapport au type d’individu.
Fonctions pour des opérations entre objets
- void reset();
- Member& operator + (const Member &B);
- Member& operator = (const Member &B);
Fonctions pour des opérations mathématiques avec un scalaire : Utile surtout pour le
calcul de nouveaux centres.
- Member& operator / (const double &d);
- Member& operator * (const double &d);
Autres fonctions:
- unsigned int getType(){return this->type;}
- unsigned int getD(){return this->D;}
- double getXi(unsigned int i,unsigned int j);
Tous les fonctions sont de type virtuelle pure, ça veut dire qu’ils doivent être implémentés
obligatoirement dans chaque sous classe par rapport à la nature de l’objet avec lequel on
va faire le calcul de l’algorithme.
Pour le projet de Stage on a fait deux implémentation pour le calcule des divergences de
Bregman entre matrices et vecteurs.
La surcharge des operateurs en c++ nous permet faire des calculs plus transparents dans
la fonction AlgBregman après.
Clustering efficace avec les Divergences de Bregman 2011
10 Université de La Rochelle – M1 IMI
CLASSE MATRIX_MEMBER
Dans la classe on va déclarer le type qu’on a besoin dans ce cas là on va déclarer un
double **Xi, lequel sera initialisé par les constructeurs ou la fonction de conversion.
Fonctions de conversion pour le type matrice :
void setDouble(double *Xi_IN,unsigned int type,unsigned int D)
{ this->type=type; this->D=D;
Xi = (double **) malloc(D *sizeof(double*));
for(unsigned int n=0;n<D;n++){
Xi[n] = (double *) malloc(D *sizeof(double));
for(unsigned int m=0;m<D;m++)
Xi[n][m]=Xi_IN[n+D*m];
}
}
void setObject(matrix_Member &O1)
{ this->type=O1.type; this->D=O1.D;
this->Xi = new double* [D];
for(unsigned int n=0;n<D;n++){
this->Xi[n] = new double[D];
for(unsigned int m=0;m<D;m++)
this->Xi[n][m]=O1.Xi[m][n];
}
}
double *returnXi(){ // matrice sous la forme d'un vecteur
double *Xv;
Xv=(double *) malloc(D*D *sizeof(double));
for(unsigned int n=0;n<D;n++){
for(unsigned int m=0;m<D;m++)
Clustering efficace avec les Divergences de Bregman 2011
11 Université de La Rochelle – M1 IMI
Xv[m+D*n]=Xi[n][m];
}
return Xv;
}
CLASSE VECTOR_MEMBER
Dans la classe on va déclarer le type qu’on a besoin dans ce cas là on va déclarer un
double *Xi (vecteur), lequel sera initialisé par les constructeurs ou la fonction de
conversion.
class vector_Member: public Member{
private:
double *Xi;
public:
Fonction dPhi pour le calcul de distance euclidienne dans le cas général dimensión D :
double dPhi(vector_Member &O1){
double dist=0.0;
for(unsigned int n=0;n<this->D;n++){
dist=dist+pow(this->Xi[n]-O1.getXi(n,0),2);
}
return sqrt(dist);
}
Fonctions de conversion pour le type vecteur :
void setDouble(double *Xi_IN,unsigned int type,unsigned int D)
{ this->type=type; this->D=D;
Xi = (double *) malloc(D *sizeof(double));
memcpy(Xi,Xi_IN,this->D*sizeof(double));
}
void setObject(vector_Member &O1)
{ this->type=O1.type; this->D=O1.D;
Xi = (double *) malloc(D *sizeof(double));
memcpy(Xi,O1.Xi,this->D*sizeof(double));
}
~vector_Member(){
free(Xi);
}
double *returnXi(){
return this->Xi;
}
Clustering efficace avec les Divergences de Bregman 2011
12 Université de La Rochelle – M1 IMI
FONCTION TEMPLATE<CLASS T> ALGBREGMAN
Les entrées pour l’exécution de l’algorithme :
- double X_IN[]: matrice de taille Nxp avec l’ensemble des individus.
- unsigned int N: quantité des individus.
- unsigned int p: taille de colonnes de X.
- unsigned int type: code d’objet, 0= vector_Member, 1 =matrix_Member.
- unsigned int K, nombre de clusters.
- double *Pih: vecteur de taille N avec
- double H_IN[]: matrice 2 x N avec l’indice du cluster pour chaque individu et dans
la deuxième ligne distance par rapport au centre du cluster.
- double UH_IN[]: matrice K x p pour la sortie des centres.
- bool retUH: option pour retourner ou pas les centres des clusters
- unsigned int It: critère de convergence, nombre des itérations.
Dans la fonction Bregman d’abord on déclare toutes les variables qu’on aura besoin pour
le calcul.
Ensemble des indivus en type T T *X;
X= new T[N];
Après on fait la validation et conversion du type d’objet double * en type T.
Déclaration et initialisation des centres du cluster, déclaration de la structure vecteur-list
de taille K pour assigner l’indice des individus en chaque cluster.
T *uh;
vector< list<unsigned int> > Xh(K);
uh=initializeUh<T>(X,K,N);
Après on aura le boucle des répétitions jusqu’à la convergence que dans cette cas est le
nombre des Itérations.
Dans cette boucle on fait le remplissage du H_IN, et de la structure de donnés Xh.
A la fin on fait la conversion du type T en double *.
do{
mexPrintf("\n-->Iteracion #:%i\n",count);
for(n=0;n<N;n++){
mexPrintf("n=%i-> .... \n",n);
k=0;
mexPrintf("%d : %d = ",n,k);
ds=X[n].dPhi(uh[k]);
H_IN[2*n]=k;
Clustering efficace avec les Divergences de Bregman 2011
13 Université de La Rochelle – M1 IMI
H_IN[1+2*n]=ds;
for(k=1;k<K;k++){
mexPrintf("%d : %d = ",n,k);
ds=X[n].dPhi(uh[k]);
if(ds<H_IN[1+2*n]){
H_IN[2*n]=k;
H_IN[1+2*n]=ds;
}
}
Xh.at(H_IN[2*n]).push_back(n);
//Affectation de Xi dans le groupe K
}
list<unsigned int>::iterator j;
double cant;
for(k=0;k<K;k++){
cant=0;
(*sum).reset();
for(j = Xh[k].begin();j != Xh[k].end(); j++)
{
(*sum)=(*sum)+(X[*j]*Pih[*j]);
cant=cant+Pih[*j];
}
if(cant!=0)
uh[k]=(*sum)/(double) cant;
}
count++;
}while(count<It);
delete sum;
double *temp;
if(retUH==true){
for(k=0;k<K;k++){
temp=(uh[k].returnXi());
for(int i=0;i<p;i++)
{
UH_IN[k+K*i]=temp[i];
}
}
}
Clustering efficace avec les Divergences de Bregman 2011
14 Université de La Rochelle – M1 IMI
EXECUTION DU PROGRAMME BREGMAN.CPP - RESULTATS
On a fait des tests avec 450 points 2D (type=0), dans l’ANNEXE 2 on a le code pour
l’exécution:
Pour des matrices la Démo 2 dans l’ANNEXE 3 nous donne l’ensemble des centres et aussi
le vecteur H (indice de cluster par individu)
Clustering efficace avec les Divergences de Bregman 2011
15 Université de La Rochelle – M1 IMI
CONCLUSIONS
Les divergences de Bregman sont une généralisation de l’algorithme K-Means., avec
lequel on peut obtenir de résultats pour n’importe quel type d’objet mathématique qui est
dans les conditions de Bregman.
Grace à la généricité, pour ajouter un nouveau type dans le code on a des pas définis:
Faire une sous classe de Member :
- Implémenter les fonctions de conversion (double * ↔ T).
- Implémentation de la divergence de Bregman (dФ ).
- Appel dans la fonction Principale de l’algorithme avec le type d’objet.
Un travail sur le parallèlisation reste à faire (OpenMP) car la structure de l’algorithme a
besoin de beaucoup des itérations, donc les coûts des exécutions pour des grands
données par exemple de grands matrices
Clustering efficace avec les Divergences de Bregman 2011
16 Université de La Rochelle – M1 IMI
REFERENCES BIBLIOGRAPHIQUES
[1] Bodo Manthey, Heiko Roglin. The Netherlands .Worst-Case and Smoothed Analysis
of k-Means Clustering with Bregman Divergences, 2010
[2] Pascal Getreuer. Wrtiting MATLAB C/MEX code, 2010
[3] Aurélie Fischer. LSTA, Université Pierre et Marie Curie. Quantification et Clustering
avec des Divergences de Bregman. 2009
[4] Shun-ichi Amari, RIKEN Brain Science Institute, Hirosawa 2-1, Wako-shi, Saitama
351-0198, Japan. Divergence, Optimization and Geometry. 2009
[5] Arindam Banerjee, Srujana Merugu, Inderjit S. Dhillon, and Joydeep Ghosh.
Clustering with bregman divergences. Journal of Machine Learning Research,
6:1705–1749, 2005.
[6] Ted Jensen. Apuntadores y Arreglos en C, 2000
[7] Bernd Amann. Classification de données (ségmentation, clustering) BDWA-M2
UPMC
[8] Philippe Leray. Le clustering en 3 leçons. INSA Rouen -Département ASI -
Laboratoire PSI, 2007
Clustering efficace avec les Divergences de Bregman 2011
17 Université de La Rochelle – M1 IMI
ANNEXE 1- CODE C++/MEX
/*
Auteur: Medalith Mimbela Estrada
Université de la Rochelle
Master 1 Ingenierie Mathematique et Image
Stage: Implementation de Clustering avec Divergences de Bregman, MEX et
C++
*/
#include <math.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <list>
#include <vector>
using namespace std;
#include "mex.h"
#ifndef mwSize
#define mwSize int
#endif
//const int It=3;
/*Type
0: vecteur double
1: matrice double
D: taille de matrice ou vecteur, pour chaque individu
K: nombre de clusters
Xi: individu
N: quantité des individus
X: ensemble des individus
µh: centres des clusters
Xh: clusters
Pih: Poids des individus
H_IN: Matrice (2xN) de groupe pour chaque individu (premier ligne
group,deuxieme ligne distance)
*/
class Member{
protected:
unsigned int type;
unsigned int D;
public:
Member() {type=0; D=0;}
Member(unsigned int type,unsigned int D) {this->type=type; this-
>D=D;}
double *returnXi();
double dPhi(Member &O1);
void reset();
void setObject(Member &O1);
void setDouble(double *Xi_IN,unsigned int type,unsigned int D);
Member& operator + (const Member &B);
Member& operator = (const Member &B);
Member& operator / (const double &d);
Member& operator * (const double &d);
unsigned int getType(){return this->type;}
unsigned int getD(){return this->D;}
Clustering efficace avec les Divergences de Bregman 2011
18 Université de La Rochelle – M1 IMI
double getXi(unsigned int i,unsigned int j);
};
class matrix_Member: public Member{
private:
double **Xi;
public:
matrix_Member(){type=0;D=0;}
matrix_Member(unsigned int type,unsigned int D)
{ this->type=type; this->D=D;
Xi = (double **) malloc(D *sizeof(double*));
for( unsigned int n=0;n<D;n++){
Xi[n] = (double *) malloc(D *sizeof(double));
for( unsigned int m=0;m<D;m++)
Xi[n][m]=0;
}
}
void setDouble(double *Xi_IN,unsigned int type,unsigned int D)
{ this->type=type; this->D=D;
Xi = (double **) malloc(D *sizeof(double*));
for(unsigned int n=0;n<D;n++){
Xi[n] = (double *) malloc(D *sizeof(double));
for(unsigned int m=0;m<D;m++)
Xi[n][m]=Xi_IN[n+D*m];
}
}
void setObject(matrix_Member &O1)
{ this->type=O1.type; this->D=O1.D;
this->Xi = new double* [D];
for(unsigned int n=0;n<D;n++){
this->Xi[n] = new double[D];
for(unsigned int m=0;m<D;m++)
this->Xi[n][m]=O1.Xi[m][n];
}
}
~matrix_Member(){
for(unsigned int n=0;n<D;n++)
free(Xi[n]);
free(Xi);
}
double *returnXi(){ // matrice sous la forme d'un vecteur
double *Xv;
Xv=(double *) malloc(D*D *sizeof(double));
for(unsigned int n=0;n<D;n++){
for(unsigned int m=0;m<D;m++)
Xv[m+D*n]=Xi[n][m];
}
return Xv;
}
double dPhi(matrix_Member &O1){
double dist=0.0;
unsigned int i,j;
for(j=0; j<this->D; j++)
{ for (i=0; i<this->D; i++)
{
dist=dist+ (this->Xi[j][i]- O1.Xi[j][i])*(this->Xi[j][i]-
O1.Xi[j][i]);
}
Clustering efficace avec les Divergences de Bregman 2011
19 Université de La Rochelle – M1 IMI
}
mexPrintf(" %lf \n",dist);
return sqrt(dist);
}
void reset(){
for(unsigned int n=0;n<this->D;n++){
for(unsigned int m=0;m<this->D;m++)
this->Xi[n][m]=0;
}
}
matrix_Member& operator + (const matrix_Member &B){
for(unsigned int n=0;n<this->D;n++){
for(unsigned int m=0;m<this->D;m++)
this->Xi[n][m]=this->Xi[n][m]+B.Xi[n][m];
}
return *this;
}
matrix_Member& operator = (const matrix_Member &B){
this->type=B.type;
this->D=B.D;
for(unsigned int n=0;n<this->D;n++){
for(unsigned int m=0;m<this->D;m++)
this->Xi[n][m]=B.Xi[n][m];
}
return *this;
}
matrix_Member& operator / (const double &d){
for(unsigned int n=0;n<D;n++){
for(unsigned int m=0;m<D;m++)
this->Xi[n][m]= this->Xi[n][m]/d;
}
return *this;
}
matrix_Member& operator * (const double &d){
for(unsigned int n=0;n<D;n++){
for(unsigned int m=0;m<D;m++)
this->Xi[n][m]= this->Xi[n][m]*d;
}
return *this;
}
double getXi(unsigned int i,unsigned int j){
return Xi[i][j];
}
};
class vector_Member: public Member{
private:
double *Xi;
public:
vector_Member(){type=0;D=0;}
vector_Member(unsigned int type,unsigned int D)
{ this->type=type; this->D=D;
Xi = (double *) malloc(this->D *sizeof(double));
for(unsigned int n=0;n<D;n++)
Xi[n]=0;
}
void setDouble(double *Xi_IN,unsigned int type,unsigned int D)
{ this->type=type; this->D=D;
Clustering efficace avec les Divergences de Bregman 2011
20 Université de La Rochelle – M1 IMI
Xi = (double *) malloc(D *sizeof(double));
memcpy(Xi,Xi_IN,this->D*sizeof(double));
}
void setObject(vector_Member &O1)
{ this->type=O1.type; this->D=O1.D;
Xi = (double *) malloc(D *sizeof(double));
memcpy(Xi,O1.Xi,this->D*sizeof(double));
}
~vector_Member(){
free(Xi);
}
double *returnXi(){
return this->Xi;
}
double dPhi(vector_Member &O1){
double dist=0.0;
for(unsigned int n=0;n<this->D;n++){
dist=dist+pow(this->Xi[n]-O1.getXi(n,0),2);
}
return sqrt(dist);
}
void reset(){
for(unsigned int n=0;n<this->D;n++)
Xi[n]=0;
}
vector_Member& operator + (const vector_Member &B){
for(unsigned int n=0;n<this->D;n++)
this->Xi[n]=this->Xi[n]+B.Xi[n];
return *this;
}
vector_Member& operator = (const vector_Member &B){
this->type=B.type;
this->D=B.D;
for(unsigned int m=0;m<this->D;m++)
this->Xi[m]=B.Xi[m];
return *this;
}
vector_Member& operator / (const double &d){
for(unsigned int n=0;n<this->D;n++)
{ this->Xi[n]=this->Xi[n]/d;
}
return *this;
}
vector_Member& operator * (const double &d){
for(unsigned int n=0;n<this->D;n++)
{
this->Xi[n]=this->Xi[n]*d;
}
return *this;
}
double getXi(unsigned int i,unsigned int j){
return this->Xi[i];
}
};
template<class T>T* initializeUh(T *X_IN,unsigned int K,unsigned int N){
T *uh;
int r;
Clustering efficace avec les Divergences de Bregman 2011
21 Université de La Rochelle – M1 IMI
srand(time(NULL));
unsigned int D=X_IN[0].getD();
unsigned int TYPE=X_IN[0].getType();
uh = (T *) malloc(K *sizeof(T));
for(int k=0;k<K;k++){
r=rand()%N;
uh[k].setObject(X_IN[r]);
}
return uh;
}
template<class T> void algBregman(double X_IN[],unsigned int N,unsigned
int p,unsigned int type,unsigned int K,double *Pih,double H_IN[],double
UH_IN[],bool retUH,unsigned int It){
unsigned int count=0;
double ds=0.0;
unsigned int k=0,n=0,m=0;
unsigned int D;
T *X;
X= new T[N];
if(type==0){
double *temp;
temp =new double[p];
D=p;
for(n=0;n<N;n++){
for (m=0;m<p;m++)
temp[m]=X_IN[n + N*m];
X[n].setDouble(temp,type,p);
}
}
if(type==1){
double *temp;
temp =new double[p];
D=(unsigned int)sqrt(p);
for(n=0;n<N;n++){
for (m=0;m<p;m++)
temp[m]=X_IN[n + N*m];
X[n].setDouble(temp,type,D);
}
}
T *uh;
vector< list<unsigned int> > Xh(K);
uh=initializeUh<T>(X,K,N);
T *sum;
sum=new T(type,D);
do{
mexPrintf("\n-->Iteracion #:%i\n",count);
for(n=0;n<N;n++){
mexPrintf("n=%i-> .... \n",n);
k=0;
mexPrintf("%d : %d = ",n,k);
ds=X[n].dPhi(uh[k]);
H_IN[2*n]=k;
H_IN[1+2*n]=ds;
for(k=1;k<K;k++){
mexPrintf("%d : %d = ",n,k);
ds=X[n].dPhi(uh[k]);
if(ds<H_IN[1+2*n]){
Clustering efficace avec les Divergences de Bregman 2011
22 Université de La Rochelle – M1 IMI
H_IN[2*n]=k;
H_IN[1+2*n]=ds;
}
}
Xh.at(H_IN[2*n]).push_back(n);
mexPrintf("Affectation de %i dans %f (dist =
%f)\n",n,H_IN[2*n],H_IN[1+2*n]);
//Affectation de Xi dans le groupe K
}
list<unsigned int>::iterator j;
double cant;
for(k=0;k<K;k++){
cant=0;
(*sum).reset();
for(j = Xh[k].begin();j != Xh[k].end(); j++)
{
(*sum)=(*sum)+(X[*j]*Pih[*j]);
cant=cant+Pih[*j];
}
if(cant!=0)
uh[k]=(*sum)/(double) cant;
}
count++;
}while(count<It);
delete sum;
double *temp;
if(retUH==true){
for(k=0;k<K;k++){
temp=(uh[k].returnXi());
for(int i=0;i<p;i++)
{
UH_IN[k+K*i]=temp[i];
}
}
}
}
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray
*prhs[])
{
#define H_OUT plhs[0]
//#define DIST_OUT plhs[1]
#define UH_OUT plhs[1]
#define X_IN prhs[0]
#define PX_IN prhs[1]
#define K_IN prhs[2]
#define TYPE_IN prhs[3]
#define IT_IN prhs[4]
double *X, *PX;
double *H;
double *UH;
unsigned int K,TYPE,n,m,k;
bool retUH=true;
X =(double*)mxGetPr(X_IN);
PX =(double *)mxGetPr(PX_IN);
K=(unsigned int)mxGetScalar(K_IN);
TYPE=(unsigned int)mxGetScalar(TYPE_IN);
unsigned const int It= (unsigned int)mxGetScalar(IT_IN);
Clustering efficace avec les Divergences de Bregman 2011
23 Université de La Rochelle – M1 IMI
unsigned const int N=mxGetM(X_IN);
unsigned const int p=mxGetN(X_IN);
mexPrintf("Nombre elements=%i ",N);
mexPrintf("taille element=%i ",p);
mexPrintf("K=%i\n",K);
if(nrhs >5)
mexErrMsgTxt("Too many input arguments.");
else if(nlhs>2)
mexErrMsgTxt("Too many output arguments.");
else if(nlhs==1)
retUH=false;
else if(TYPE==1 && (sqrt(p)-(int)sqrt(p))!=0)
mexErrMsgTxt("Pour le type Matrice, la taille des individus doit
être un carrée parfait");
else if(K>N)
mexErrMsgTxt("La quantité de clusters doit être mineur au
quantité des individus");
H_OUT = mxCreateDoubleMatrix(2,N,mxREAL);
UH_OUT= mxCreateDoubleMatrix(K,p,mxREAL);
H=mxGetPr(H_OUT);
UH=mxGetPr(UH_OUT);
if(TYPE==0)
algBregman<vector_Member>(X,N,p,TYPE,K,PX,H,UH,retUH,It);
if(TYPE==1)
algBregman<matrix_Member>(X,N,p,TYPE,K,PX,H,UH,retUH,It);
return;
}
Clustering efficace avec les Divergences de Bregman 2011
24 Université de La Rochelle – M1 IMI
ANNEXE 2 – CODE MATLAB DEMO VECTEUR
load('dif.txt'); X=dif(:,2:end); PX(1:450)=1; K=5; TYPE=0; IT=4; [H,UH]=bregman(X,PX,K,TYPE,IT); H(1,:)=H(1,:)+1; [N,p]=size(X);
[x,k1]=find(H(1,:)==1); [x,k2]=find(H(1,:)==2); [x,k3]=find(H(1,:)==3); [x,k4]=find(H(1,:)==4); [x,k5]=find(H(1,:)==5); title('K-Means 2D'); hold on; plot(X(k1,1),X(k1,2),'*r'); hold on; plot(X(k2,1),X(k2,2),'*b'); hold on; plot(X(k3,1),X(k3,2),'*g'); hold on; plot(X(k4,1),X(k4,2),'*c'); hold on; plot(X(k5,1),X(k5,2),'*y'); hold on plot(UH(:,1),UH(:,2),'kx','MarkerSize',12,'LineWidth',2) plot(UH(:,1),UH(:,2),'ko','MarkerSize',12,'LineWidth',2); legend('Cluster 1','Cluster 2','Cluster 3','Cluster 4','Cluster
5','Centroids','Location','NW');
Clustering efficace avec les Divergences de Bregman 2011
25 Université de La Rochelle – M1 IMI
ANNEXE 3 – CODE MATLAB DEMO MATRICES
for i=1:21 if i<11 Xm(i,:)=rand(1,9); else Xm(i,:)=randn(1,9); end end PXm(1:21)=1; K=3; It=4; TYPE=1; %matrice [Hm,UHm]=bregman(Xm,PXm,K,TYPE,It);