<jupyter_start><jupyter_text>VISUALISATION DES RESULTATS DES MODELES LDA  **OBJECTIF GENERAL** **Tester différentes méthodes de visualisation des résultats LDA**  **OBJECTIFS SPECIFIQUES** *ECHELLE CORPUS*- Visualiser l'importance relative des thèmes produits avec PyLDAvis- Visualiser chaque thème à l'aide de nuages de mots*ECHELLE ARTICLE*- Visualiser la proportion de chaque thème par document- Clustering des documents à l'aide des thèmes les composant **Récupération des bibliothèques et modèles**<jupyter_code>import gensim
from gensim import models, corpora, utils
from gensim.models import LdaModel
import json
import numpy as np
import time
import pandas as pd
from tqdm import tqdm
from sklearn.manifold import TSNE

# Bibliothèques de visualisation

import pyLDAvis.gensim
pyLDAvis.enable_notebook()
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning) 
warnings.filterwarnings("ignore", category=UserWarning) 

from matplotlib import pyplot as plt
import matplotlib.colors as mcolors
from wordcloud import WordCloud, STOPWORDS

from bokeh.io import export_png
from bokeh.plotting import figure, output_file, show
from bokeh.models import Label
from bokeh.io import output_notebook
from bokeh.models import HoverTool, CustomJS, ColumnDataSource, Slider
from bokeh.layouts import column
from bokeh.palettes import all_palettes

output_notebook()<jupyter_output><empty_output><jupyter_text>Données pour AE<jupyter_code># liste de tokens pour chaque article
%store -r tokens_bigrams_Corpus_LDA_AE_clean 
%store -r tokens_bigrams_Corpus_LDA_AE_clean_lemma<jupyter_output><empty_output><jupyter_text>**Sac de mots**<jupyter_code>%store -r corpus_train_AE
%store -r corpus_test_AE
%store -r train_texts_AE
%store -r dictionary_AE_2
corpus_full_AE = corpus_train_AE + corpus_test_AE
# Modèles de 1 à 10 thèmes (incrément=10)
num_topic=20
model_ae_20 = LdaModel.load('Résultats_LDA/AE/lda_ae_'+ str(num_topic))
# Etude de fiabilité
model_ae_10_0 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ae_'+ str(10) +'_' + str(0))
model_ae_10_1 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ae_'+ str(10) +'_' + str(1))
model_ae_10_2 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ae_'+ str(10) +'_' + str(2))
model_ae_10_3 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ae_'+ str(10) +'_' + str(3))
model_ae_10_4 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ae_'+ str(10) +'_' + str(4))<jupyter_output><empty_output><jupyter_text>**Sac de mots avec lemmatisation**<jupyter_code>%store -r train_texts_AE
%store -r corpus_train_AE_lemma
%store -r dictionary_AE_2_lemma 
# Modèle sac de mots
model_ae_10_lemma = LdaModel.load('Résultats_LDA/AE/lda_ae_lemma_'+ str(10))<jupyter_output><empty_output><jupyter_text>**Tf-idf**<jupyter_code>%store -r corpus_train_AE_tfidf
# Modèles de 1 à 10 thèmes (incrément=1)
model_ae_1_tfidf = LdaModel.load('Résultats_LDA/AE/lda_ae_tfidf'+ str(1))

# Modèles de 10 à 100 thèmes (incrément=10)
model_ae_20_tfidf = LdaModel.load('Résultats_LDA/AE/lda_ae_tfidf'+ str(20))<jupyter_output><empty_output><jupyter_text>**Tf-idf avec lemmatisation**<jupyter_code># Modèle tf-idf avec lemmatisation
model_ae_10_tfidf_lemma = LdaModel.load('Résultats_LDA/AE/lda_ae_tfidf_lemma'+ str(10))<jupyter_output><empty_output><jupyter_text>Données pour EI<jupyter_code># liste de tokens pour chaque article
%store -r tokens_bigrams_Corpus_LDA_EI_clean 
#%store -r tokens_bigrams_Corpus_LDA_EI_clean_lemma<jupyter_output><empty_output><jupyter_text>**Sac de mots**<jupyter_code>%store -r corpus_train_EI
%store -r corpus_test_EI
%store -r train_texts_EI
%store -r dictionary_EI_2
corpus_full_EI = corpus_train_EI + corpus_test_EI
num_topic=10
model_ei_10 = LdaModel.load('Résultats_LDA/EI/lda_ei_'+ str(num_topic))
# Etude de fiabilité
model_ei_10_0 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ei_'+ str(10) +'_' + str(0))
model_ei_10_1 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ei_'+ str(10) +'_' + str(1))
model_ei_10_2 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ei_'+ str(10) +'_' + str(2))
model_ei_10_3 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ei_'+ str(10) +'_' + str(3))
model_ei_10_4 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ei_'+ str(10) +'_' + str(4))<jupyter_output><empty_output><jupyter_text>**Sac de mots avec lemmatisation**<jupyter_code>%store -r train_texts_EI
%store -r corpus_train_EI_lemma
%store -r dictionary_EI_2_lemma 
# Modèle sac de mots
model_ei_10_lemma = LdaModel.load('Résultats_LDA/EI/lda_ei_lemma_'+ str(10))<jupyter_output><empty_output><jupyter_text>**Tf-idf**<jupyter_code>%store -r corpus_train_EI_tfidf
model_ei_10_tfidf = LdaModel.load('Résultats_LDA/EI/lda_ei_tfidf'+ str(10))<jupyter_output><empty_output><jupyter_text>**Tf-idf avec lemmatisation**<jupyter_code># Modèle tf-idf avec lemmatisation
model_ei_10_tfidf_lemma = LdaModel.load('Résultats_LDA/EI/lda_ei_tfidf_lemma'+ str(10))<jupyter_output><empty_output><jupyter_text>Données pour RI<jupyter_code># liste de tokens pour chaque article
%store -r tokens_bigrams_Corpus_LDA_RI_clean 
#%store -r tokens_bigrams_Corpus_LDA_RI_clean_lemma<jupyter_output><empty_output><jupyter_text>**Sac de mots**<jupyter_code>%store -r corpus_train_RI
%store -r corpus_test_RI
%store -r train_texts_RI
%store -r dictionary_RI_2
corpus_full_RI = corpus_train_RI + corpus_test_RI
#num_topic=[70,80]
model_ri_70 = LdaModel.load('Résultats_LDA/RI/lda_ri_'+ str(70))
model_ri_80 = LdaModel.load('Résultats_LDA/RI/lda_ri_'+ str(80))
# Etude de fiabilité
model_ri_10_0 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ri_'+ str(10) +'_' + str(0))
model_ri_10_1 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ri_'+ str(10) +'_' + str(1))
model_ri_10_2 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ri_'+ str(10) +'_' + str(2))
model_ri_10_3 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ri_'+ str(10) +'_' + str(3))
model_ri_10_4 = LdaModel.load('Résultats_LDA/Fiabilité/lda_ri_'+ str(10) +'_' + str(4))<jupyter_output><empty_output><jupyter_text>**Sac de mots avec lemmatisation**<jupyter_code>%store -r train_texts_RI
%store -r corpus_train_RI_lemma
%store -r dictionary_RI_2_lemma 
# Modèle sac de mots
model_ri_10_lemma = LdaModel.load('Résultats_LDA/lda_ri_lemma_'+ str(10))<jupyter_output><empty_output><jupyter_text>**Tf-idf**<jupyter_code>%store -r corpus_train_RI_tfidf
model_ri_10_tfidf = LdaModel.load('Résultats_LDA/RI/lda_ri_tfidf'+ str(10))<jupyter_output><empty_output><jupyter_text>**Tf-idf avec lemmatisation**<jupyter_code># Modèle tf-idf avec lemmatisation
model_ri_10_tfidf_lemma = LdaModel.load('Résultats_LDA/lda_ri_tfidf_lemma'+ str(10))<jupyter_output><empty_output><jupyter_text>1) **ANALYSE CORPUS : THEMES ET JETONS** **PYLDAVIS**<jupyter_code>pyLDAvis.show(pyLDAvis.gensim.prepare(model_ae_20_tfidf, corpus_train_AE_tfidf, dictionary_AE_2))
pyLDAvis.show(pyLDAvis.gensim.prepare(model_ri_80, corpus_train_RI, dictionary_RI_2))<jupyter_output><empty_output><jupyter_text>**SHOW TOPIC LDA** Analyse des poids des mots attribués par le modèle<jupyter_code>topic = 10
path = 'Résultats_LDA/AE/lda_ae_'
#path = 'Résultats_LDA/AE/lda_ae_lemma_'
#path = 'Résultats_LDA/AE/lda_ae_tfidf'
#path = 'Résultats_LDA/AE/lda_ae_tfidf_lemma'
model = LdaModel.load(path+ str(topic))
model.show_topic(0)<jupyter_output><empty_output><jupyter_text>Etude du poids moyen des 10 premiers mots-clés de chaque thème **BUT****Vérifier si poids reste constant : permet une certaine convergence des mots vs. attribution qui reste aléatoire** **METHODE**--> Récupérer un poids moyen pour chaque thème et tracer un courbe avec abscisse x = nombre de thèmes et ordonnée y = valeur moyenne des poids--> Tracer une courbe pour chaque configuration (sac de mot - tf-idf - lemma - pas lemma)<jupyter_code>def get_top_weights (model):
    """Récupère la moyenne des poids des 10 mots clés prépondérants de chaque thème sous forme de liste"""
    top_weights = []
    for topic in range(model.num_topics):
        top_weights.append(np.mean([element[1] for element in model.show_topic(topicid=topic)]))
    return top_weights<jupyter_output><empty_output><jupyter_text>**Etude de la variabilité du poids pour chaque modèle : boîte à moustaches**<jupyter_code>def get_top_weights_models (path):
    """Récupère la moyenne des poids des 10 mots clés prépondérants de chaque thème pour tous les modèles d'une revue sous forme de liste"""
    top_weigths_models = {}
    for topic in tqdm(num_topics):
        model = LdaModel.load(path+ str(topic))
        top_weigths_models[str(topic)] = get_top_weights(model)
    return top_weigths_models
def plot_variabilité_weights (top_weights_models_bow, revue ='AE', forme='bow'):
    fig = plt.figure(figsize=(17,8))
    BoxName = [key for key in top_weights_models_AE_bow.keys()]
    data = list(top_weights_models_bow.values())
    plt.boxplot(data, patch_artist=False)
    if forme =='bow' or forme == 'bow_lemma':
        plt.ylim(0,0.05)
    elif forme == 'tfidf' or forme =='tfidf_lemma':
        plt.ylim(0,0.01)
    plt.xticks([x for x in range(1,21,1)], BoxName)
    plt.xticks(fontsize=14)
    plt.yticks(fontsize=14)
    plt.title(forme, fontsize=15)
    plt.ylabel('Poids moyen attribué aux mots prépondérants de chaque thème',fontsize=14)
    plt.savefig("Plots/LDA/poids_mots_clés/variabilité_"+ revue + "_"+ forme +".png")
    plt.show()<jupyter_output><empty_output><jupyter_text>**AE**<jupyter_code>num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)]
top_weights_models_AE_bow = get_top_weights_models (path ='Résultats_LDA/AE/lda_ae_')
top_weights_models_AE_bow_lemma = get_top_weights_models (path ='Résultats_LDA/AE/lda_ae_lemma_')
top_weights_models_AE_tfidf = get_top_weights_models (path ='Résultats_LDA/AE/lda_ae_tfidf')
# Cas spécial pour tfidf + lemma
num_topics = [x for x in range(1,10)]
top_weights_models_AE_tfidf_lemma = get_top_weights_models (path = 'Résultats_LDA/AE/lda_ae_tfidf_lemma_')
num_topics = [x for x in range(10,110,10)]
top_weights_models_AE_tfidf_lemma_v2 = get_top_weights_models (path = 'Résultats_LDA/AE/lda_ae_tfidf_lemma')
top_weights_models_AE_tfidf_lemma.update(top_weights_models_AE_tfidf_lemma_v2)
plot_variabilité_weights (top_weights_models_AE_bow, revue ='AE', forme='bow')
plot_variabilité_weights (top_weights_models_AE_bow_lemma, revue ='AE', forme='bow_lemma')
plot_variabilité_weights (top_weights_models_AE_tfidf, revue ='AE', forme='tfidf')
plot_variabilité_weights (top_weights_models_AE_tfidf_lemma, revue ='AE', forme='tfidf_lemma')<jupyter_output><empty_output><jupyter_text>**EI**<jupyter_code>num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)]
top_weights_models_EI_bow = get_top_weights_models (path ='Résultats_LDA/EI/lda_ei_')
top_weights_models_EI_bow_lemma = get_top_weights_models (path ='Résultats_LDA/EI/lda_ei_lemma_')
top_weights_models_EI_tfidf = get_top_weights_models (path ='Résultats_LDA/EI/lda_ei_tfidf')
# Cas spécial pour tfidf + lemma
num_topics = [x for x in range(1,10)]
top_weights_models_EI_tfidf_lemma = get_top_weights_models (path = 'Résultats_LDA/EI/lda_ei_tfidf_lemma_')
num_topics = [x for x in range(10,110,10)]
top_weights_models_EI_tfidf_lemma_v2 = get_top_weights_models (path = 'Résultats_LDA/EI/lda_ei_tfidf_lemma')
top_weights_models_EI_tfidf_lemma.update(top_weights_models_EI_tfidf_lemma_v2)
plot_variabilité_weights (top_weights_models_EI_bow, revue ='EI', forme='bow')
plot_variabilité_weights (top_weights_models_EI_bow_lemma, revue ='EI', forme='bow_lemma')
plot_variabilité_weights (top_weights_models_EI_tfidf, revue ='EI', forme='tfidf')
plot_variabilité_weights (top_weights_models_EI_tfidf_lemma, revue ='EI', forme='tfidf_lemma')<jupyter_output><empty_output><jupyter_text>**RI**<jupyter_code>num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)]
top_weights_models_RI_bow = get_top_weights_models (path ='Résultats_LDA/RI/lda_ri_')
top_weights_models_RI_bow_lemma = get_top_weights_models (path ='Résultats_LDA/RI/lda_ri_lemma_')
top_weights_models_RI_tfidf = get_top_weights_models (path ='Résultats_LDA/RI/lda_ri_tfidf')
top_weights_models_RI_tfidf_lemma = get_top_weights_models (path = 'Résultats_LDA/RI/lda_ri_tfidf_lemma')
plot_variabilité_weights (top_weights_models_RI_bow, revue ='RI', forme='bow')
plot_variabilité_weights (top_weights_models_RI_bow_lemma, revue ='RI', forme='bow_lemma')
plot_variabilité_weights (top_weights_models_RI_tfidf, revue ='RI', forme='tfidf')
plot_variabilité_weights (top_weights_models_RI_tfidf_lemma, revue ='RI', forme='tfidf_lemma')<jupyter_output><empty_output><jupyter_text>**Evolution de la moyenne des poids moyens attribués par chaque modèle de thème**<jupyter_code>def get_model_top_weights (path):
    """Récupère la moyenne sur tous les thèmes de la moyenne des poids des 10 mots clés prépondérants pour chaque thème sous forme de dictionnaire"""
    top_weigths_models = {}
    for topic in tqdm(num_topics):
        model = LdaModel.load(path+ str(topic))
        top_weigths_models[str(topic)] = np.mean(get_top_weights(model))
    return top_weigths_models
def plot_weigths (num_topics, bow, bow_lemma, tfidf, tfidf_lemma, revue ='AE'):    
    fig = plt.figure(figsize=(15,8))
    plt.plot(num_topics, list(bow.values()), 'kx', label = 'sac-de-mot', markersize=10)
    plt.plot(num_topics, list(bow_lemma.values()), 'yx', label = 'sac-de-mot_lemma', markersize=10)
    plt.plot(num_topics, list(tfidf.values()), 'ko', label = 'tfidf', markersize=10)
    plt.plot(num_topics, list(tfidf_lemma.values()), 'yo', label = 'tfidf_lemma', markersize=10)
    plt.legend(prop={'size': 18})
    plt.xticks(fontsize=14)
    plt.yticks(fontsize=14)
    plt.xlabel('Nombre de thèmes',fontsize=20)
    plt.ylabel('Poids moyen attribué à l\'ensemble des thèmes d\'un modèle',fontsize=14)
    plt.title(revue,fontsize=40)
    #plt.savefig("Plots/LDA/poids_mots_clés/" + revue + ".png")
    plt.show()<jupyter_output><empty_output><jupyter_text>**AE**<jupyter_code>num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)]
top_weights_AE_bow = get_model_top_weights (path ='Résultats_LDA/AE/lda_ae_')
num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)]
top_weights_AE_bow = get_model_top_weights (path ='Résultats_LDA/AE/lda_ae_')
top_weights_AE_bow_lemma = get_model_top_weights (path ='Résultats_LDA/AE/lda_ae_lemma_')
top_weights_AE_tfidf = get_model_top_weights (path ='Résultats_LDA/AE/lda_ae_tfidf')
# Cas spécial pour tfidf + lemma
num_topics = [x for x in range(1,10)]
top_weights_AE_tfidf_lemma = get_model_top_weights (path = 'Résultats_LDA/AE/lda_ae_tfidf_lemma_')
num_topics = [x for x in range(10,110,10)]
top_weights_AE_tfidf_lemma_v2 = get_model_top_weights (path = 'Résultats_LDA/AE/lda_ae_tfidf_lemma')
top_weights_AE_tfidf_lemma.update(top_weights_AE_tfidf_lemma_v2)
plot_weigths(num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)], 
             bow = top_weights_AE_bow, bow_lemma = top_weights_AE_bow_lemma,
             tfidf = top_weights_AE_tfidf,tfidf_lemma = top_weights_AE_tfidf_lemma, revue ='AE')<jupyter_output><empty_output><jupyter_text>**EI**<jupyter_code>num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)]
top_weights_EI_bow = get_model_top_weights (path ='Résultats_LDA/EI/lda_ei_')
top_weights_EI_bow_lemma = get_model_top_weights (path ='Résultats_LDA/EI/lda_ei_lemma_')
top_weights_EI_tfidf = get_model_top_weights (path ='Résultats_LDA/EI/lda_ei_tfidf')
# Cas spécial pour tfidf + lemma
num_topics = [x for x in range(1,10)]
top_weights_EI_tfidf_lemma = get_model_top_weights (path = 'Résultats_LDA/EI/lda_ei_tfidf_lemma_')
num_topics = [x for x in range(10,110,10)]
top_weights_EI_tfidf_lemma_v2 = get_model_top_weights (path = 'Résultats_LDA/EI/lda_ei_tfidf_lemma')
top_weights_EI_tfidf_lemma.update(top_weights_EI_tfidf_lemma_v2)
plot_weigths(num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)], 
             bow = top_weights_EI_bow, bow_lemma = top_weights_EI_bow_lemma,
             tfidf = top_weights_EI_tfidf,tfidf_lemma = top_weights_EI_tfidf_lemma, revue ='EI')<jupyter_output><empty_output><jupyter_text>**RI**<jupyter_code>num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)]
top_weights_RI_bow = get_model_top_weights (path ='Résultats_LDA/RI/lda_ri_')
top_weights_RI_bow_lemma = get_model_top_weights (path ='Résultats_LDA/RI/lda_ri_lemma_')
top_weights_RI_tfidf = get_model_top_weights (path ='Résultats_LDA/RI/lda_ri_tfidf')
top_weights_RI_tfidf_lemma = get_model_top_weights (path = 'Résultats_LDA/RI/lda_ri_tfidf_lemma')
plot_weigths(num_topics = [x for x in range(1,10)] + [x for x in range(10,110,10)], 
             bow = top_weights_RI_bow, bow_lemma = top_weights_RI_bow_lemma,
             tfidf = top_weights_RI_tfidf,tfidf_lemma = top_weights_RI_tfidf_lemma, revue ='RI')<jupyter_output><empty_output><jupyter_text>Stockage des résultats des thèmes dans un fichier excel 1) Ecriture des mots-clés dans un dataframe panda<jupyter_code>def format_topics(ldamodel):
    # Init output
    topics_df = pd.DataFrame()
    for topic in range(ldamodel.num_topics):
        topics = ldamodel.show_topic(topic)
        topic_keywords = '\n'.join([element[0] for element in topics])
        topics_df = topics_df.append(pd.Series(topic_keywords), ignore_index=True)
    
    topics_df.columns = ['Mots-clés']
    return(topics_df)
topic_df_40 = format_topics(ldamodel=model_ae_40)
# Show (nombre de documents fixé)
topic_df_40.head(10)<jupyter_output><empty_output><jupyter_text>2) Ecriture du dataframe dans feuille excel<jupyter_code>#pip install XlsxWriter
path = 'Résultats_LDA/'<jupyter_output><empty_output><jupyter_text>**AE**<jupyter_code>topic = 100
#model = 'Résultats_LDA/AE/lda_ae_'
#model = 'Résultats_LDA/AE/lda_ae_lemma_'
model = 'Résultats_LDA/AE/lda_ae_tfidf'
#model = 'Résultats_LDA/AE/lda_ae_tfidf_lemma'
test = pd.ExcelWriter(path + 'test_python_excel.xlsx', engine='xlsxwriter')
model = LdaModel.load(model+ str(topic))
topic_df = format_topics(ldamodel=model)
topic_df.to_excel(test, 'Feuille')
test.save()<jupyter_output><empty_output><jupyter_text>**EI**<jupyter_code>topic = 100
#model = 'Résultats_LDA/EI/lda_ei_'
#model = 'Résultats_LDA/EI/lda_ei_lemma_'
#model = 'Résultats_LDA/EI/lda_ei_tfidf'
model = 'Résultats_LDA/EI/lda_ei_tfidf_lemma'
test = pd.ExcelWriter(path + 'test_python_excel.xlsx', engine='xlsxwriter')
model = LdaModel.load(model+ str(topic))
topic_df = format_topics(ldamodel=model)
topic_df.to_excel(test, 'Feuille')
test.save()<jupyter_output><empty_output><jupyter_text>**RI**<jupyter_code>topic = 100
#model = 'Résultats_LDA/RI/lda_ri_'
#model = 'Résultats_LDA/RI/lda_ri_lemma_'
#model = 'Résultats_LDA/RI/lda_ri_tfidf'
model = 'Résultats_LDA/RI/lda_ri_tfidf_lemma'
test = pd.ExcelWriter(path + 'test_python_excel.xlsx', engine='xlsxwriter')
model = LdaModel.load(model+ str(topic))
topic_df = format_topics(ldamodel=model)
topic_df.to_excel(test, 'Feuille')
test.save()<jupyter_output><empty_output><jupyter_text>Remarque : pour des questions de mise en forme, je copie ensuite le contenu du fichier excel test dans le ficheir excel des résultats propres "Etude comparée LDA"  **Nuages de mots**<jupyter_code>def plot_cloud(lda_model, save=True, plot=True, revue='RI',size=(3,3,10)):
    
    cols = [color for name, color in mcolors.XKCD_COLORS.items()]
    num_topics = lda_model.num_topics
    cloud = WordCloud(stopwords=STOPWORDS, background_color='white', width=2500, height=1800, max_words=10, 
                      colormap='tab10', color_func=lambda *args, **kwargs: cols[i], prefer_horizontal=1.0)

    topics = lda_model.show_topics(formatted=False, num_topics=num_topics)

    fig, axes = plt.subplots(size[0], size[1], figsize=(size[2],size[2]), sharex=True, sharey=True)
    
    for i, ax in enumerate(axes.flatten()):
        fig.add_subplot(ax)
        topic_words = dict(topics[i][1])
        cloud.generate_from_frequencies(topic_words, max_font_size=300)
        plt.gca().imshow(cloud, interpolation="bilinear")
        plt.gca().set_title('Topic ' + str(i), fontdict=dict(size=16))
        plt.gca().axis('off')
    
    plt.subplots_adjust(wspace=0, hspace=0)
    plt.axis('off')
    plt.margins(x=0, y=0)
    plt.tight_layout()
    
    if save:
        plt.savefig("Plots/LDA/nuages_mots/nuages_mots_"+revue+'_num_topics='+str(num_topics))
    if plot:
        plt.show()
    else:
        plt.close()<jupyter_output><empty_output><jupyter_text>**AE**<jupyter_code>plot_cloud(lda_model=model_ae_10, revue ='AE', save=True, plot=False, size=(2,5,15))
plot_cloud(lda_model=model_ae_20, revue ='AE', save=True, plot=False, size=(5,4,15))
plot_cloud(lda_model=model_ae_30, save=True, revue='AE', plot=False, size=(6,5,25))<jupyter_output><empty_output><jupyter_text>**EI**<jupyter_code>plot_cloud(lda_model=model_ei_10, revue ='EI', save=True, plot=False, size=(2,5,15))
plot_cloud(lda_model=model_ei_20, revue ='EI', save=True, plot=False, size=(5,4,15))
plot_cloud(lda_model=model_ei_30, save=True, revue='EI', plot=False, size=(6,5,25))<jupyter_output><empty_output><jupyter_text>**RI**<jupyter_code>plot_cloud(lda_model=model_ri_10, revue ='RI', save=True, plot=False, size=(2,5,15))
plot_cloud(lda_model=model_ri_20, revue ='RI', save=True, plot=False, size=(5,4,15))
plot_cloud(lda_model=model_ri_30, save=True, revue='RI', plot=False, size=(6,5,25))<jupyter_output><empty_output><jupyter_text>2)**ANALYSE PAR ARTICLE**  Répartition thème par document<jupyter_code>def create_index(model, corpus):
    """Création d'un dictionnaire (index_topic:[prop pour chaque document du corpus])"""
    topics = {0:[],1:[],2:[], 3:[],4:[],5:[],6:[],7:[],8:[],9:[]}
    for document in model.get_document_topics(bow=corpus):
        for i in range(10):
            topics[i].append(0)
        for n_topic, prop in document:  
            topics[n_topic][-1] = prop
    return topics

def plot_topic_by_doc(topics,ind, revue='RI'):
    plt.figure(figsize=(15,10))
    plt.bar(ind, topics[0][:len(ind)], width=0.6, label='thème 1')
    plt.bar(ind, topics[1][:len(ind)], width=0.6, label='thème 2')
    plt.bar(ind, topics[2][:len(ind)], width=0.6, label='thème 3')
    plt.bar(ind, topics[3][:len(ind)], width=0.6, label='thème 4')
    plt.bar(ind, topics[4][:len(ind)], width=0.6, label='thème 5')
    plt.bar(ind, topics[5][:len(ind)], width=0.6, label='thème 6')
    plt.bar(ind, topics[6][:len(ind)], width=0.6, label='thème 7')
    plt.bar(ind, topics[7][:len(ind)], width=0.6, label='thème 8')
    plt.bar(ind, topics[8][:len(ind)], width=0.6, label='thème 9')
    plt.bar(ind, topics[9][:len(ind)], width=0.6, label='thème 10')
    plt.ylabel("Proportion des thèmes", fontsize=20)
    plt.xlabel("",fontsize=20)
    #plt.title('Distribution des thèmes par document pour la revue '+ revue)
    plt.title(revue, fontsize=40)
    plt.legend(loc='upper right')
    plt.savefig('Plots/LDA/histogrammes_topic_document/'+revue+'.png')
    plt.show()
    plt.close()
topics_AE = create_index(model_ae_10,corpus_train_AE)
for document in model.get_document_topics(bow=corpus):
    for i in range(10):
        topics[i].append(0)
    for n_topic, prop in document:  
        topics[n_topic][-1] = prop
topics_EI = create_index(model_ei_10,corpus_train_EI)
topics_RI = create_index(model_ri_10,corpus_train_RI)<jupyter_output><empty_output><jupyter_text>Idée : comment choisir les documents à plotter ?<jupyter_code>ind = [x for x in range(50)] # choix du nombre de documents à plotter
i = 0
for document in corpus_ae_filtre[:50]:
    print(i, ': ', document[1])
    i+=1
plot_topic_by_doc(topics=topics_AE,revue='AE',ind=ind)
plot_topic_by_doc(topics=topics_EI,revue='EI',ind=ind)
plot_topic_by_doc(topics=topics_RI,revue='RI',ind=ind)<jupyter_output><empty_output><jupyter_text>Visualisation du document le plus représentatif pour chaque thème<jupyter_code># Récupérer les articles en français, de type article et avec année de publication
def filtre_corpus_metadata(Corpus, tokens,dictionary):
    """Prend en paramètre le Corpus avec textes et métadonnées et retourne un corpus du type 
       Output : liste du type [(URL,titre,tokens,BoW)]"""
    Corpus_filtre = []
    index_clean = 0
    for index_document in tqdm(range(len(Corpus))) :
    # on ne traite que les articles de type article et en français
        if (Corpus[index_document]['metadata']['typeart'], Corpus[index_document]['metadata']['lang']) == ('article','fr') : 
            try :
                Corpus_filtre.append((Corpus[index_document]['URL'], Corpus[index_document]['metadata']['title'],tokens[index_clean],dictionary.doc2bow(tokens[index_clean]))) 
            except:
                Corpus_filtre = [(Corpus[index_document]['URL'], Corpus[index_document]['metadata']['title'],tokens[index_clean],dictionary.doc2bow(tokens[index_clean]))]
            index_clean +=1
    return Corpus_filtre
Corpus_AE = json.loads(open("Data/corpus_ae.json", "r").read())
corpus_ae_filtre = filtre_corpus_metadata(Corpus_AE, tokens_bigrams_Corpus_LDA_AE_clean,dictionary_AE_2)
Corpus_EI = json.loads(open("Data/corpus_ei.json", "r").read())
corpus_ei_filtre = filtre_corpus_metadata(Corpus_EI, tokens_bigrams_Corpus_LDA_EI_clean,dictionary_EI_2)
Corpus_RI = json.loads(open("Data/corpus_ri.json", "r").read())
corpus_ri_filtre = filtre_corpus_metadata(Corpus_RI, tokens_bigrams_Corpus_LDA_RI_clean,dictionary_RI_2)
def format_topics_sentences(ldamodel, corpus_filtre):
    """Retourne un tableau panda avec chaque ligne qui correspond à un document avec pour colonnes les infos suivantes :
        - Thème majoritaire
        - Poids du thème au sein du document
        - Mots-clés du thème
        - Tokens du document
        - Titre du document
        - URL du document"""
    
    sent_topics_df = pd.DataFrame()
    
    corpus = [element[3] for element in corpus_filtre]
    tokens = [element[2] for element in corpus_filtre]
    titres = [element[1] for element in corpus_filtre]
    URLs = [element[0] for element in corpus_filtre]
    
    # Get main topic in each document
    for i, row in enumerate(ldamodel[corpus]):
        row = sorted(row, key=lambda x: (x[1]), reverse=True)
        # Get the Dominant topic, Perc Contribution and Keywords for each document
        for j, (topic_num, prop_topic) in enumerate(row):
            if j == 0:  # => dominant topic
                wp = ldamodel.show_topic(topic_num)
                topic_keywords = ", ".join([word for word, prop in wp])
                sent_topics_df = sent_topics_df.append(pd.Series([int(topic_num), round(prop_topic,4), topic_keywords]), ignore_index=True)
            else:
                break
    
    texts, titres, URLs = pd.Series(tokens), pd.Series(titres), pd.Series(URLs)
    sent_topics_df = pd.concat([sent_topics_df, texts, titres,URLs], axis=1)
    
    return(sent_topics_df)

def get_representative_documents(model, corpus=corpus_ae_filtre, print_= True):
    """ Retourne un tableau panda avec chaque ligne qui correspond à un thème avec comme colonnes les mêmes infos que format_topics_sentences
        """
    df_topic_sents_keywords = format_topics_sentences(ldamodel=model, corpus_filtre=corpus)
    
    sent_topics_sorteddf_mallet = pd.DataFrame()
    sent_topics_outdf_grpd = df_topic_sents_keywords.groupby('Thème principal')

    # Tri par thème dominant
    for i, grp in sent_topics_outdf_grpd:
        sent_topics_sorteddf_mallet = pd.concat([sent_topics_sorteddf_mallet, 
                                                 grp.sort_values(['% de contribution du thème'], ascending=[0]).head(1)], 
                                                axis=0)
    # Reset Index    
    sent_topics_sorteddf_mallet.reset_index(drop=True, inplace=True)
    
    # Format
    sent_topics_sorteddf_mallet.columns = ['Topic_Num', '% de contribution du thème', "Mots-clés",'Text','Titre','URL']
    
    # Show
    if print_== True:
        sent_topics_sorteddf_mallet.head(model.num_topics)
        
    return sent_topics_sorteddf_mallet
#document_ae = format_topics_sentences_2(ldamodel=model_ae_10, corpus_filtre=corpus_ae_filtre)
documents_majoritaires = get_representative_documents(model=model_ae_10, corpus=corpus_ae_filtre)
documents = get_representative_documents(model_ri_10,corpus_full_RI)
documents.head(10)<jupyter_output><empty_output><jupyter_text>Clustering t-SNE des documents<jupyter_code>def plot_tsne_lda(model, corpus, save=True, plot=True, revue='AE'):
    """Calcule puis trace la projection t-SNE 2D de la représentation LDA du corpus"""
    # Poids des thèmes
    topic_weights = []
    for i, row_list in enumerate(model[corpus]):
        topic_weights.append([w for i, w in row_list])

    arr = pd.DataFrame(topic_weights).fillna(0).values

    # Réduction t-SNE
    tsne_model = TSNE(n_components=2, verbose=1, random_state=0, angle=.99, init='pca')
    tsne_lda = tsne_model.fit_transform(arr)
    embedding = pd.DataFrame(tsne_lda, columns=['x','y'])
    embedding['hue'] = arr.argmax(axis=1)
    
    # Récupérer le thème dominant pour chaque document
    topic_num = np.argmax(arr, axis=1)
    
    n_topics = model.num_topics
    # Création du plot
    
    mycolors = np.array([color for name, color in mcolors.XKCD_COLORS.items()])
    plot = figure(title="Clustering t-SNE de la revue {} avec {} LDA Topics".format(revue, n_topics), 
                  plot_width=900, plot_height=700)
    plot.scatter(x=tsne_lda[:,0], y=tsne_lda[:,1], color=mycolors[topic_num])
    
    if plot:
        show(plot)
    else :
        plot.close()
    if save:
        export_png(plot, filename="Plots/LDA/clustering_tsne/tsne_"+revue+'_num_topics='+ str(n_topics)+ ".png")
    
    return embedding, tsne_lda<jupyter_output><empty_output><jupyter_text>**AE**<jupyter_code>corpus = corpus_full_AE
for topic in tqdm([10,20,30]):
    model = LdaModel.load("Résultats_LDA/AE/lda_ae_" + str(topic))
    plot_tsne_lda(model, corpus, revue='AE', save=False,plot=True)<jupyter_output><empty_output><jupyter_text>**EI**<jupyter_code>corpus = corpus_full_EI
for topic in tqdm([10,20,30]):
    model = LdaModel.load("Résultats_LDA/EI/lda_ei_" + str(topic))
    plot_tsne_lda(model, corpus, revue='EI', save=True,plot=False)<jupyter_output><empty_output><jupyter_text>**RI**<jupyter_code>corpus = corpus_full_RI
for topic in tqdm([10,20,30]):
    model = LdaModel.load("Résultats_LDA/RI/lda_ri_" + str(topic))
    plot_tsne_lda(model, corpus, revue='RI', save=True,plot=False)<jupyter_output><empty_output><jupyter_text>**PLOT INTERACTIF AVEC TITRES DES DOCUMENTS SUR LE SCHEMA**<jupyter_code>def plot_interactive_tsne (model, corpus = corpus_full_AE, corpus_filtre=corpus_ae_filtre, revue='AE', save=False):
    # Formation du tableau de documents/thèmes
    df = format_topics_sentences(ldamodel=model, corpus_filtre=corpus_filtre)
    df_dominant_topic = df.reset_index()
    df_dominant_topic.columns = ['index', 'Thème principal', '% de contribution du thème', 'Mots-clés du thème','Text','Titre','URL']
    
    # Calcul de la projection t-SNE
    topic_weights = []
    for i, row_list in enumerate(model[corpus]):
        topic_weights.append([w for i, w in row_list])
    arr = pd.DataFrame(topic_weights).fillna(0).values
    tsne_model = TSNE(n_components=2, verbose=1, random_state=0, angle=.99, init='pca')
    tsne_lda = tsne_model.fit_transform(arr)
    embedding = pd.DataFrame(tsne_lda, columns=['x','y'])
    embedding['hue'] = arr.argmax(axis=1)
    
    # Visualisation dans Bokeh
    n_topics = model.num_topics
    topic_num = np.argmax(arr, axis=1)
    source = ColumnDataSource(
        data=dict(
            x = embedding.x,
            y = embedding.y,
            colors = np.array([color for name, color in mcolors.XKCD_COLORS.items()])[topic_num],
            title = df_dominant_topic.Titre,
            alpha = [0.9] * embedding.shape[0],
            size = [9] * embedding.shape[0],
        )
    )
    callback = CustomJS(args=dict(source=source), code="""
        var data = source.data;
        var f = cb_obj.value
        x = data['x']
        y = data['y']
        colors = data['colors']
        alpha = data['alpha']
        title = data['title']
        size = data['size']
        for (i = 0; i < x.length; i++) {
            if (year[i] <= f) {
                alpha[i] = 0.9
                size[i] = 7
            } else {
                alpha[i] = 0.05
                size[i] = 4
            }
        }
        source.trigger('change');
    """)

    hover_tsne = HoverTool(names=["df_dominant_topic"], tooltips="""
        <div style="margin: 10">
            <div style="margin: 0 auto; width:300px;">
                <span style="font-size: 12px; font-weight: bold;">Title:</span>
                <span style="font-size: 12px">@title</span>
            </div>
        </div>
        """)
    tools_tsne = [hover_tsne, 'pan', 'wheel_zoom', 'reset']
    plot_tsne = figure(title="Clustering t-SNE de la revue {} avec {} LDA Topics".format(revue, n_topics), 
                      plot_width=700, plot_height=700, tools=tools_tsne)
    plot_tsne.circle('x', 'y', size='size', fill_color='colors',
                     alpha='alpha', line_alpha=0, line_width=0.01, source=source, name="df_dominant_topic")

    show(plot_tsne)
    
    if save:
        export_png(plot_tsne, filename="Plots/LDA/clustering_tsne/tsne_"+revue+'_num_topics='+ str(n_topics)+ ".png")
        
    plt.close()
plot_interactive_tsne (model=model_ae_10, corpus=corpus_full_AE,corpus_filtre=corpus_ae_filtre, revue='AE', save=False)
for topic in range(10):
    print([element[0] for element in model_ae_10.show_topic(topicid=topic)])
model_ei_10 = LdaModel.load("Résultats_LDA/EI/lda_ei_" + str(10))
plot_interactive_tsne (model=model_ei_10, corpus=corpus_full_EI,corpus_filtre=corpus_ei_filtre, revue='EI', save=True)
for topic in range(10):
    print([element[0] for element in model_ei_10.show_topic(topicid=topic)])
model_ri_10 = LdaModel.load("Résultats_LDA/RI/lda_ri_" + str(10))
plot_interactive_tsne (model=model_ri_10, corpus=corpus_full_RI,corpus_filtre=corpus_ri_filtre, revue='RI', save=True)
for topic in range(10):
    print([element[0] for element in model_ri_10.show_topic(topicid=topic)])<jupyter_output><empty_output><jupyter_text>**Analyse manuelle de fréquence de tokens**<jupyter_code>%store -r Corpus_AE
%store -r tokens_bigrams_Corpus_LDA_AE_clean
Corpus_AE_LDA_metadata = filtre_corpus(Corpus_AE, tokens_bigrams_Corpus_LDA_AE_clean)
#### Récupérer les métadonnées et tokens pour les articles
def filtre_corpus(Corpus, tokens):
    """Prend en paramètre le Corpus avec textes et métadonnées et retourne le Corpus filtré avec les articles en français et de type article
    + les tokens nettoyés pour chacun d'entre eux"""
    Corpus_filtre = []
    index_clean = 0
    for index_document in tqdm_notebook(range(len(Corpus))) :
    # on ne traite que les articles de type article et en français
        if (Corpus[index_document]['metadata']['typeart'], Corpus[index_document]['metadata']['lang']) == ('article','fr') : 
            Corpus_filtre.append((Corpus[index_document]['URL'], Corpus[index_document]['metadata']['title'], tokens[index_clean]))
            index_clean +=1
    return Corpus_filtre
def compte_frequences(liste_tokens):
    """Retourne une liste de tuples (token,occurence) triée dans l'ordre décroissant"""
    compte = {}
    for element in liste_tokens:
        try: compte[element] += 1
        except: compte[element] = 1
    sorted_by_value = sorted(compte.items(), key=lambda kv: kv[1], reverse=True)
    return sorted_by_value
# compte_frequence_AE contient pour chaque article un triplet de la forme : (URL, titre, (token , occurence du token))
compte_frequence_AE = []
for article in Corpus_AE_LDA_metadata:
    compte_frequence_AE.append((article[0], article[1], compte_frequences(article[2])))
def find_string(string, string2 ='', double_check=False):
    """Chercher un token d'intérêt et retourner le triplet de compte_frequence_AE le cas échéant"""
    articles_with_string = []
    for article in compte_frequence_AE:
        for element in article[2]:
            if string == element[0]:
                if double_check == True: #option pour vérifier la présence simultanée de 2 string dans le même texte
                    for element in article[2] :
                        if string2 == element[0]:
                            articles_with_string.append((article))
                            break
                else : 
                    articles_with_string.append((article))
                    break
    return articles_with_string
test_string = find_string('baie_james', '', double_check=False)
for element in test_string:
    print(element[1])<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup