L’espace sémantique du DES et les méthodes de regroupement de sens : l’exemple de sec ===================================================================================== Introduction ------------ Ce dépôt est en relation avec la publication [L’espace sémantique du "Dictionnaire électronique des synonymes" (DES) et les méthodes de regroupement de sens : l’exemple de SEC](https://halshs.archives-ouvertes.fr/halshs-03155459) dans la revue [Syntaxe et Sématique](https://www.unicaen.fr/puc/html/spipe3fc.html?rubrique55=). A partir de l'extraction de la base de donnée sous forme d'un fichier texte, nous extrayions les relations concernant le mot SEC et tous ses synonymes, puis nous créons la matrice d'adjacence et enfin un graphe selon la librairie igraph. Ensuite nous utilisons les différentes méthodes de regroupement que propose cette librairie et en affichons les graphiques correspondants. Extraction ---------- Le fichier d'extraction de la base de données du DES (syno_paires_.txt est accessible via un contrat de prêt pour la recherche, contacter crisco.webestre @ unicaen.fr)se présente sous cette forme : mot1 mot2 [0|1] Les lignes sont triées sur mot1 puis mot2 dans l'ordre alpabétique. Pour sec, avec ce code : fichier = open (path+"syno_paires_mars2020.txt","r",encoding="iso-8859-1") listemots.append(mot) for ligne in fichier: #print('ligne',ligne) i1=ligne.index("\t") mot1=ligne[0:i1] ligne=ligne[i1+1:] i2=ligne.index("\t") #print('i2',i2) mot2=ligne[0:i2] #print('mot1-',mot1,'-mot2-',mot2,'-') if (mot == mot1): # si le 1er mot de la ligne est celui qu'on cherche listemots.append(mot2) fichier.close() return(listemots) nous allons avoir : >>> listemots ['sec', 'abrupt', 'acerbe', 'aigre', 'anhydre', 'aride', 'asséché', 'austère', 'autoritaire', 'blessant', 'bourru', 'bref', 'brusque', 'brutal', 'cassant', 'concis', 'cru', 'desséchant', 'desséché', 'dur', 'décharné', 'déplaisant', 'désagréable', 'désargenté', 'désertique', 'désobligeant', 'efflanqué', 'endurci', 'essuyé', 'fauché', 'ferme', 'froid', 'glacial', 'glacé', 'improductif', 'impécunieux', 'indifférent', 'ingrat', 'insensible', 'maigre', 'maigrelet', 'osseux', 'pauvre', 'pincé', 'pur', 'racorni', 'raide', 'rebutant', 'revêche', 'rigide', 'rogue', 'rude', 'rébarbatif', 'sans-coeur', 'seul', 'simple', 'squelettique', 'stérile', 'séché', 'sécot', 'sévère', 'tranchant', 'vide', 'âpre', 'égoïste', 'émacié', 'étique', 'étriqué'] >>> Pour chacun des synonymes de sec ci-dessus, nous extrayions du fichier les lignes où mot1 et mot2 sont synonymes de SEC. Création de la matrice d'adjacence ---------------------------------- Pour créer la matrice d'adjacence, nous utilisons ce code : fichier = open (path+"syno_paires_mars2020.txt","r",encoding="iso-8859-1") for ligne in fichier: i1=ligne.index("\t") mot1=ligne[0:i1] ligne=ligne[i1+1:] i2=ligne.index("\t") mot2=ligne[0:i2] i1=0 for m1 in lm: # on compare le mot lu à la vedette et à tous ses synonymes if (m1 == mot1): #print(i1,'-',m1,'-',mot2) MatAdj[i1][i1]=1 # chaque synonyme de la vedette est synonyme de lui-même (diagonale) #print(i1,'-',m1,'-',i1,'-',m1,'- à garder') i2=0 for m2 in lm: if (m2 == mot2): print(i1,'-',m1,'-',i2,'-',m2,'- à garder') MatAdj[i1][i2]=1 i2=i2+1 i1=i1+1 #MatAdj[5]=6 return(MatAdj) et obtenons la matrice suivante : >>> MatAdj array([[0, 1, 1, ..., 1, 1, 1], [1, 0, 1, ..., 0, 0, 0], [1, 1, 0, ..., 0, 0, 0], ..., [1, 0, 0, ..., 0, 1, 0], [1, 0, 0, ..., 1, 0, 0], [1, 0, 0, ..., 0, 0, 0]]) >>> MatAdj.shape (68, 68) >>> Sur [l'interface publique](https://crisco2.unicaen.fr/des/synonymes/sec), SEC a bien 67 synonymes + lui-même. La matrice d'adjacence a 68 lignes et colonnes Création du graphe avec igraph ------------------------------ np.fill_diagonal(MatAdj,0) # on remplit la diagonale de 0 -> éviter les arêtes sur les sommets G=igraph.Graph.Adjacency(MatAdj.tolist(),"MAX") G.vs["name"]=listemots # On ajoute à chaque sommet un intitulé #On ajoute au libellé du sommet le nombre de liens qu'il a labels=[] for i in listemots: ind=listemots.index(i) labels.append(str(i+" "+str(G.vs[ind].degree()))) # SizeMarkers mémorise le diamètre de chaque sommet en fonction du nombre de liens SizeMarkers=G.vs.degree() # SizeLine mémorise la taille de chaque lien entre 2 sommets e[0] ete[1] proportionnelle au nombre de chemins existants pour aller de l'un à l'autre SizeLine=[] for e in G.get_edgelist(): SizeLine.append(G.edge_connectivity(e[0],e[1])) # les paramètres d'affichage visual_style3 = {} visual_style3["vertex_label"] = labels visual_style3["margin"] = 40 #visual_style3["vertex_color"]="#33FFF3" #visual_style3["vertex_color"]='red' visual_style3["vertex_label_size"]=12 visual_style3["vertex_size"]= [i*2 for i in SizeMarkers] visual_style3["vertex_label_dist"]=1 #visual_style3["vertex_label_color"]="red" visual_style3["bbox"] = (1000, 1000) visual_style3["edge_color"]="gray" # couleurs prédéfinies : brown, gray ... cf http://www.proftnj.com/RGB3.htm visual_style3["edge_width"] = [i/8 for i in SizeLine] visual_style3["title"] = "Mot : "+ mot.upper() visual_style3["legend"] = "Mot : "+ mot.upper() Les différents algorithmes -------------------------- comms = G.community_multilevel() igraph.plot(comms, mot+"-multilevelNoMarkGroups.svg", **visual_style3) comms = G.community_infomap() igraph.plot(comms, mot+"-infomapNoMarkGroups.svg", mark_groups = False, **visual_style3) comms = G.community_fastgreedy() visual_style3["vertex_size"] = 2*igraph.degree(G3) igraph.plot(comms, mot+"-fastgreedy.svg", mark_groups = True, **visual_style3) comms = G.community_leading_eigenvector(clusters=6) igraph.plot(comms, mot+"-leading-eigenvector.svg", mark_groups = True, **visual_style3) comms = G.community_walktrap() igraph.plot(comms, mot+"-walktrap.svg", palette="red", **visual_style3) comms = G.community_optimal_modularity() # très long ... igraph.plot(comms, mot+"-optimal_modularity.svg", mark_groups = True, **visual_style3) comms=G.community_spinglass() igraph.plot(comms, mot+"-spinglassNoMarkGroups.svg", mark_groups = False, **visual_style3) comms=G.community_edge_betweenness() igraph.plot(comms, mot+"-edge_betweenness.svg", mark_groups = True, **visual_style3)