Demosthene-OR commited on
Commit
babcb18
1 Parent(s): 95043cb
app.py CHANGED
@@ -5,8 +5,8 @@ from streamlit_option_menu import option_menu
5
  # Define TITLE, TEAM_MEMBERS and PROMOTION values, in config.py.
6
  import config
7
  from tabs.custom_vectorizer import custom_tokenizer, custom_preprocessor
8
-
9
-
10
 
11
  # Initialize a session state variable that tracks the sidebar state (either 'expanded' or 'collapsed').
12
  if 'sidebar_state' not in st.session_state:
@@ -20,10 +20,23 @@ st.set_page_config (
20
  initial_sidebar_state=st.session_state.sidebar_state
21
  )
22
 
 
 
 
 
 
 
 
 
 
 
 
23
  # Define the root folders depending on local/cloud run
24
  thisfile = os.path.abspath(__file__)
 
25
  if ('/' in thisfile):
26
  os.chdir(os.path.dirname(thisfile))
 
27
 
28
  # Nécessaire pour la version windows 11
29
  os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
@@ -43,20 +56,27 @@ st.markdown(f"<style>{style}</style>", unsafe_allow_html=True)
43
  # as value as follow :
44
  TABS = OrderedDict(
45
  [
46
- (intro.sidebar_name, intro),
47
- (exploration_tab.sidebar_name, exploration_tab),
48
- (data_viz_tab.sidebar_name, data_viz_tab),
49
- (id_lang_tab.sidebar_name, id_lang_tab),
50
- (modelisation_dict_tab.sidebar_name, modelisation_dict_tab),
51
- (modelisation_seq2seq_tab.sidebar_name, modelisation_seq2seq_tab),
52
- (game_tab.sidebar_name, game_tab ),
53
  ]
54
  )
55
 
56
 
57
- def run():
 
 
 
 
58
  global lang_tgt, label_lang
59
-
 
 
 
60
  st.sidebar.image(
61
  "assets/demosthene_logo.png",
62
  width=270,
@@ -64,7 +84,7 @@ def run():
64
  with st.sidebar:
65
  tab_name = option_menu(None, list(TABS.keys()),
66
  # icons=['house', 'bi-binoculars', 'bi bi-graph-up', 'bi-chat-right-text','bi-book', 'bi-body-text'], menu_icon="cast", default_index=0,
67
- icons=['house', 'binoculars', 'graph-up', 'search','book', 'chat-right-text', 'controller'], menu_icon="cast", default_index=0,
68
  styles={"container": {"padding": "0!important","background-color": "#10b8dd", "border-radius": "0!important"},
69
  "nav-link": {"font-size": "1rem", "text-align": "left", "margin":"0em", "padding": "0em",
70
  "padding-left": "0.2em", "--hover-color": "#eee", "font-weight": "400",
@@ -78,9 +98,11 @@ def run():
78
  for member in config.TEAM_MEMBERS:
79
  st.sidebar.markdown(member.sidebar_markdown(), unsafe_allow_html=True)
80
 
 
 
 
81
  tab = TABS[tab_name]
82
  tab.run()
83
 
84
-
85
  if __name__ == "__main__":
86
  run()
 
5
  # Define TITLE, TEAM_MEMBERS and PROMOTION values, in config.py.
6
  import config
7
  from tabs.custom_vectorizer import custom_tokenizer, custom_preprocessor
8
+ import os
9
+ from translate_app import tr
10
 
11
  # Initialize a session state variable that tracks the sidebar state (either 'expanded' or 'collapsed').
12
  if 'sidebar_state' not in st.session_state:
 
20
  initial_sidebar_state=st.session_state.sidebar_state
21
  )
22
 
23
+ # Si l'application tourne localement, session_state.Cloud == 0
24
+ # Si elle tourne sur le Cloud de Hugging Face, ==1
25
+ st.session_state.Cloud = 1
26
+ # En fonction de la valeur de varible précédente, le data path est différent
27
+ if st.session_state.Cloud == 0:
28
+ st.session_state.DataPath = "../data"
29
+ st.session_state.reCalcule = False
30
+ else:
31
+ st.session_state.DataPath = "data"
32
+ st.session_state.reCalcule = False
33
+
34
  # Define the root folders depending on local/cloud run
35
  thisfile = os.path.abspath(__file__)
36
+ print("Path before:",os.path.abspath(__file__))
37
  if ('/' in thisfile):
38
  os.chdir(os.path.dirname(thisfile))
39
+ print("Path after:",os.path.abspath(__file__))
40
 
41
  # Nécessaire pour la version windows 11
42
  os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
 
56
  # as value as follow :
57
  TABS = OrderedDict(
58
  [
59
+ (tr(intro.sidebar_name), intro),
60
+ (tr(exploration_tab.sidebar_name), exploration_tab),
61
+ (tr(data_viz_tab.sidebar_name), data_viz_tab),
62
+ (tr(id_lang_tab.sidebar_name), id_lang_tab),
63
+ (tr(modelisation_dict_tab.sidebar_name), modelisation_dict_tab),
64
+ (tr(modelisation_seq2seq_tab.sidebar_name), modelisation_seq2seq_tab),
65
+ (tr(game_tab.sidebar_name), game_tab ),
66
  ]
67
  )
68
 
69
 
70
+ lang_tgt = ['fr','en','af','ak','sq','de','am','en','ar','hy','as','az','ba','bm','eu','bn','be','my','bs','bg','ks','ca','ny','zh','si','ko','co','ht','hr','da','dz','gd','es','eo','et','ee','fo','fj','fi','fr','fy','gl','cy','lg','ka','el','gn','gu','ha','he','hi','hu','ig','id','iu','ga','is','it','ja','kn','kk','km','ki','rw','ky','rn','ku','lo','la','lv','li','ln','lt','lb','mk','ms','ml','dv','mg','mt','mi','mr','mn','nl','ne','no','nb','nn','oc','or','ug','ur','uz','ps','pa','fa','pl','pt','ro','ru','sm','sg','sa','sc','sr','sn','sd','sk','sl','so','st','su','sv','sw','ss','tg','tl','ty','ta','tt','cs','te','th','bo','ti','to','ts','tn','tr','tk','tw','uk','vi','wo','xh','yi']
71
+ label_lang = ['Français', 'Anglais','Afrikaans','Akan','Albanais','Allemand','Amharique','Anglais','Arabe','Arménien','Assamais','Azéri','Bachkir','Bambara','Basque','Bengali','Biélorusse','Birman','Bosnien','Bulgare','Cachemiri','Catalan','Chichewa','Chinois','Cingalais','Coréen','Corse','Créolehaïtien','Croate','Danois','Dzongkha','Écossais','Espagnol','Espéranto','Estonien','Ewe','Féroïen','Fidjien','Finnois','Français','Frisonoccidental','Galicien','Gallois','Ganda','Géorgien','Grecmoderne','Guarani','Gujarati','Haoussa','Hébreu','Hindi','Hongrois','Igbo','Indonésien','Inuktitut','Irlandais','Islandais','Italien','Japonais','Kannada','Kazakh','Khmer','Kikuyu','Kinyarwanda','Kirghiz','Kirundi','Kurde','Lao','Latin','Letton','Limbourgeois','Lingala','Lituanien','Luxembourgeois','Macédonien','Malais','Malayalam','Maldivien','Malgache','Maltais','MaorideNouvelle-Zélande','Marathi','Mongol','Néerlandais','Népalais','Norvégien','Norvégienbokmål','Norvégiennynorsk','Occitan','Oriya','Ouïghour','Ourdou','Ouzbek','Pachto','Pendjabi','Persan','Polonais','Portugais','Roumain','Russe','Samoan','Sango','Sanskrit','Sarde','Serbe','Shona','Sindhi','Slovaque','Slovène','Somali','SothoduSud','Soundanais','Suédois','Swahili','Swati','Tadjik','Tagalog','Tahitien','Tamoul','Tatar','Tchèque','Télougou','Thaï','Tibétain','Tigrigna','Tongien','Tsonga','Tswana','Turc','Turkmène','Twi','Ukrainien','Vietnamien','Wolof','Xhosa','Yiddish']
72
+
73
+ @st.cache_data
74
+ def find_lang_label(lang_sel):
75
  global lang_tgt, label_lang
76
+ return label_lang[lang_tgt.index(lang_sel)]
77
+
78
+ def run():
79
+
80
  st.sidebar.image(
81
  "assets/demosthene_logo.png",
82
  width=270,
 
84
  with st.sidebar:
85
  tab_name = option_menu(None, list(TABS.keys()),
86
  # icons=['house', 'bi-binoculars', 'bi bi-graph-up', 'bi-chat-right-text','bi-book', 'bi-body-text'], menu_icon="cast", default_index=0,
87
+ icons=['house', 'binoculars', 'graph-up', 'search','book', 'chat-right-text','controller'], menu_icon="cast", default_index=0,
88
  styles={"container": {"padding": "0!important","background-color": "#10b8dd", "border-radius": "0!important"},
89
  "nav-link": {"font-size": "1rem", "text-align": "left", "margin":"0em", "padding": "0em",
90
  "padding-left": "0.2em", "--hover-color": "#eee", "font-weight": "400",
 
98
  for member in config.TEAM_MEMBERS:
99
  st.sidebar.markdown(member.sidebar_markdown(), unsafe_allow_html=True)
100
 
101
+ with st.sidebar:
102
+ st.selectbox("langue:",lang_tgt, format_func = find_lang_label, key="Language", label_visibility="hidden")
103
+
104
  tab = TABS[tab_name]
105
  tab.run()
106
 
 
107
  if __name__ == "__main__":
108
  run()
tabs/data_viz_tab.py CHANGED
@@ -17,10 +17,11 @@ from gensim import corpora
17
  import networkx as nx
18
  from sklearn.manifold import TSNE
19
  from gensim.models import KeyedVectors
20
-
21
 
22
  title = "Data Vizualization"
23
  sidebar_name = "Data Vizualization"
 
24
 
25
  with contextlib.redirect_stdout(open(os.devnull, "w")):
26
  nltk.download('stopwords')
@@ -34,7 +35,7 @@ if ((first_line+max_lines)>137860):
34
  # Nombre maximum de ligne à afficher pour les DataFrame
35
  max_lines_to_display = 50
36
 
37
- @st.cache_data(ttl='1h00s')
38
  def load_data(path):
39
 
40
  input_file = os.path.join(path)
@@ -47,7 +48,7 @@ def load_data(path):
47
  data = data.split('\n')
48
  return data[first_line:min(len(data),first_line+max_lines)]
49
 
50
- @st.cache_data(ttl='1h00s')
51
  def load_preprocessed_data(path,data_type):
52
 
53
  input_file = os.path.join(path)
@@ -68,14 +69,14 @@ def load_preprocessed_data(path,data_type):
68
  data=data2
69
  return data
70
 
71
- @st.cache_data(ttl='1h00s')
72
  def load_all_preprocessed_data(lang):
73
- txt =load_preprocessed_data('data/preprocess_txt_'+lang,0)
74
- corpus =load_preprocessed_data('data/preprocess_corpus_'+lang,0)
75
- txt_split = load_preprocessed_data('data/preprocess_txt_split_'+lang,3)
76
- df_count_word = pd.concat([load_preprocessed_data('data/preprocess_df_count_word1_'+lang,1), load_preprocessed_data('data/preprocess_df_count_word2_'+lang,1)])
77
- sent_len =load_preprocessed_data('data/preprocess_sent_len_'+lang,2)
78
- vec_model= KeyedVectors.load_word2vec_format('data/mini.wiki.'+lang+'.align.vec')
79
  return txt, corpus, txt_split, df_count_word,sent_len, vec_model
80
 
81
  #Chargement des textes complet dans les 2 langues
@@ -92,7 +93,7 @@ def plot_word_cloud(text, title, masque, stop_words, background_color = "white")
92
  max_font_size=50, random_state=42)
93
  # Générer et afficher le nuage de mots
94
  fig=plt.figure(figsize= (20,10))
95
- plt.title(title, fontsize=25, color="green")
96
  wc.generate(text)
97
 
98
  # getting current axes
@@ -130,7 +131,7 @@ def dist_frequence_mots(df_count_word):
130
 
131
  sns.set()
132
  fig = plt.figure() #figsize=(4,4)
133
- plt.title("Nombre d'apparitions des mots", fontsize=16)
134
 
135
  chart = sns.barplot(x='mots',y='occurences',data=nb_occurences.iloc[:40]);
136
  chart.set_xticklabels(chart.get_xticklabels(), rotation=45, horizontalalignment='right', size=8)
@@ -174,7 +175,7 @@ def dist_longueur_phrase(sent_len,sent_len2, lang1, lang2 ):
174
  chart = sns.histplot(df, color=['r','b'], label=[lang1,lang2], binwidth=1, binrange=[2,22], element="step",
175
  common_norm=False, multiple="layer", discrete=True, stat='proportion')
176
  plt.xticks([2,4,6,8,10,12,14,16,18,20,22])
177
- chart.set(title='Distribution du nombre de mots sur '+str(len(sent_len))+' phrase(s)');
178
  st.pyplot(fig)
179
 
180
  '''
@@ -245,8 +246,8 @@ def proximite():
245
  labels = []
246
  tokens = []
247
 
248
- nb_words = st.slider('Nombre de mots à afficher :',10,50, value=20)
249
- df = pd.read_csv('data/dict_we_en_fr',header=0,index_col=0, encoding ="utf-8", keep_default_na=False)
250
  words_en = df.index.to_list()[:nb_words]
251
  words_fr = df['Francais'].to_list()[:nb_words]
252
 
@@ -280,7 +281,7 @@ def proximite():
280
  va='bottom',
281
  color= color,
282
  size=20)
283
- plt.title("Proximité des mots anglais avec leur traduction", fontsize=30, color="green")
284
  plt.legend(loc='best');
285
  st.pyplot(fig)
286
 
@@ -292,13 +293,13 @@ def run():
292
  global full_txt_fr, full_corpus_fr, full_txt_split_fr, full_df_count_word_fr,full_sent_len_fr, vec_model_fr
293
 
294
  st.write("")
295
- st.title(title)
296
 
297
  #
298
- st.write("## **Paramètres :**\n")
299
- Langue = st.radio('Langue:',('Anglais','Français'), horizontal=True)
300
- first_line = st.slider('No de la premiere ligne à analyser :',0,137859)
301
- max_lines = st.select_slider('Nombre de lignes à analyser :',
302
  options=[1,5,10,15,100, 500, 1000,'Max'])
303
  if max_lines=='Max':
304
  max_lines=137860
@@ -328,74 +329,78 @@ def run():
328
  st.dataframe(pd.DataFrame(data=full_txt_fr,columns=['Texte']).loc[first_line:last_line-1].head(max_lines_to_display), width=800)
329
  st.write("")
330
 
331
- tab1, tab2, tab3, tab4, tab5 = st.tabs(["World Cloud", "Frequence","Distribution longueur", "Co-occurence", "Proximité"])
332
 
333
  with tab1:
334
- st.subheader("World Cloud")
335
- st.markdown(
336
  """
337
  On remarque, en changeant de langue, que certains mot de taille importante dans une langue,
338
  apparaissent avec une taille identique dans l'autre langue.
339
  La traduction mot à mot sera donc peut-être bonne.
340
- """
341
  )
342
  if (Langue == 'Anglais'):
343
  text = ""
344
  # Initialiser la variable des mots vides
345
  stop_words = set(stopwords.words('english'))
346
  for e in txt_en : text += e
347
- plot_word_cloud(text, "English words corpus", "images/coeur.png", stop_words)
348
  else:
349
  text = ""
350
  # Initialiser la variable des mots vides
351
  stop_words = set(stopwords.words('french'))
352
  for e in txt_fr : text += e
353
- plot_word_cloud(text,"Mots français du corpus", "images/coeur.png", stop_words)
354
 
355
  with tab2:
356
- st.subheader("Frequence d'apparition des mots")
357
- st.markdown(
358
  """
359
  On remarque, en changeant de langue, que certains mot fréquents dans une langue,
360
  apparaissent aussi fréquemment dans l'autre langue.
361
  Cela peut nous laisser penser que la traduction mot à mot sera peut-être bonne.
362
- """
363
  )
364
  if (Langue == 'Anglais'):
365
  dist_frequence_mots(df_count_word_en)
366
  else:
367
  dist_frequence_mots(df_count_word_fr)
368
  with tab3:
369
- st.subheader("Distribution des longueurs de phrases")
370
- st.markdown(
371
  """
372
  Malgré quelques différences entre les 2 langues (les phrases anglaises sont généralement un peu plus courtes),
373
  on constate une certaine similitude dans les ditributions de longueur de phrases.
374
  Cela peut nous laisser penser que la traduction mot à mot ne sera pas si mauvaise.
375
- """
376
  )
377
  if (Langue == 'Anglais'):
378
  dist_longueur_phrase(sent_len_en, sent_len_fr, 'Anglais','Français')
379
  else:
380
  dist_longueur_phrase(sent_len_fr, sent_len_en, 'Français', 'Anglais')
381
  with tab4:
382
- st.subheader("Co-occurence des mots dans une phrase")
383
  if (Langue == 'Anglais'):
384
  graphe_co_occurence(txt_split_en[:1000],corpus_en)
385
  else:
386
  graphe_co_occurence(txt_split_fr[:1000],corpus_fr)
387
  with tab5:
388
- st.subheader("Proximité sémantique des mots (Word Embedding)")
389
- st.markdown(
390
  """
391
  MUSE est une bibliothèque Python pour l'intégration de mots multilingues, qui fournit
392
  notamment des "Word Embedding" multilingues
393
  Facebook fournit des dictionnaires de référence. Ces embeddings sont des embeddings fastText Wikipedia pour 30 langues qui ont été alignés dans un espace espace vectoriel unique.
394
  Dans notre cas, nous avons utilisé 2 mini-dictionnaires d'environ 3000 mots (Français et Anglais).
395
 
 
 
 
 
396
  En novembre 2015, l'équipe de recherche de Facebook a créé fastText qui est une extension de la bibliothèque word2vec.
397
  Elle s'appuie sur Word2Vec en apprenant des représentations vectorielles pour chaque mot et les n-grammes trouvés dans chaque mot.
398
- """
399
  )
400
  st.write("")
401
  proximite()
 
17
  import networkx as nx
18
  from sklearn.manifold import TSNE
19
  from gensim.models import KeyedVectors
20
+ from translate_app import tr
21
 
22
  title = "Data Vizualization"
23
  sidebar_name = "Data Vizualization"
24
+ dataPath = st.session_state.DataPath
25
 
26
  with contextlib.redirect_stdout(open(os.devnull, "w")):
27
  nltk.download('stopwords')
 
35
  # Nombre maximum de ligne à afficher pour les DataFrame
36
  max_lines_to_display = 50
37
 
38
+ @st.cache_data
39
  def load_data(path):
40
 
41
  input_file = os.path.join(path)
 
48
  data = data.split('\n')
49
  return data[first_line:min(len(data),first_line+max_lines)]
50
 
51
+ @st.cache_data
52
  def load_preprocessed_data(path,data_type):
53
 
54
  input_file = os.path.join(path)
 
69
  data=data2
70
  return data
71
 
72
+ @st.cache_data
73
  def load_all_preprocessed_data(lang):
74
+ txt =load_preprocessed_data(dataPath+'/preprocess_txt_'+lang,0)
75
+ corpus =load_preprocessed_data(dataPath+'/preprocess_corpus_'+lang,0)
76
+ txt_split = load_preprocessed_data(dataPath+'/preprocess_txt_split_'+lang,3)
77
+ df_count_word = pd.concat([load_preprocessed_data(dataPath+'/preprocess_df_count_word1_'+lang,1), load_preprocessed_data(dataPath+'/preprocess_df_count_word2_'+lang,1)])
78
+ sent_len =load_preprocessed_data(dataPath+'/preprocess_sent_len_'+lang,2)
79
+ vec_model= KeyedVectors.load_word2vec_format(dataPath+'/mini.wiki.'+lang+'.align.vec')
80
  return txt, corpus, txt_split, df_count_word,sent_len, vec_model
81
 
82
  #Chargement des textes complet dans les 2 langues
 
93
  max_font_size=50, random_state=42)
94
  # Générer et afficher le nuage de mots
95
  fig=plt.figure(figsize= (20,10))
96
+ plt.title(tr(title), fontsize=25, color="green")
97
  wc.generate(text)
98
 
99
  # getting current axes
 
131
 
132
  sns.set()
133
  fig = plt.figure() #figsize=(4,4)
134
+ plt.title(tr("Nombre d'apparitions des mots"), fontsize=16)
135
 
136
  chart = sns.barplot(x='mots',y='occurences',data=nb_occurences.iloc[:40]);
137
  chart.set_xticklabels(chart.get_xticklabels(), rotation=45, horizontalalignment='right', size=8)
 
175
  chart = sns.histplot(df, color=['r','b'], label=[lang1,lang2], binwidth=1, binrange=[2,22], element="step",
176
  common_norm=False, multiple="layer", discrete=True, stat='proportion')
177
  plt.xticks([2,4,6,8,10,12,14,16,18,20,22])
178
+ chart.set(title=tr('Distribution du nombre de mots sur '+str(len(sent_len))+' phrase(s)'));
179
  st.pyplot(fig)
180
 
181
  '''
 
246
  labels = []
247
  tokens = []
248
 
249
+ nb_words = st.slider(tr('Nombre de mots à afficher')+' :',10,50, value=20)
250
+ df = pd.read_csv('../data/dict_we_en_fr',header=0,index_col=0, encoding ="utf-8", keep_default_na=False)
251
  words_en = df.index.to_list()[:nb_words]
252
  words_fr = df['Francais'].to_list()[:nb_words]
253
 
 
281
  va='bottom',
282
  color= color,
283
  size=20)
284
+ plt.title(tr("Proximité des mots anglais avec leur traduction"), fontsize=30, color="green")
285
  plt.legend(loc='best');
286
  st.pyplot(fig)
287
 
 
293
  global full_txt_fr, full_corpus_fr, full_txt_split_fr, full_df_count_word_fr,full_sent_len_fr, vec_model_fr
294
 
295
  st.write("")
296
+ st.title(tr(title))
297
 
298
  #
299
+ st.write("## **"+tr("Paramètres")+" :**\n")
300
+ Langue = st.radio(tr('Langue:'),('Anglais','Français'), horizontal=True)
301
+ first_line = st.slider(tr('No de la premiere ligne à analyser')+' :',0,137859)
302
+ max_lines = st.select_slider(tr('Nombre de lignes à analyser')+' :',
303
  options=[1,5,10,15,100, 500, 1000,'Max'])
304
  if max_lines=='Max':
305
  max_lines=137860
 
329
  st.dataframe(pd.DataFrame(data=full_txt_fr,columns=['Texte']).loc[first_line:last_line-1].head(max_lines_to_display), width=800)
330
  st.write("")
331
 
332
+ tab1, tab2, tab3, tab4, tab5 = st.tabs([tr("World Cloud"), tr("Frequence"),tr("Distribution longueur"), tr("Co-occurence"), tr("Proximité")])
333
 
334
  with tab1:
335
+ st.subheader(tr("World Cloud"))
336
+ st.markdown(tr(
337
  """
338
  On remarque, en changeant de langue, que certains mot de taille importante dans une langue,
339
  apparaissent avec une taille identique dans l'autre langue.
340
  La traduction mot à mot sera donc peut-être bonne.
341
+ """)
342
  )
343
  if (Langue == 'Anglais'):
344
  text = ""
345
  # Initialiser la variable des mots vides
346
  stop_words = set(stopwords.words('english'))
347
  for e in txt_en : text += e
348
+ plot_word_cloud(text, "English words corpus", "../images/coeur.png", stop_words)
349
  else:
350
  text = ""
351
  # Initialiser la variable des mots vides
352
  stop_words = set(stopwords.words('french'))
353
  for e in txt_fr : text += e
354
+ plot_word_cloud(text,"Mots français du corpus", "../images/coeur.png", stop_words)
355
 
356
  with tab2:
357
+ st.subheader(tr("Frequence d'apparition des mots"))
358
+ st.markdown(tr(
359
  """
360
  On remarque, en changeant de langue, que certains mot fréquents dans une langue,
361
  apparaissent aussi fréquemment dans l'autre langue.
362
  Cela peut nous laisser penser que la traduction mot à mot sera peut-être bonne.
363
+ """)
364
  )
365
  if (Langue == 'Anglais'):
366
  dist_frequence_mots(df_count_word_en)
367
  else:
368
  dist_frequence_mots(df_count_word_fr)
369
  with tab3:
370
+ st.subheader(tr("Distribution des longueurs de phrases"))
371
+ st.markdown(tr(
372
  """
373
  Malgré quelques différences entre les 2 langues (les phrases anglaises sont généralement un peu plus courtes),
374
  on constate une certaine similitude dans les ditributions de longueur de phrases.
375
  Cela peut nous laisser penser que la traduction mot à mot ne sera pas si mauvaise.
376
+ """)
377
  )
378
  if (Langue == 'Anglais'):
379
  dist_longueur_phrase(sent_len_en, sent_len_fr, 'Anglais','Français')
380
  else:
381
  dist_longueur_phrase(sent_len_fr, sent_len_en, 'Français', 'Anglais')
382
  with tab4:
383
+ st.subheader(tr("Co-occurence des mots dans une phrase"))
384
  if (Langue == 'Anglais'):
385
  graphe_co_occurence(txt_split_en[:1000],corpus_en)
386
  else:
387
  graphe_co_occurence(txt_split_fr[:1000],corpus_fr)
388
  with tab5:
389
+ st.subheader(tr("Proximité sémantique des mots (Word Embedding)") )
390
+ st.markdown(tr(
391
  """
392
  MUSE est une bibliothèque Python pour l'intégration de mots multilingues, qui fournit
393
  notamment des "Word Embedding" multilingues
394
  Facebook fournit des dictionnaires de référence. Ces embeddings sont des embeddings fastText Wikipedia pour 30 langues qui ont été alignés dans un espace espace vectoriel unique.
395
  Dans notre cas, nous avons utilisé 2 mini-dictionnaires d'environ 3000 mots (Français et Anglais).
396
 
397
+ """)
398
+ )
399
+ st.markdown(tr(
400
+ """
401
  En novembre 2015, l'équipe de recherche de Facebook a créé fastText qui est une extension de la bibliothèque word2vec.
402
  Elle s'appuie sur Word2Vec en apprenant des représentations vectorielles pour chaque mot et les n-grammes trouvés dans chaque mot.
403
+ """)
404
  )
405
  st.write("")
406
  proximite()
tabs/exploration_tab.py CHANGED
@@ -6,13 +6,21 @@ import collections
6
  from nltk.tokenize import word_tokenize
7
  from nltk import download
8
  from ast import literal_eval
9
- # import contextlib
10
- # import re
11
- # import nltk
12
- # from nltk.corpus import stopwords
 
 
 
 
 
 
 
13
 
14
  title = "Exploration et Preprocessing"
15
  sidebar_name = "Exploration et Preprocessing"
 
16
 
17
  # Indiquer si l'on veut enlever les stop words. C'est un processus long
18
  stopwords_to_do = True
@@ -29,10 +37,12 @@ if ((first_line+max_lines)>137860):
29
  # Nombre maximum de ligne à afficher pour les DataFrame
30
  max_lines_to_display = 50
31
 
32
-
33
  download('punkt')
34
- # nltk.download('averaged_perceptron_tagger')
35
- # nltk.download('stopwords')
 
 
 
36
 
37
  @st.cache_data
38
  def load_data(path):
@@ -67,23 +77,25 @@ def load_preprocessed_data(path,data_type):
67
  data=data2
68
  return data
69
 
70
- # @st.cache_data(ttl='1h00s')
71
  def load_all_preprocessed_data(lang):
72
- txt =load_preprocessed_data('data/preprocess_txt_'+lang,0)
73
- txt_split = load_preprocessed_data('data/preprocess_txt_split_'+lang,3)
74
- txt_lem = load_preprocessed_data('data/preprocess_txt_lem_'+lang,0)
75
- txt_wo_stopword = load_preprocessed_data('data/preprocess_txt_wo_stopword_'+lang,0)
76
- df_count_word = pd.concat([load_preprocessed_data('data/preprocess_df_count_word1_'+lang,1), load_preprocessed_data('data/preprocess_df_count_word2_'+lang,1)])
77
  return txt, txt_split, txt_lem, txt_wo_stopword, df_count_word
78
 
79
  #Chargement des textes complet dans les 2 langues
80
- full_txt_en = load_data('data/small_vocab_en')
81
- full_txt_fr = load_data('data/small_vocab_fr')
 
 
 
 
 
 
82
 
83
- # Chargement du résultat du préprocessing
84
- _ , full_txt_split_en, full_txt_lem_en, full_txt_wo_stopword_en, full_df_count_word_en = load_all_preprocessed_data('en')
85
- _ , full_txt_split_fr, full_txt_lem_fr, full_txt_wo_stopword_fr, full_df_count_word_fr = load_all_preprocessed_data('fr')
86
- """
87
  def remove_stopwords(text, lang):
88
  stop_words = set(stopwords.words(lang))
89
  # stop_words will contain set all english stopwords
@@ -245,7 +257,7 @@ def preprocess_txt (data, lang):
245
  txt_n_unique_val= pd.DataFrame(columns=corpus,index=range(nb_phrases), data=countvectors.todense()).astype(float)
246
 
247
  return data, corpus, data_split, data_lemmatized, data_wosw, txt_n_unique_val, sentence_length, data_length_wo_stopwords, data_lem_length
248
- """
249
 
250
  def count_world(data):
251
  word_count = collections.Counter()
@@ -269,47 +281,45 @@ def display_preprocess_results(lang, data, data_split, data_lem, data_wosw, txt_
269
  txt_n_unique_val = txt_n_unique_val.drop(columns=columns_with_only_zeros)
270
 
271
  # Affichage du nombre de mot en fonction du pré-processing réalisé
272
- tab1, tab2, tab3, tab4 = st.tabs(["Résumé", "Tokenisation","Lemmatisation", "Sans Stopword"])
273
  with tab1:
274
- st.subheader("Résumé du pré-processing")
275
- st.write("**Nombre de phrases : "+str(nb_phrases)+"**")
276
- st.write("**Nombre de mots : "+str(nb_mots)+"**")
277
- st.write("**Nombre de mots uniques : "+str(nb_mots_uniques)+"**")
278
  st.write("")
279
- st.write("\n**Nombre d'apparitions de chaque mot dans chaque phrase (:red[Bag Of Words]):**")
280
  st.dataframe(txt_n_unique_val.head(max_lines_to_display), width=800)
281
  with tab2:
282
- st.subheader("Tokenisation")
283
- st.write('Texte "splited":')
284
  st.dataframe(pd.DataFrame(data=data_split, index=range(first_line,last_line)).head(max_lines_to_display).fillna(''), width=800)
285
- st.write("**Nombre de mots uniques : "+str(nb_mots_uniques)+"**")
286
  st.write("")
287
- st.write("\n**Mots uniques:**")
288
  st.markdown(corpus[:500])
289
- st.write("\n**Nombre d'apparitions de chaque mot dans chaque phrase (:red[Bag Of Words]):**")
290
  st.dataframe(txt_n_unique_val.head(max_lines_to_display), width=800)
291
  with tab3:
292
- st.subheader("Lemmatisation")
293
  if lemmatize_to_do:
294
- st.dataframe(pd.DataFrame(data=data_lem,columns=['Texte lemmatisé'],index=range(first_line,last_line)).head(max_lines_to_display), width=800)
295
  # Si langue anglaise, affichage du taggage des mots
296
- """
297
- if lang == 'en':
298
- for i in range(min(5,len(data))):
299
- s = str(nltk.pos_tag(data_split[i]))
300
- st.markdown("**Texte avec Tags "+str(i)+"** : "+s)
301
- """
302
- st.write("**Nombre de mots uniques lemmatisés : "+str(nb_mots_lem)+"**")
303
  st.write("")
304
- st.write("\n**Mots uniques lemmatisés:**")
305
  st.markdown(mots_lem[:500])
306
  with tab4:
307
- st.subheader("Sans Stopword")
308
  if stopwords_to_do:
309
  st.dataframe(pd.DataFrame(data=data_wosw,columns=['Texte sans stopwords'],index=range(first_line,last_line)).head(max_lines_to_display), width=800)
310
- st.write("**Nombre de mots uniques sans stop words: "+str(nb_mots_wo_stopword)+"**")
311
  st.write("")
312
- st.write("\n**Mots uniques sans stop words:**")
313
  st.markdown(mots_wo_sw[:500])
314
 
315
 
@@ -319,40 +329,40 @@ def run():
319
  global full_txt_fr, full_txt_split_fr, full_txt_lem_fr, full_txt_wo_stopword_fr, full_df_count_word_fr
320
 
321
  st.write("")
322
- st.title(title)
323
 
324
- st.write("## **Explications :**\n")
325
-
326
- st.markdown(
327
  """
328
  Le traitement du langage naturel permet à l'ordinateur de comprendre et de traiter les langues humaines.
329
  Lors de notre projet, nous avons étudié le dataset small_vocab, proposés par Suzan Li, Chief Data Scientist chez Campaign Research à Toronto.
330
  Celui-ci représente un corpus de phrases simples en anglais, et sa traduction (approximative) en français.
331
  :red[**Small_vocab**] contient 137 860 phrases en anglais et français.
 
 
 
 
332
  Afin de découvrir ce corpus et de préparer la traduction, nous allons effectuer un certain nombre de tâches de pré-traitement (preprocessing).
333
  Ces taches sont, par exemple:
334
- * le :red[**nettoyage**] du texte (enlever les majuscules et la ponctuation)
335
- * la :red[**tokenisation**] (découpage du texte en mots)
336
- * la :red[**lemmatisation**] (traitement lexical qui permet de donner une forme unique à toutes les "variations" d'un même mot)
337
- * l'élimination des :red[**mots "transparents**"] (sans utilité pour la compréhension, tels que les articles).
338
- Ce prétraintement se conclut avec la contruction d'un :red[**Bag Of Worlds**], c'est à dire une matrice qui compte le nombre d'apparition de chaque mots (colonne) dans chaque phrase (ligne)
339
-
340
- """
341
- )
 
342
  #
343
- st.write("## **Paramètres :**\n")
344
- Langue = st.radio('Langue:',('Anglais','Français'), horizontal=True)
345
- first_line = st.slider('No de la premiere ligne à analyser:',0,137859)
346
- max_lines = st.select_slider('Nombre de lignes à analyser:',
347
  options=[1,5,10,15,100, 500, 1000,'Max'])
348
  if max_lines=='Max':
349
  max_lines=137860
350
  if ((first_line+max_lines)>137860):
351
  max_lines = max(137860-first_line,0)
352
- # if ((max_lines-first_line)>1000):
353
- # lemmatize_to_do = True
354
- # else:
355
- # lemmatize_to_do = False
356
 
357
  last_line = first_line+max_lines
358
  if (Langue=='Anglais'):
@@ -361,62 +371,50 @@ def run():
361
  st.dataframe(pd.DataFrame(data=full_txt_fr,columns=['Texte']).loc[first_line:last_line-1].head(max_lines_to_display), width=800)
362
  st.write("")
363
 
364
- # Chargement du résultat du préprocessing (max lignes = max_lines)
365
  txt_en = full_txt_en[first_line:last_line]
366
- txt_split_en = full_txt_split_en[first_line:last_line]
367
- txt_lem_en = full_txt_lem_en[first_line:last_line]
368
- txt_wo_stopword_en = full_txt_wo_stopword_en[first_line:last_line]
369
- df_count_word_en = full_df_count_word_en.loc[first_line:last_line-1]
370
  txt_fr = full_txt_fr[first_line:last_line]
371
- txt_split_fr = full_txt_split_fr[first_line:last_line]
372
- txt_lem_fr = full_txt_lem_fr[first_line:last_line]
373
- txt_wo_stopword_fr = full_txt_wo_stopword_fr[first_line:last_line]
374
- df_count_word_fr = full_df_count_word_fr.loc[first_line:last_line-1]
 
 
 
 
 
 
 
 
 
375
 
376
  # Lancement du préprocessing du texte qui va spliter nettoyer les phrases et les spliter en mots
377
  # et calculer nombre d'occurences des mots dans chaque phrase
378
  if (Langue == 'Anglais'):
379
- st.write("## **Préprocessing de small_vocab_en :**\n")
380
  if max_lines>10000:
381
  with st.status(":sunglasses:", expanded=True):
382
- # txt_en, corpus_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en,sent_len_en, sent_wo_sw_len_en, sent_lem_len_en = preprocess_txt (txt_en,'en')
 
383
  display_preprocess_results('en',txt_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en)
384
  else:
385
- # txt_en, corpus_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en,sent_len_en, sent_wo_sw_len_en, sent_lem_len_en = preprocess_txt (txt_en,'en')
 
386
  display_preprocess_results('en',txt_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en)
387
  else:
388
- st.write("## **Préprocessing de small_vocab_fr :**\n")
389
  if max_lines>10000:
390
  with st.status(":sunglasses:", expanded=True):
391
- # txt_fr, corpus_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr,sent_len_fr, sent_wo_sw_len_fr, sent_lem_len_fr = preprocess_txt (txt_fr,'fr')
 
392
  display_preprocess_results('fr', txt_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr)
393
  else:
394
- # txt_fr, corpus_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr,sent_len_fr, sent_wo_sw_len_fr, sent_lem_len_fr = preprocess_txt (txt_fr,'fr')
 
395
  display_preprocess_results('fr', txt_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr)
396
 
397
 
398
 
399
- # Might be used later....
400
- # DEFAULT_TEXT = """Google was founded in September 1998 by Larry Page and Sergey Brin while they were Ph.D. students at Stanford University in California. Together they own about 14 percent of its shares and control 56 percent of the stockholder voting power through supervoting stock. They incorporated Google as a California privately held company on September 4, 1998, in California. Google was then reincorporated in Delaware on October 22, 2002."""
401
- """
402
- spacy_model = "en_core_web_sm"
403
-
404
- text = st.text_area("Text to analyze", DEFAULT_TEXT, height=200)
405
- doc = spacy_streamlit.process_text(spacy_model, text)
406
-
407
- spacy_streamlit.visualize_ner(
408
- doc,
409
- labels=["PERSON", "DATE", "GPE"],
410
- show_table=False,
411
- title="Persons, dates and locations",
412
- )
413
- st.text(f"Analyzed using spaCy model {spacy_model}")
414
- """
415
-
416
- # models = ["en_core_web_sm"]
417
- # default_text = "Google was founded in September 1998 by Larry Page and Sergey Brin while they were Ph.D. students at Stanford University in California. Together they own about 14 percent of its shares and control 56 percent of the stockholder voting power through supervoting stock. They incorporated Google as a California privately held company on September 4, 1998, in California. Google was then reincorporated in Delaware on October 22, 2002."
418
- # spacy_streamlit.visualize(models, default_text)
419
-
420
 
421
 
422
 
 
6
  from nltk.tokenize import word_tokenize
7
  from nltk import download
8
  from ast import literal_eval
9
+ from translate_app import tr
10
+ if st.session_state.Cloud == 0:
11
+ import nltk
12
+ import contextlib
13
+ import re
14
+ from nltk.corpus import stopwords
15
+ import warnings
16
+ warnings.filterwarnings('ignore')
17
+ # from PIL import Image
18
+ # import time
19
+ # import random
20
 
21
  title = "Exploration et Preprocessing"
22
  sidebar_name = "Exploration et Preprocessing"
23
+ dataPath = st.session_state.DataPath
24
 
25
  # Indiquer si l'on veut enlever les stop words. C'est un processus long
26
  stopwords_to_do = True
 
37
  # Nombre maximum de ligne à afficher pour les DataFrame
38
  max_lines_to_display = 50
39
 
 
40
  download('punkt')
41
+
42
+ if st.session_state.Cloud == 0:
43
+ download('averaged_perceptron_tagger')
44
+ with contextlib.redirect_stdout(open(os.devnull, "w")):
45
+ download('stopwords')
46
 
47
  @st.cache_data
48
  def load_data(path):
 
77
  data=data2
78
  return data
79
 
80
+ @st.cache_data
81
  def load_all_preprocessed_data(lang):
82
+ txt =load_preprocessed_data(dataPath+'/preprocess_txt_'+lang,0)
83
+ txt_split = load_preprocessed_data(dataPath+'/preprocess_txt_split_'+lang,3)
84
+ txt_lem = load_preprocessed_data(dataPath+'/preprocess_txt_lem_'+lang,0)
85
+ txt_wo_stopword = load_preprocessed_data(dataPath+'/preprocess_txt_wo_stopword_'+lang,0)
86
+ df_count_word = pd.concat([load_preprocessed_data(dataPath+'/preprocess_df_count_word1_'+lang,1), load_preprocessed_data(dataPath+'/preprocess_df_count_word2_'+lang,1)])
87
  return txt, txt_split, txt_lem, txt_wo_stopword, df_count_word
88
 
89
  #Chargement des textes complet dans les 2 langues
90
+ full_txt_en = load_data(dataPath+'/small_vocab_en')
91
+ full_txt_fr = load_data(dataPath+'/small_vocab_fr')
92
+
93
+ # Chargement du résultat du préprocessing, si st.session_state.reCalcule == False
94
+ if not st.session_state.reCalcule:
95
+ full_txt_en, full_txt_split_en, full_txt_lem_en, full_txt_wo_stopword_en, full_df_count_word_en = load_all_preprocessed_data('en')
96
+ full_txt_fr, full_txt_split_fr, full_txt_lem_fr, full_txt_wo_stopword_fr, full_df_count_word_fr = load_all_preprocessed_data('fr')
97
+
98
 
 
 
 
 
99
  def remove_stopwords(text, lang):
100
  stop_words = set(stopwords.words(lang))
101
  # stop_words will contain set all english stopwords
 
257
  txt_n_unique_val= pd.DataFrame(columns=corpus,index=range(nb_phrases), data=countvectors.todense()).astype(float)
258
 
259
  return data, corpus, data_split, data_lemmatized, data_wosw, txt_n_unique_val, sentence_length, data_length_wo_stopwords, data_lem_length
260
+
261
 
262
  def count_world(data):
263
  word_count = collections.Counter()
 
281
  txt_n_unique_val = txt_n_unique_val.drop(columns=columns_with_only_zeros)
282
 
283
  # Affichage du nombre de mot en fonction du pré-processing réalisé
284
+ tab1, tab2, tab3, tab4 = st.tabs([tr("Résumé"), tr("Tokenisation"),tr("Lemmatisation"), tr("Sans Stopword")])
285
  with tab1:
286
+ st.subheader(tr("Résumé du pré-processing"))
287
+ st.write("**"+tr("Nombre de phrases")+" : "+str(nb_phrases)+"**")
288
+ st.write("**"+tr("Nombre de mots")+" : "+str(nb_mots)+"**")
289
+ st.write("**"+tr("Nombre de mots uniques")+" : "+str(nb_mots_uniques)+"**")
290
  st.write("")
291
+ st.write("\n**"+tr("Nombre d'apparitions de chaque mot dans chaque phrase (:red[Bag Of Words]):")+"**")
292
  st.dataframe(txt_n_unique_val.head(max_lines_to_display), width=800)
293
  with tab2:
294
+ st.subheader(tr("Tokenisation"))
295
+ st.write(tr('Texte "splited":'))
296
  st.dataframe(pd.DataFrame(data=data_split, index=range(first_line,last_line)).head(max_lines_to_display).fillna(''), width=800)
297
+ st.write("**"+tr("Nombre de mots uniques")+" : "+str(nb_mots_uniques)+"**")
298
  st.write("")
299
+ st.write("\n**"+tr("Mots uniques")+":**")
300
  st.markdown(corpus[:500])
301
+ st.write("\n**"+tr("Nombre d'apparitions de chaque mot dans chaque phrase (:red[Bag Of Words]):")+"**")
302
  st.dataframe(txt_n_unique_val.head(max_lines_to_display), width=800)
303
  with tab3:
304
+ st.subheader(tr("Lemmatisation"))
305
  if lemmatize_to_do:
306
+ st.dataframe(pd.DataFrame(data=data_lem,columns=[tr('Texte lemmatisé')],index=range(first_line,last_line)).head(max_lines_to_display), width=800)
307
  # Si langue anglaise, affichage du taggage des mots
308
+ # if lang == 'en':
309
+ # for i in range(min(5,len(data))):
310
+ # s = str(nltk.pos_tag(data_split[i]))
311
+ # st.markdown("**Texte avec Tags "+str(i)+"** : "+s)
312
+ st.write("**"+tr("Nombre de mots uniques lemmatisés")+" : "+str(nb_mots_lem)+"**")
 
 
313
  st.write("")
314
+ st.write("\n**"+tr("Mots uniques lemmatisés:")+"**")
315
  st.markdown(mots_lem[:500])
316
  with tab4:
317
+ st.subheader(tr("Sans Stopword"))
318
  if stopwords_to_do:
319
  st.dataframe(pd.DataFrame(data=data_wosw,columns=['Texte sans stopwords'],index=range(first_line,last_line)).head(max_lines_to_display), width=800)
320
+ st.write("**"+tr("Nombre de mots uniques sans stop words")+": "+str(nb_mots_wo_stopword)+"**")
321
  st.write("")
322
+ st.write("\n**"+tr("Mots uniques sans stop words")+":**")
323
  st.markdown(mots_wo_sw[:500])
324
 
325
 
 
329
  global full_txt_fr, full_txt_split_fr, full_txt_lem_fr, full_txt_wo_stopword_fr, full_df_count_word_fr
330
 
331
  st.write("")
332
+ st.title(tr(title))
333
 
334
+ st.write("## **"+tr("Explications")+" :**\n")
335
+ st.markdown(tr(
 
336
  """
337
  Le traitement du langage naturel permet à l'ordinateur de comprendre et de traiter les langues humaines.
338
  Lors de notre projet, nous avons étudié le dataset small_vocab, proposés par Suzan Li, Chief Data Scientist chez Campaign Research à Toronto.
339
  Celui-ci représente un corpus de phrases simples en anglais, et sa traduction (approximative) en français.
340
  :red[**Small_vocab**] contient 137 860 phrases en anglais et français.
341
+ """)
342
+ , unsafe_allow_html=True)
343
+ st.markdown(tr(
344
+ """
345
  Afin de découvrir ce corpus et de préparer la traduction, nous allons effectuer un certain nombre de tâches de pré-traitement (preprocessing).
346
  Ces taches sont, par exemple:
347
+ """)
348
+ , unsafe_allow_html=True)
349
+ st.markdown(
350
+ "* "+tr("le :red[**nettoyage**] du texte (enlever les majuscules et la ponctuation)")+"\n"+ \
351
+ "* "+tr("la :red[**tokenisation**] (découpage du texte en mots)")+"\n"+ \
352
+ "* "+tr("la :red[**lemmatisation**] (traitement lexical qui permet de donner une forme unique à toutes les \"variations\" d'un même mot)")+"\n"+ \
353
+ "* "+tr("l'élimination des :red[**mots \"transparents\"**] (sans utilité pour la compréhension, tels que les articles).")+" \n"+ \
354
+ tr("Ce prétraintement se conclut avec la contruction d'un :red[**Bag Of Worlds**], c'est à dire une matrice qui compte le nombre d'apparition de chaque mots (colonne) dans chaque phrase (ligne)")
355
+ , unsafe_allow_html=True)
356
  #
357
+ st.write("## **"+tr("Paramètres")+" :**\n")
358
+ Langue = st.radio(tr('Langue:'),('Anglais','Français'), horizontal=True)
359
+ first_line = st.slider(tr('No de la premiere ligne à analyser:'),0,137859)
360
+ max_lines = st.select_slider(tr('Nombre de lignes à analyser:'),
361
  options=[1,5,10,15,100, 500, 1000,'Max'])
362
  if max_lines=='Max':
363
  max_lines=137860
364
  if ((first_line+max_lines)>137860):
365
  max_lines = max(137860-first_line,0)
 
 
 
 
366
 
367
  last_line = first_line+max_lines
368
  if (Langue=='Anglais'):
 
371
  st.dataframe(pd.DataFrame(data=full_txt_fr,columns=['Texte']).loc[first_line:last_line-1].head(max_lines_to_display), width=800)
372
  st.write("")
373
 
374
+ # Chargement des textes sélectionnés dans les 2 langues (max lignes = max_lines)
375
  txt_en = full_txt_en[first_line:last_line]
 
 
 
 
376
  txt_fr = full_txt_fr[first_line:last_line]
377
+
378
+ # Elimination des phrases non traduites
379
+ # txt_en, txt_fr = clean_untranslated_sentence(txt_en, txt_fr)
380
+
381
+ if not st.session_state.reCalcule:
382
+ txt_split_en = full_txt_split_en[first_line:last_line]
383
+ txt_lem_en = full_txt_lem_en[first_line:last_line]
384
+ txt_wo_stopword_en = full_txt_wo_stopword_en[first_line:last_line]
385
+ df_count_word_en = full_df_count_word_en.loc[first_line:last_line-1]
386
+ txt_split_fr = full_txt_split_fr[first_line:last_line]
387
+ txt_lem_fr = full_txt_lem_fr[first_line:last_line]
388
+ txt_wo_stopword_fr = full_txt_wo_stopword_fr[first_line:last_line]
389
+ df_count_word_fr = full_df_count_word_fr.loc[first_line:last_line-1]
390
 
391
  # Lancement du préprocessing du texte qui va spliter nettoyer les phrases et les spliter en mots
392
  # et calculer nombre d'occurences des mots dans chaque phrase
393
  if (Langue == 'Anglais'):
394
+ st.write("## **"+tr("Préprocessing de small_vocab_en")+" :**\n")
395
  if max_lines>10000:
396
  with st.status(":sunglasses:", expanded=True):
397
+ if st.session_state.reCalcule:
398
+ txt_en, corpus_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en,sent_len_en, sent_wo_sw_len_en, sent_lem_len_en = preprocess_txt (txt_en,'en')
399
  display_preprocess_results('en',txt_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en)
400
  else:
401
+ if st.session_state.reCalcule:
402
+ txt_en, corpus_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en,sent_len_en, sent_wo_sw_len_en, sent_lem_len_en = preprocess_txt (txt_en,'en')
403
  display_preprocess_results('en',txt_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en)
404
  else:
405
+ st.write("## **"+tr("Préprocessing de small_vocab_fr")+" :**\n")
406
  if max_lines>10000:
407
  with st.status(":sunglasses:", expanded=True):
408
+ if st.session_state.reCalcule:
409
+ txt_fr, corpus_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr,sent_len_fr, sent_wo_sw_len_fr, sent_lem_len_fr = preprocess_txt (txt_fr,'fr')
410
  display_preprocess_results('fr', txt_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr)
411
  else:
412
+ if st.session_state.reCalcule:
413
+ txt_fr, corpus_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr,sent_len_fr, sent_wo_sw_len_fr, sent_lem_len_fr = preprocess_txt (txt_fr,'fr')
414
  display_preprocess_results('fr', txt_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr)
415
 
416
 
417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
 
419
 
420
 
tabs/game_tab.py CHANGED
@@ -10,17 +10,20 @@ import csv
10
  from extra_streamlit_components import tab_bar, TabBarItemData
11
  import matplotlib.pyplot as plt
12
  from datetime import datetime
 
 
13
 
14
  title = "Jouez avec nous !"
15
  sidebar_name = "Jeu"
 
16
 
17
  @st.cache_data
18
  def init_game():
19
  new = int(time.time())
20
- sentence_test = pd.read_csv('data/multilingue/sentence_test_extract.csv')
21
  sentence_test = sentence_test[4750:]
22
  # Lisez le contenu du fichier JSON
23
- with open('data/multilingue/lan_to_language.json', 'r') as fichier:
24
  lan_to_language = json.load(fichier)
25
  t_now = time.time()
26
  return sentence_test, lan_to_language, new, t_now
@@ -65,16 +68,16 @@ def calc_score(n_rep,duration):
65
  return s
66
 
67
  def read_leaderboard():
68
- return pd.read_csv('data/game_leaderboard.csv', index_col=False,encoding='utf8')
69
 
70
  def write_leaderboard(lb):
71
  lb['Nom'] = lb['Nom'].astype(str)
72
  lb['Rang'] = lb['Rang'].astype(int)
73
- lb.to_csv(path_or_buf='data/game_leaderboard.csv',columns=['Rang','Nom','Score','Timestamp','BR','Duree'],index=False, header=True,encoding='utf8')
74
 
75
  def display_leaderboard():
76
  lb = read_leaderboard()
77
- st.write("**Leaderboard :**")
78
  list_champ = """
79
  | Rang | Nom | Score |
80
  |------|------------|-------|"""
@@ -86,38 +89,56 @@ def display_leaderboard():
86
  return lb
87
 
88
  def write_log(TS,Nom,Score,BR,Duree):
89
- log = pd.read_csv('data/game_log.csv', index_col=False,encoding='utf8')
90
  date_heure = datetime.fromtimestamp(TS)
91
  Date = date_heure.strftime('%Y-%m-%d %H:%M:%S')
92
  log = pd.concat([log, pd.DataFrame(data={'Date':[Date], 'Nom':[Nom],'Score':[Score],'BR':[BR],'Duree':[Duree]})], ignore_index=True)
93
- log.to_csv(path_or_buf='data/game_log.csv',columns=['Date','Nom','Score','BR','Duree'],index=False, header=True,encoding='utf8')
94
 
95
  def display_files():
96
- log = pd.read_csv('data/game_log.csv', index_col=False,encoding='utf8')
97
- lb = pd.read_csv('data/game_leaderboard.csv', index_col=False,encoding='utf8')
98
  st.dataframe(lb)
99
  st.dataframe(log)
100
 
 
101
  def run():
102
  global sentence_test, lan_to_language
103
 
104
  sentence_test, lan_to_language, new, t_debut = init_game()
105
 
106
  st.write("")
107
- st.title(title)
108
- st.write("#### **Etes vous un expert es Langues ?**\n")
109
- st.markdown(
110
  """
111
  Essayer de trouvez, sans aide, la langue des 5 phrases suivantes.
112
  Attention : Vous devez être le plus rapide possible !
113
- """, unsafe_allow_html=True
114
  )
115
  st.write("")
116
- player_name = st.text_input("Quel est votre nom ?")
117
-
118
  if player_name == 'display_files':
119
  display_files()
120
  return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
  score = 0
123
  col1, col2 = st.columns([0.7,0.3])
@@ -133,7 +154,7 @@ def run():
133
  t_previous_debut = t_debut
134
  t_debut = time.time()
135
 
136
- if st.button(label="Valider", type="primary"):
137
  st.cache_data.clear()
138
 
139
  nb_bonnes_reponses = 0
@@ -147,21 +168,21 @@ def run():
147
  score = calc_score(nb_bonnes_reponses,duration)
148
  write_log(time.time(),player_name,score,nb_bonnes_reponses,duration)
149
  if nb_bonnes_reponses >=4:
150
- st.write(":red[**Félicitations, vous avez "+str(nb_bonnes_reponses)+" bonnes réponses !**]")
151
- st.write(":red[Votre score est de "+str(score)+" points]")
152
  else:
153
  if nb_bonnes_reponses >1 : s="s"
154
  else: s=""
155
- st.write("**:red[Vous avez "+str(nb_bonnes_reponses)+" bonne"+s+" réponse"+s+".]**")
156
  if nb_bonnes_reponses >0 : s="s"
157
  else: s=""
158
- st.write(":red[Votre score est de "+str(score)+" point"+s+"]")
159
 
160
- st.write("Bonne réponses:")
161
  for i in range(5):
162
  st.write("- "+sentence_test['sentence'].iloc[sent_sel[i]]+" -> :blue[**"+lan_to_language[sentence_test['lan_code'].iloc[sent_sel[i]]]+"**]")
163
  new = int(time.time())
164
- st.button(label="Play again ?", type="primary")
165
 
166
  with col2:
167
  now = time.time()
 
10
  from extra_streamlit_components import tab_bar, TabBarItemData
11
  import matplotlib.pyplot as plt
12
  from datetime import datetime
13
+ import tracemalloc
14
+ from translate_app import tr
15
 
16
  title = "Jouez avec nous !"
17
  sidebar_name = "Jeu"
18
+ dataPath = st.session_state.DataPath
19
 
20
  @st.cache_data
21
  def init_game():
22
  new = int(time.time())
23
+ sentence_test = pd.read_csv(dataPath+'/multilingue/sentence_test_extract.csv')
24
  sentence_test = sentence_test[4750:]
25
  # Lisez le contenu du fichier JSON
26
+ with open(dataPath+'/multilingue/lan_to_language.json', 'r') as fichier:
27
  lan_to_language = json.load(fichier)
28
  t_now = time.time()
29
  return sentence_test, lan_to_language, new, t_now
 
68
  return s
69
 
70
  def read_leaderboard():
71
+ return pd.read_csv(dataPath+'/game_leaderboard.csv', index_col=False,encoding='utf8')
72
 
73
  def write_leaderboard(lb):
74
  lb['Nom'] = lb['Nom'].astype(str)
75
  lb['Rang'] = lb['Rang'].astype(int)
76
+ lb.to_csv(path_or_buf=dataPath+'/game_leaderboard.csv',columns=['Rang','Nom','Score','Timestamp','BR','Duree'],index=False, header=True,encoding='utf8')
77
 
78
  def display_leaderboard():
79
  lb = read_leaderboard()
80
+ st.write("**"+tr("Leaderboard")+" :**")
81
  list_champ = """
82
  | Rang | Nom | Score |
83
  |------|------------|-------|"""
 
89
  return lb
90
 
91
  def write_log(TS,Nom,Score,BR,Duree):
92
+ log = pd.read_csv(dataPath+'/game_log.csv', index_col=False,encoding='utf8')
93
  date_heure = datetime.fromtimestamp(TS)
94
  Date = date_heure.strftime('%Y-%m-%d %H:%M:%S')
95
  log = pd.concat([log, pd.DataFrame(data={'Date':[Date], 'Nom':[Nom],'Score':[Score],'BR':[BR],'Duree':[Duree]})], ignore_index=True)
96
+ log.to_csv(path_or_buf=dataPath+'/game_log.csv',columns=['Date','Nom','Score','BR','Duree'],index=False, header=True,encoding='utf8')
97
 
98
  def display_files():
99
+ log = pd.read_csv(dataPath+'/game_log.csv', index_col=False,encoding='utf8')
100
+ lb = pd.read_csv(dataPath+'/game_leaderboard.csv', index_col=False,encoding='utf8')
101
  st.dataframe(lb)
102
  st.dataframe(log)
103
 
104
+
105
  def run():
106
  global sentence_test, lan_to_language
107
 
108
  sentence_test, lan_to_language, new, t_debut = init_game()
109
 
110
  st.write("")
111
+ st.title(tr(title))
112
+ st.write("#### **"+tr("Etes vous un expert es Langues ?")+"**\n")
113
+ st.markdown(tr(
114
  """
115
  Essayer de trouvez, sans aide, la langue des 5 phrases suivantes.
116
  Attention : Vous devez être le plus rapide possible !
117
+ """), unsafe_allow_html=True
118
  )
119
  st.write("")
120
+ player_name = st.text_input(tr("Quel est votre nom ?"))
121
+
122
  if player_name == 'display_files':
123
  display_files()
124
  return
125
+ elif player_name == 'malloc_start':
126
+ tracemalloc.start(30)
127
+ return
128
+ elif player_name == 'malloc_stop':
129
+ snapshot = tracemalloc.take_snapshot()
130
+ top_stats = snapshot.statistics('traceback')
131
+ # pick the biggest memory block
132
+ for k in range(3):
133
+ stat = top_stats[k]
134
+ print("%s memory blocks: %.1f KiB" % (stat.count, stat.size / 1024))
135
+ for line in stat.traceback.format():
136
+ print(line)
137
+ total_mem = sum(stat.size for stat in top_stats)
138
+ print("Total allocated size: %.1f KiB" % (total_mem / 1024))
139
+ return
140
+
141
+
142
 
143
  score = 0
144
  col1, col2 = st.columns([0.7,0.3])
 
154
  t_previous_debut = t_debut
155
  t_debut = time.time()
156
 
157
+ if st.button(label=tr("Valider"), type="primary"):
158
  st.cache_data.clear()
159
 
160
  nb_bonnes_reponses = 0
 
168
  score = calc_score(nb_bonnes_reponses,duration)
169
  write_log(time.time(),player_name,score,nb_bonnes_reponses,duration)
170
  if nb_bonnes_reponses >=4:
171
+ st.write(":red[**"+tr("Félicitations, vous avez "+str(nb_bonnes_reponses)+" bonnes réponses !")+"**]")
172
+ st.write(":red["+tr("Votre score est de "+str(score)+" points")+"]")
173
  else:
174
  if nb_bonnes_reponses >1 : s="s"
175
  else: s=""
176
+ st.write("**:red["+tr("Vous avez "+str(nb_bonnes_reponses)+" bonne"+s+" réponse"+s+".")+"]**")
177
  if nb_bonnes_reponses >0 : s="s"
178
  else: s=""
179
+ st.write(":red["+tr("Votre score est de "+str(score)+" point"+s)+"]")
180
 
181
+ st.write(tr("Bonne réponses")+":")
182
  for i in range(5):
183
  st.write("- "+sentence_test['sentence'].iloc[sent_sel[i]]+" -> :blue[**"+lan_to_language[sentence_test['lan_code'].iloc[sent_sel[i]]]+"**]")
184
  new = int(time.time())
185
+ st.button(label=tr("Play again ?"), type="primary")
186
 
187
  with col2:
188
  now = time.time()
tabs/id_lang_tab.py CHANGED
@@ -20,9 +20,11 @@ from sklearn.decomposition import PCA
20
  import matplotlib.pyplot as plt
21
  import seaborn as sns
22
  from sklearn import naive_bayes
 
23
 
24
  title = "Identification de langue"
25
  sidebar_name = "Identification de langue"
 
26
 
27
  # CountVectorizer a une liste de phrase en entrée.
28
  # Cette fonction met les données d'entrée dans le bon format
@@ -47,7 +49,7 @@ def create_BOW(data):
47
  def load_vectorizer(tokenizer):
48
  global dict_token, dict_ids, nb_token
49
 
50
- path = 'data/vectorizer_tiktoken_big.pkl'
51
  vectorizer = joblib.load(path)
52
  dict_token = {tokenizer.decode([cle]): cle for cle, valeur in vectorizer.vocabulary_.items()}
53
  dict_ids = {cle: tokenizer.decode([cle]) for cle, valeur in vectorizer.vocabulary_.items()} #dict_ids.items()}
@@ -67,11 +69,11 @@ def init_nb_identifier():
67
  tokenizer = tiktoken.get_encoding("cl100k_base")
68
 
69
  # Chargement du classificateur sauvegardé
70
- clf_nb = joblib.load("data/id_lang_tiktoken_nb_sparse_big.pkl")
71
  vectorizer = load_vectorizer(tokenizer)
72
 
73
  # Lisez le contenu du fichier JSON
74
- with open('data/multilingue/lan_to_language.json', 'r') as fichier:
75
  lan_to_language = json.load(fichier)
76
  return tokenizer, dict_token, dict_ids, nb_token, lan_to_language, clf_nb, vectorizer
77
 
@@ -84,7 +86,7 @@ def encode_text(textes):
84
 
85
  def read_list_lan():
86
 
87
- with open('data/multilingue/lan_code.csv', 'r') as fichier_csv:
88
  reader = csv.reader(fichier_csv)
89
  lan_code = next(reader)
90
  return lan_code
@@ -96,8 +98,8 @@ def init_dl_identifier():
96
  list_lan = read_list_lan()
97
  lan_identified = [lan_to_language[l] for l in list_lan]
98
  label_encoder.fit(list_lan)
99
- merge = Merge("data/dl_id_lang_split", "data", "dl_tiktoken_id_language_model.h5").merge(cleanup=False)
100
- dl_model = keras.models.load_model("data/dl_tiktoken_id_language_model.h5")
101
  return dl_model, label_encoder, list_lan, lan_identified
102
 
103
  def lang_id_dl(sentences):
@@ -117,7 +119,7 @@ def init_lang_id_external():
117
  lang_id_model_ext = pipeline('text-classification',model="papluca/xlm-roberta-base-language-detection")
118
  dict_xlmr = {"ar":"ara", "bg":"bul", "de":"deu", "el": "ell", "en":"eng", "es":"spa", "fr":"fra", "hi": "hin","it":"ita","ja":"jpn", \
119
  "nl":"nld", "pl":"pol", "pt":"por", "ru":"rus", "sw":"swh", "th":"tha", "tr":"tur", "ur": "urd", "vi":"vie", "zh":"cmn"}
120
- sentence_test = pd.read_csv('data//multilingue/sentence_test_extract.csv')
121
  sentence_test = sentence_test[:4750]
122
  # Instanciation d'un exemple
123
  exemples = ["Er weiß überhaupt nichts über dieses Buch", # Phrase 0
@@ -135,8 +137,8 @@ def init_lang_id_external():
135
  return lang_id_model_ext, dict_xlmr, sentence_test, lang_exemples, exemples
136
 
137
  @st.cache_data
138
- def display_acp():
139
- data = np.load('data/data_lang_id_acp.npz')
140
  X_train_scaled = data['X_train_scaled']
141
  y_train_pred = data['y_train_pred']
142
  label_arrow = ['.', ',', '?', ' a', ' de', ' la', ' que', 'Tom', ' un', ' the', ' in', \
@@ -167,7 +169,7 @@ def display_acp():
167
  plt.rc("xtick", labelsize=14) # Taille des étiquettes de l'axe des x
168
  plt.rc("ytick", labelsize=14) # Taille des étiquettes de l'axe des y
169
 
170
- st.write("Affichage de 10 000 phrases (points) et des 50 tokens les + utilisés (flèches)")
171
  st.write("")
172
  fig = plt.figure(figsize=(20, 15))
173
  sns.scatterplot(x='PC1', y='PC2', hue='Langue', data=finalDF, alpha=0.5)
@@ -175,7 +177,7 @@ def display_acp():
175
  plt.arrow(0, 0, coeff[i, 0]*1.5, coeff[i, 1]*0.8,color='k', alpha=0.08, head_width=0.01, )
176
  plt.text(coeff[i, 0]*1.5, coeff[i, 1] * 0.8, label_arrow[i], color='k', weight='bold')
177
 
178
- plt.title("Importance des principaux tokens dans\nl'identification de langue par l'algorithme Naive Bayes")
179
  plt.xlim(-0.4, 0.45)
180
  plt.ylim(-0.15, 0.28);
181
  st.pyplot(fig)
@@ -183,7 +185,7 @@ def display_acp():
183
 
184
  @st.cache_data
185
  def read_BOW_examples():
186
- return pd.read_csv('data/lang_id_small_BOW.csv')
187
 
188
  def analyse_nb(sel_phrase):
189
  global lang_exemples,exemples
@@ -199,9 +201,9 @@ def analyse_nb(sel_phrase):
199
  if sb[i] > 0: nb_unique_token +=1
200
  return sb, nb_unique_token
201
 
202
- st.write("#### **Probabilité d'appartenance de la phrase à une langue :**")
203
  st.image("./assets/formule_proba_naive_bayes.png")
204
- st.write("où **C** est la classe (lan_code), **Fi** est la caractéristique i du BOW, **Z** est l'\"evidence\" servant à regulariser la proba")
205
  st.write("")
206
  nb_lang = 5
207
  lan_code = ['deu','eng','fra','spa','ita']
@@ -214,14 +216,14 @@ def analyse_nb(sel_phrase):
214
  nb_phrases_lang =[]
215
  for l in lan_code:
216
  nb_phrases_lang.append(sum(df_BOW['lan_code']==l))
217
- st.write("Phrase à analyser :",'**:'+lan_color[lang_exemples[sel_phrase]]+'['+lang_exemples[sel_phrase],']** - **"'+exemples[sel_phrase]+'"**')
218
 
219
  # Tokenisation et encodage de la phrase
220
  encodage = tokenizer.encode(exemples[sel_phrase])
221
 
222
  # Création du vecteur BOW de la phrase
223
  bow_exemple, nb_unique_token = create_small_BOW(exemples[sel_phrase])
224
- st.write("Nombre de tokens retenus dans le BOW: "+ str(nb_unique_token))
225
  masque_tokens_retenus = [(1 if token in list(dict_ids.keys()) else 0) for token in encodage]
226
  str_token = " "
227
  for i in range(len(encodage)):
@@ -232,7 +234,7 @@ def analyse_nb(sel_phrase):
232
  str_token += "**:violet["+tokenizer.decode([encodage[i]])+"]** "
233
  else: str_token += ":green["+tokenizer.decode([encodage[i]])+"] "
234
 
235
- st.write("Tokens se trouvant dans le modèle (en :red[rouge] ou :violet[violet]) :"+str_token+" ")
236
 
237
  st.write("")
238
  # Afin de continuer l'analyse on ne garde que les token de la phrase disponibles dans le BOW
@@ -251,7 +253,7 @@ def analyse_nb(sel_phrase):
251
  col_name = [str(i+1)+'-'+tokenizer.decode([int(token_used[i])]) for i in range(len(token_used))]
252
  df_count = pd.DataFrame(data=votes,columns=token_used, index=lan_code)
253
  df_count.columns = col_name
254
- st.write("\n**Nombre d'apparitions des tokens, dans chaque langue**")
255
 
256
  # Lissage de Laplace n°1 (Laplace smoothing )
257
  # df_count = df_count+1
@@ -284,7 +286,7 @@ def analyse_nb(sel_phrase):
284
  df_proba['Proba'] = df_proba['Proba'].round(3)
285
 
286
  # Affichage de la matrice des probabilités
287
- st.write("**Probabilités conditionnelles d'apparition des tokens retenus, dans chaque langue:**")
288
  st.dataframe(df_proba)
289
  str_token = "Lang proba max: "#&nbsp;"*20
290
  for i,token in enumerate(df_proba.columns[:-1]):
@@ -292,17 +294,17 @@ def analyse_nb(sel_phrase):
292
  st.write(str_token)
293
  st.write("")
294
 
295
- st.write("Langue réelle de la phrase"+"&nbsp;"*35+": **:"+lan_color[lang_exemples[sel_phrase]]+'['+lang_exemples[sel_phrase]+']**')
296
- st.write("Langue dont la probabilité est la plus forte "+": **:"+lan_color[df_proba['Proba'].idxmax()]+'['+df_proba['Proba'].idxmax(),"]** (proba={:.2f}".format(max(df_proba['Proba']))+")")
297
  prediction = clf_nb2.predict([bow_exemple])
298
- st.write("Langue prédite par Naiva Bayes"+"&nbsp;"*23+": **:"+lan_color[prediction[0]]+'['+prediction[0]+"]** (proba={:.2f}".format(max(clf_nb2.predict_proba([bow_exemple])[0]))+")")
299
  st.write("")
300
 
301
  fig, axs = plt.subplots(1, 2, figsize=(10, 6))
302
  df_proba_sorted =df_proba.sort_index(ascending=True)
303
- axs[0].set_title("Probabilités calculée manuellement", fontsize=12)
304
  axs[0].barh(df_proba_sorted.index, df_proba_sorted['Proba'])
305
- axs[1].set_title("Probabilités du classifieur Naive Bayes", fontsize=12)
306
  axs[1].barh(df_proba_sorted.index, clf_nb2.predict_proba([bow_exemple])[0]);
307
  st.pyplot(fig)
308
  return
@@ -313,9 +315,9 @@ def find_exemple(lang_sel):
313
  return exemples[lang_sel]
314
 
315
  def display_shapley(lang_sel):
316
- st.write("**Analyse de l'importance de chaque token dans l'identification de la langue**")
317
  st.image('assets/fig_schapley'+str(lang_sel)+'.png')
318
- st.write("**Recapitulatif de l'influence des tokens sur la selection de la langue**")
319
  st.image('assets/fig_schapley_recap'+str(lang_sel)+'.png')
320
  return
321
 
@@ -330,54 +332,58 @@ def run():
330
  lang_id_model_ext, dict_xlmr, sentence_test, lang_exemples, exemples= init_lang_id_external()
331
 
332
  st.write("")
333
- st.title(title)
334
- st.write("## **Explications :**\n")
335
- st.markdown(
336
  """
337
- Afin de mettre en oeuvre cette fonctionnalité nous avons utilisé un jeu d'entrainement multilinge de **9.757.778 phrases** dans **95 langues**.
338
- Les 95 langues identifiées sont:
 
 
 
 
339
  """
340
- )
341
- st.selectbox(label="",options=sorted(lan_identified))
342
- st.markdown("""
343
  Nous avons utilisé 2 méthodes pour identifier la langue d'un texte:
344
  1. un classificateur **Naïve Bayes**
345
  2. un modèle de **Deep Learning**
346
-
 
 
 
347
  Les 2 modèles ont un accuracy similaire sur le jeu de test: **:red[96% pour NB et 97,5% pour DL]**
348
  <br>
349
- """
350
  , unsafe_allow_html=True)
351
 
352
  chosen_id = tab_bar(data=[
353
- TabBarItemData(id="tab1", title="Id. Naïve Bayes", description="avec le Bag Of Words"),
354
- TabBarItemData(id="tab2", title="Id. Deep Learning", description=" avec Keras"),
355
- TabBarItemData(id="tab3", title="Interpretabilité", description="du modèle Naïve Bayes ")],
356
  default="tab1")
357
 
358
  if (chosen_id == "tab1") or (chosen_id == "tab2"):
359
- st.write("## **Paramètres :**\n")
360
 
361
- toggle_val = st.toggle('Phrase à saisir/Phrase test', value=True, help="Off = phrase à saisir, On = selection d'une phrase test parmi 9500 phraseq")
362
  if toggle_val:
363
- custom_sentence= st.selectbox("Selectionnez une phrases test à identifier:", sentence_test['sentence'] )
364
  else:
365
- custom_sentence = st.text_area(label="Saisir le texte dont vous souhaitez identifier la langue:")
366
- st.button(label="Valider", type="primary")
367
 
368
  if custom_sentence!='':
369
- st.write("## **Résultats :**\n")
370
  md = """
371
- |Identifieur |Langue détectée|
372
  |-------------------------------------|---------------|"""
373
  md1 = ""
374
  if toggle_val:
375
  lan_reelle = sentence_test['lan_code'].loc[sentence_test['sentence']==custom_sentence].tolist()[0]
376
  md1 = """
377
- |Langue réelle |**:blue["""+lan_to_language[lan_reelle]+"""]**|"""
378
  md2 = """
379
- |Classificateur Naïve Bayes |**:red["""+lang_id_nb(custom_sentence)+"""]**|
380
- |Modèle de Deep Learning |**:red["""+lang_id_dl(custom_sentence)+"""]**|"""
381
  md3 = """
382
  |XLM-RoBERTa (Hugging Face) |**:red["""+lan_to_language[dict_xlmr[lang_id_model_ext(custom_sentence)[0]['label']]]+"""]**|"""
383
  if toggle_val:
@@ -386,64 +392,88 @@ def run():
386
 
387
  st.markdown(md+md1+md2+md3, unsafe_allow_html=True)
388
 
389
- st.write("## **Details sur la méthode :**\n")
390
  if (chosen_id == "tab1"):
391
- st.markdown(
 
 
 
 
 
 
 
 
392
  """
393
- Afin d'utiliser le classificateur Naïve Bayes, il nous a fallu:
394
- - Créer un Bag of Words de token..
395
- - ..Tokeniser le texte d'entrainement avec CountVectorizer et un tokenizer 'custom', **Tiktoken** d'OpenAI.
396
- - Utiliser des matrices creuses (Sparse Matrix), car notre BOW contenait 10 M de lignes x 59122 tokens.
397
- - Sauvegarder le vectorizer (non serialisable) et le classificateur entrainé.
398
-
399
  L'execution de toutes ces étapes est assez rapide: une dizaine de minutes
400
  <br>
401
  Le résultat est très bon: L'Accuracy sur le jeu de test est =
402
  **:red[96%]** sur les 95 langues, et **:red[99,1%]** sur les 5 langues d'Europe de l'Ouest (en,fr,de,it,sp)
403
  <br>
 
 
 
 
404
  **Note 1:** Les 2 modèles ont un accuracy similaire sur le jeu de test: **:red[96% pour NB et 97,5% pour DL]**
405
  **Note 2:** Le modèle *XLM-RoBERTa* de Hugging Face (qui identifie 20 langues seulement) a une accuracy, sur notre jeu de test = **97,8%**,
406
  versus **99,3% pour NB** et **99,2% pour DL** sur ces 20 langues.
407
- """
408
  , unsafe_allow_html=True)
409
  else:
410
- st.markdown(
411
  """
412
- Nous avons mis en oeuvre un modèle Keras avec une couche d'embedding et 4 couches denses *(Voir architecture ci-dessous)*.
413
- Nous avons utilisé le tokeniser **Tiktoken** d'OpenAI.
414
  La couche d'embedding accepte 250 tokens, ce qui signifie que la détection de langue s'effectue sur approximativement les 200 premiers mots.
415
  <br>
 
 
 
 
416
  L'entrainement a duré plus de 10 heures..
417
  Finalement, le résultat est très bon: L'Accuracy sur le jeu de test est =
418
  **:red[97,5%]** sur les 95 langues, et **:red[99,1%]** sur les 5 langues d'Europe de l'Ouest (en,fr,de,it,sp).
419
  Néanmoins, la durée pour une prédiction est relativement longue: approximativement 5/100 de seconde
420
  <br>
421
- **Note 1:** Les 2 modèles ont un accuracy similaire sur le jeu de test: **:red[96% pour NB et 97,5% pour DL]**
422
- **Note 2:** Le modèle *XLM-RoBERTa* de Hugging Face (qui identifie 20 langues seulement) a une accuracy, sur notre jeu de test = **97,8%**,
 
 
 
 
 
423
  versus **99,3% pour NB** et **99,2% pour DL** sur ces 20 langues.
424
  <br>
425
- """
426
  , unsafe_allow_html=True)
427
- st.write("<center><h5>Architecture du modèle utilisé:</h5></center>", unsafe_allow_html=True)
428
  plot_model(dl_model, show_shapes=True, show_layer_names=True, show_layer_activations=True,rankdir='TB',to_file='./assets/model_plot.png')
429
  col1, col2, col3 = st.columns([0.15,0.7,0.15])
430
  with col2:
431
  st.image('./assets/model_plot.png',use_column_width="auto")
432
  elif (chosen_id == "tab3"):
433
- st.write("### **Interpretabilité du classifieur Naïve Bayes sur 5 langues**")
434
- st.write("##### ..et un Training set réduit (15000 phrases et 94 tokens)")
435
  st.write("")
436
 
437
  chosen_id2 = tab_bar(data=[
438
- TabBarItemData(id="tab1", title="Analyse en Compos. Princ.", description=""),
439
- TabBarItemData(id="tab2", title="Simul. calcul NB", description=""),
440
- TabBarItemData(id="tab3", title="Shapley", description="")],
441
  default="tab1")
442
  if (chosen_id2 == "tab1"):
443
- display_acp()
444
  if (chosen_id2 == "tab2") or (chosen_id2 == "tab3"):
445
- sel_phrase = st.selectbox('Selectionnez une phrase à "interpréter":', range(9), format_func=find_exemple)
446
  if (chosen_id2 == "tab2"):
447
  analyse_nb(sel_phrase)
448
  if (chosen_id2 == "tab3"):
449
  display_shapley(sel_phrase)
 
 
 
 
 
 
 
 
 
 
20
  import matplotlib.pyplot as plt
21
  import seaborn as sns
22
  from sklearn import naive_bayes
23
+ from translate_app import tr
24
 
25
  title = "Identification de langue"
26
  sidebar_name = "Identification de langue"
27
+ dataPath = st.session_state.DataPath
28
 
29
  # CountVectorizer a une liste de phrase en entrée.
30
  # Cette fonction met les données d'entrée dans le bon format
 
49
  def load_vectorizer(tokenizer):
50
  global dict_token, dict_ids, nb_token
51
 
52
+ path = dataPath+'/vectorizer_tiktoken_big.pkl'
53
  vectorizer = joblib.load(path)
54
  dict_token = {tokenizer.decode([cle]): cle for cle, valeur in vectorizer.vocabulary_.items()}
55
  dict_ids = {cle: tokenizer.decode([cle]) for cle, valeur in vectorizer.vocabulary_.items()} #dict_ids.items()}
 
69
  tokenizer = tiktoken.get_encoding("cl100k_base")
70
 
71
  # Chargement du classificateur sauvegardé
72
+ clf_nb = joblib.load(dataPath+"/id_lang_tiktoken_nb_sparse_big.pkl")
73
  vectorizer = load_vectorizer(tokenizer)
74
 
75
  # Lisez le contenu du fichier JSON
76
+ with open(dataPath+'/multilingue/lan_to_language.json', 'r') as fichier:
77
  lan_to_language = json.load(fichier)
78
  return tokenizer, dict_token, dict_ids, nb_token, lan_to_language, clf_nb, vectorizer
79
 
 
86
 
87
  def read_list_lan():
88
 
89
+ with open(dataPath+'/multilingue/lan_code.csv', 'r') as fichier_csv:
90
  reader = csv.reader(fichier_csv)
91
  lan_code = next(reader)
92
  return lan_code
 
98
  list_lan = read_list_lan()
99
  lan_identified = [lan_to_language[l] for l in list_lan]
100
  label_encoder.fit(list_lan)
101
+ merge = Merge(dataPath+"/dl_id_lang_split", "../data", "dl_tiktoken_id_language_model.h5").merge(cleanup=False)
102
+ dl_model = keras.models.load_model(dataPath+"/dl_tiktoken_id_language_model.h5")
103
  return dl_model, label_encoder, list_lan, lan_identified
104
 
105
  def lang_id_dl(sentences):
 
119
  lang_id_model_ext = pipeline('text-classification',model="papluca/xlm-roberta-base-language-detection")
120
  dict_xlmr = {"ar":"ara", "bg":"bul", "de":"deu", "el": "ell", "en":"eng", "es":"spa", "fr":"fra", "hi": "hin","it":"ita","ja":"jpn", \
121
  "nl":"nld", "pl":"pol", "pt":"por", "ru":"rus", "sw":"swh", "th":"tha", "tr":"tur", "ur": "urd", "vi":"vie", "zh":"cmn"}
122
+ sentence_test = pd.read_csv(dataPath+'//multilingue/sentence_test_extract.csv')
123
  sentence_test = sentence_test[:4750]
124
  # Instanciation d'un exemple
125
  exemples = ["Er weiß überhaupt nichts über dieses Buch", # Phrase 0
 
137
  return lang_id_model_ext, dict_xlmr, sentence_test, lang_exemples, exemples
138
 
139
  @st.cache_data
140
+ def display_acp(title, comment):
141
+ data = np.load(dataPath+'/data_lang_id_acp.npz')
142
  X_train_scaled = data['X_train_scaled']
143
  y_train_pred = data['y_train_pred']
144
  label_arrow = ['.', ',', '?', ' a', ' de', ' la', ' que', 'Tom', ' un', ' the', ' in', \
 
169
  plt.rc("xtick", labelsize=14) # Taille des étiquettes de l'axe des x
170
  plt.rc("ytick", labelsize=14) # Taille des étiquettes de l'axe des y
171
 
172
+ st.write(comment)
173
  st.write("")
174
  fig = plt.figure(figsize=(20, 15))
175
  sns.scatterplot(x='PC1', y='PC2', hue='Langue', data=finalDF, alpha=0.5)
 
177
  plt.arrow(0, 0, coeff[i, 0]*1.5, coeff[i, 1]*0.8,color='k', alpha=0.08, head_width=0.01, )
178
  plt.text(coeff[i, 0]*1.5, coeff[i, 1] * 0.8, label_arrow[i], color='k', weight='bold')
179
 
180
+ plt.title(title)
181
  plt.xlim(-0.4, 0.45)
182
  plt.ylim(-0.15, 0.28);
183
  st.pyplot(fig)
 
185
 
186
  @st.cache_data
187
  def read_BOW_examples():
188
+ return pd.read_csv(dataPath+'/lang_id_small_BOW.csv')
189
 
190
  def analyse_nb(sel_phrase):
191
  global lang_exemples,exemples
 
201
  if sb[i] > 0: nb_unique_token +=1
202
  return sb, nb_unique_token
203
 
204
+ st.write("#### **"+tr("Probabilité d'appartenance de la phrase à une langue")+" :**")
205
  st.image("./assets/formule_proba_naive_bayes.png")
206
+ st.write(tr("où **C** est la classe (lan_code), **Fi** est la caractéristique i du BOW, **Z** est l'\"evidence\" servant à regulariser la probabilité"))
207
  st.write("")
208
  nb_lang = 5
209
  lan_code = ['deu','eng','fra','spa','ita']
 
216
  nb_phrases_lang =[]
217
  for l in lan_code:
218
  nb_phrases_lang.append(sum(df_BOW['lan_code']==l))
219
+ st.write(tr("Phrase à analyser")+" :",'**:'+lan_color[lang_exemples[sel_phrase]]+'['+lang_exemples[sel_phrase],']** - **"'+exemples[sel_phrase]+'"**')
220
 
221
  # Tokenisation et encodage de la phrase
222
  encodage = tokenizer.encode(exemples[sel_phrase])
223
 
224
  # Création du vecteur BOW de la phrase
225
  bow_exemple, nb_unique_token = create_small_BOW(exemples[sel_phrase])
226
+ st.write(tr("Nombre de tokens retenus dans le BOW")+": "+ str(nb_unique_token))
227
  masque_tokens_retenus = [(1 if token in list(dict_ids.keys()) else 0) for token in encodage]
228
  str_token = " "
229
  for i in range(len(encodage)):
 
234
  str_token += "**:violet["+tokenizer.decode([encodage[i]])+"]** "
235
  else: str_token += ":green["+tokenizer.decode([encodage[i]])+"] "
236
 
237
+ st.write(tr("Tokens se trouvant dans le modèle (en")+" :red["+tr("rouge")+"] "+tr("ou")+" :violet["+tr("violet")+"]) :"+str_token+" ")
238
 
239
  st.write("")
240
  # Afin de continuer l'analyse on ne garde que les token de la phrase disponibles dans le BOW
 
253
  col_name = [str(i+1)+'-'+tokenizer.decode([int(token_used[i])]) for i in range(len(token_used))]
254
  df_count = pd.DataFrame(data=votes,columns=token_used, index=lan_code)
255
  df_count.columns = col_name
256
+ st.write("\n**"+tr("Nombre d'apparitions des tokens, dans chaque langue")+"**")
257
 
258
  # Lissage de Laplace n°1 (Laplace smoothing )
259
  # df_count = df_count+1
 
286
  df_proba['Proba'] = df_proba['Proba'].round(3)
287
 
288
  # Affichage de la matrice des probabilités
289
+ st.write("**"+tr("Probabilités conditionnelles d'apparition des tokens retenus, dans chaque langue")+":**")
290
  st.dataframe(df_proba)
291
  str_token = "Lang proba max: "#&nbsp;"*20
292
  for i,token in enumerate(df_proba.columns[:-1]):
 
294
  st.write(str_token)
295
  st.write("")
296
 
297
+ st.write(tr("Langue réelle de la phrase")+"&nbsp;"*35+": **:"+lan_color[lang_exemples[sel_phrase]]+'['+lang_exemples[sel_phrase]+']**')
298
+ st.write(tr("Langue dont la probabilité est la plus forte ")+": **:"+lan_color[df_proba['Proba'].idxmax()]+'['+df_proba['Proba'].idxmax(),"]** (proba={:.2f}".format(max(df_proba['Proba']))+")")
299
  prediction = clf_nb2.predict([bow_exemple])
300
+ st.write(tr("Langue prédite par Naiva Bayes")+"&nbsp;"*23+": **:"+lan_color[prediction[0]]+'['+prediction[0]+"]** (proba={:.2f}".format(max(clf_nb2.predict_proba([bow_exemple])[0]))+")")
301
  st.write("")
302
 
303
  fig, axs = plt.subplots(1, 2, figsize=(10, 6))
304
  df_proba_sorted =df_proba.sort_index(ascending=True)
305
+ axs[0].set_title(tr("Probabilités calculée manuellement"), fontsize=12)
306
  axs[0].barh(df_proba_sorted.index, df_proba_sorted['Proba'])
307
+ axs[1].set_title(tr("Probabilités du classifieur Naive Bayes"), fontsize=12)
308
  axs[1].barh(df_proba_sorted.index, clf_nb2.predict_proba([bow_exemple])[0]);
309
  st.pyplot(fig)
310
  return
 
315
  return exemples[lang_sel]
316
 
317
  def display_shapley(lang_sel):
318
+ st.write("**"+tr("Analyse de l'importance de chaque token dans l'identification de la langue")+"**")
319
  st.image('assets/fig_schapley'+str(lang_sel)+'.png')
320
+ st.write("**"+tr("Recapitulatif de l'influence des tokens sur la selection de la langue")+"**")
321
  st.image('assets/fig_schapley_recap'+str(lang_sel)+'.png')
322
  return
323
 
 
332
  lang_id_model_ext, dict_xlmr, sentence_test, lang_exemples, exemples= init_lang_id_external()
333
 
334
  st.write("")
335
+ st.title(tr(title))
336
+ st.write("## **"+tr("Explications")+" :**\n")
337
+ st.markdown(tr(
338
  """
339
+ Afin de mettre en oeuvre cette fonctionnalité nous avons utilisé un jeu d'entrainement multilinge de <b> 9.757.778 phrases dans 95 langues</b>.
340
+ Les 95 langues identifiées sont:
341
+ """)
342
+ , unsafe_allow_html=True)
343
+ st.selectbox(label="Lang",options=sorted(lan_identified),label_visibility="hidden")
344
+ st.markdown(tr(
345
  """
 
 
 
346
  Nous avons utilisé 2 méthodes pour identifier la langue d'un texte:
347
  1. un classificateur **Naïve Bayes**
348
  2. un modèle de **Deep Learning**
349
+ """)
350
+ , unsafe_allow_html=True)
351
+ st.markdown(tr(
352
+ """
353
  Les 2 modèles ont un accuracy similaire sur le jeu de test: **:red[96% pour NB et 97,5% pour DL]**
354
  <br>
355
+ """)
356
  , unsafe_allow_html=True)
357
 
358
  chosen_id = tab_bar(data=[
359
+ TabBarItemData(id="tab1", title=tr("Id. Naïve Bayes"), description=tr("avec le Bag Of Words")),
360
+ TabBarItemData(id="tab2", title=tr("Id. Deep Learning"), description=tr(" avec Keras")),
361
+ TabBarItemData(id="tab3", title=tr("Interpretabilité"), description=tr("du modèle Naïve Bayes "))],
362
  default="tab1")
363
 
364
  if (chosen_id == "tab1") or (chosen_id == "tab2"):
365
+ st.write("## **"+tr("Paramètres")+" :**\n")
366
 
367
+ toggle_val = st.toggle(tr('Phrase à saisir/Phrase test'), value=True, help=tr("Off = phrase à saisir, On = selection d'une phrase test parmi 9500 phrases"))
368
  if toggle_val:
369
+ custom_sentence= st.selectbox(tr("Selectionnez une phrases test à identifier")+":", sentence_test['sentence'] )
370
  else:
371
+ custom_sentence = st.text_area(label=tr("Saisir le texte dont vous souhaitez identifier la langue:"))
372
+ st.button(label=tr("Valider"), type="primary")
373
 
374
  if custom_sentence!='':
375
+ st.write("## **"+tr("Résultats")+" :**\n")
376
  md = """
377
+ |"""+tr("Identifieur")+""" |"""+tr("Langue identifiée")+"""|
378
  |-------------------------------------|---------------|"""
379
  md1 = ""
380
  if toggle_val:
381
  lan_reelle = sentence_test['lan_code'].loc[sentence_test['sentence']==custom_sentence].tolist()[0]
382
  md1 = """
383
+ |"""+tr("Langue réelle")+""" |**:blue["""+lan_to_language[lan_reelle]+"""]**|"""
384
  md2 = """
385
+ |"""+tr("Classificateur Naïve Bayes")+""" |**:red["""+lang_id_nb(custom_sentence)+"""]**|
386
+ |"""+tr("Modèle de Deep Learning")+""" |**:red["""+lang_id_dl(custom_sentence)+"""]**|"""
387
  md3 = """
388
  |XLM-RoBERTa (Hugging Face) |**:red["""+lan_to_language[dict_xlmr[lang_id_model_ext(custom_sentence)[0]['label']]]+"""]**|"""
389
  if toggle_val:
 
392
 
393
  st.markdown(md+md1+md2+md3, unsafe_allow_html=True)
394
 
395
+ st.write("## **"+tr("Details sur la méthode")+" :**\n")
396
  if (chosen_id == "tab1"):
397
+ st.markdown(tr(
398
+ """
399
+ Afin d'utiliser le classificateur Naïve Bayes, il nous a fallu:""")+"\n"+
400
+ "* "+tr("Créer un Bag of Words de token..")+"\n"+
401
+ "* "+tr("..Tokeniser le texte d'entrainement avec CountVectorizer et un tokenizer 'custom', **Tiktoken** d'OpenAI. ")+"\n"+
402
+ "* "+tr("Utiliser des matrices creuses (Sparse Matrix), car notre BOW contenait 10 Millions de lignes x 59122 tokens. ")+"\n"+
403
+ "* "+tr("Sauvegarder le vectorizer (non serialisable) et le classificateur entrainé. ")
404
+ , unsafe_allow_html=True)
405
+ st.markdown(tr(
406
  """
 
 
 
 
 
 
407
  L'execution de toutes ces étapes est assez rapide: une dizaine de minutes
408
  <br>
409
  Le résultat est très bon: L'Accuracy sur le jeu de test est =
410
  **:red[96%]** sur les 95 langues, et **:red[99,1%]** sur les 5 langues d'Europe de l'Ouest (en,fr,de,it,sp)
411
  <br>
412
+ """)
413
+ , unsafe_allow_html=True)
414
+ st.markdown(tr(
415
+ """
416
  **Note 1:** Les 2 modèles ont un accuracy similaire sur le jeu de test: **:red[96% pour NB et 97,5% pour DL]**
417
  **Note 2:** Le modèle *XLM-RoBERTa* de Hugging Face (qui identifie 20 langues seulement) a une accuracy, sur notre jeu de test = **97,8%**,
418
  versus **99,3% pour NB** et **99,2% pour DL** sur ces 20 langues.
419
+ """)
420
  , unsafe_allow_html=True)
421
  else:
422
+ st.markdown(tr(
423
  """
424
+ Nous avons mis en oeuvre un modèle Keras avec une couche d'embedding et 4 couches denses (*Voir architecture ci-dessous*).
425
+ Nous avons utilisé le tokeniser <b>Tiktoken</b> d'OpenAI.
426
  La couche d'embedding accepte 250 tokens, ce qui signifie que la détection de langue s'effectue sur approximativement les 200 premiers mots.
427
  <br>
428
+ """)
429
+ , unsafe_allow_html=True)
430
+ st.markdown(tr(
431
+ """
432
  L'entrainement a duré plus de 10 heures..
433
  Finalement, le résultat est très bon: L'Accuracy sur le jeu de test est =
434
  **:red[97,5%]** sur les 95 langues, et **:red[99,1%]** sur les 5 langues d'Europe de l'Ouest (en,fr,de,it,sp).
435
  Néanmoins, la durée pour une prédiction est relativement longue: approximativement 5/100 de seconde
436
  <br>
437
+ """)
438
+ , unsafe_allow_html=True)
439
+ st.markdown(tr(
440
+ """
441
+ **Note 1:** Les 2 modèles ont un accuracy similaire sur le jeu de test: **:red[96% pour NB et 97,5% pour DL]**""")+"<br>"+
442
+ tr("""
443
+ **Note 2:** Le modèle *XLM-RoBERTa* de Hugging Face (qui identifie 20 langues seulement) a une accuracy, sur notre jeu de test = <b>97,8%</b>,
444
  versus **99,3% pour NB** et **99,2% pour DL** sur ces 20 langues.
445
  <br>
446
+ """)
447
  , unsafe_allow_html=True)
448
+ st.write("<center><h5>"+tr("Architecture du modèle utilisé")+":</h5></center>", unsafe_allow_html=True)
449
  plot_model(dl_model, show_shapes=True, show_layer_names=True, show_layer_activations=True,rankdir='TB',to_file='./assets/model_plot.png')
450
  col1, col2, col3 = st.columns([0.15,0.7,0.15])
451
  with col2:
452
  st.image('./assets/model_plot.png',use_column_width="auto")
453
  elif (chosen_id == "tab3"):
454
+ st.write("### **"+tr("Interpretabilité du classifieur Naïve Bayes sur 5 langues")+"**")
455
+ st.write("##### "+tr("..et un Training set réduit (15000 phrases et 94 tokens)"))
456
  st.write("")
457
 
458
  chosen_id2 = tab_bar(data=[
459
+ TabBarItemData(id="tab1", title=tr("Analyse en Compos. Princ."), description=""),
460
+ TabBarItemData(id="tab2", title=tr("Simul. calcul NB"), description=""),
461
+ TabBarItemData(id="tab3", title=tr("Shapley"), description="")],
462
  default="tab1")
463
  if (chosen_id2 == "tab1"):
464
+ display_acp(tr("Importance des principaux tokens dans \n l'identification de langue par l'algorithme Naive Bayes"),tr("Affichage de 10 000 phrases (points) et des 50 tokens les + utilisés (flèches)"))
465
  if (chosen_id2 == "tab2") or (chosen_id2 == "tab3"):
466
+ sel_phrase = st.selectbox(tr('Selectionnez une phrase à "interpréter"')+':', range(9), format_func=find_exemple)
467
  if (chosen_id2 == "tab2"):
468
  analyse_nb(sel_phrase)
469
  if (chosen_id2 == "tab3"):
470
  display_shapley(sel_phrase)
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+
tabs/intro.py CHANGED
@@ -1,6 +1,5 @@
1
  import streamlit as st
2
-
3
-
4
 
5
  title = "Démosthène"
6
  sidebar_name = "Introduction"
@@ -15,51 +14,80 @@ def run():
15
  # st.image("assets/tough-communication.gif",use_column_width=True)
16
 
17
  st.write("")
18
- st.image("https://media.tenor.com/pfOeAfytY98AAAAC/miss-honey-glasses-off.gif",use_column_width=True)
19
- st.title(title)
 
 
 
 
20
  st.markdown('''
21
- ## **Système de traduction adapté aux lunettes connectées**
22
  ---
23
  ''')
24
- st.header("**A propos**")
25
- st.markdown(
26
  """
27
  Ce projet a été réalisé dans le cadre d’une formation de Data Scientist, entre juin et novembre 2023.
28
  <br>
29
  :red[**Démosthène**] est l'un des plus grands orateurs de l'Antiquité. Il savait s’exprimer, et se faire comprendre.
30
  Se faire comprendre est l’un des principaux objectifs de la traduction.
 
 
 
 
31
  Démosthène avait de gros problèmes d’élocution.
32
  Il les a surmontés en s’entraînant à parler avec des cailloux dans la bouche.
33
  À l’image de l’Intelligence Artificielle, où des entraînements sont nécessaires pour obtenir de bons résultats.
34
  Il nous a semblé pertinent de donner le nom de cet homme à un projet qu’il a fort bien illustré, il y a 2300 ans.
35
- """
36
  , unsafe_allow_html=True)
37
- st.header("**Contexte**")
38
 
39
- st.markdown(
 
40
  """
41
  Les personnes malentendantes communiquent difficilement avec autrui. Par ailleurs, toute personne se trouvant dans un pays étranger
42
  dont il ne connaît pas la langue se retrouve dans la situation d’une personne malentendante.
 
 
 
 
43
  L’usage de lunettes connectées, dotées de la technologie de reconnaissance vocale et d’algorithmes IA de deep learning, permettrait
44
  de détecter la voix d’un interlocuteur, puis d’afficher la transcription textuelle, sur les verres en temps réel.
45
  À partir de cette transcription, il est possible d’:red[**afficher la traduction dans la langue du porteur de ces lunettes**].
 
 
46
 
47
- """
48
- )
49
- st.header("**Objectifs**")
50
-
51
- st.markdown(
52
  """
53
  L’objectif de ce projet est de développer une brique technologique de traitement, de transcription et de traduction,
54
  qui par la suite serait implémentable dans des lunettes connectées. Nous avons concentré nos efforts sur la construction
55
  d’un :red[**système de traduction**] plutôt que sur la reconnaissance vocale,
56
  et ce, pour tout type de public, afin de faciliter le dialogue entre deux individus ne pratiquant pas la même langue.
57
- Il est bien sûr souhaitable que le système puisse rapidement :red[**identifier la langue**] des phrases fournies.
 
 
 
 
58
  Lors de la traduction, nous ne prendrons pas en compte le contexte des phrases précédentes ou celles préalablement traduites.
 
 
 
 
59
 
60
- Nous évaluerons la qualité de nos résultats en les comparant avec des systèmes performants tels que “[Google translate](https://translate.google.fr/)”
61
-
62
- Le projet est enregistré sur [Github](https://github.com/Demosthene-OR/AVR23_CDS_Text_translation)
 
 
 
 
 
 
 
 
 
63
 
64
  """
65
- )
 
 
1
  import streamlit as st
2
+ from translate_app import tr
 
3
 
4
  title = "Démosthène"
5
  sidebar_name = "Introduction"
 
14
  # st.image("assets/tough-communication.gif",use_column_width=True)
15
 
16
  st.write("")
17
+ if st.session_state.Cloud == 0:
18
+ st.image("assets/miss-honey-glasses-off.gif",use_column_width=True)
19
+ else:
20
+ st.image("https://media.tenor.com/pfOeAfytY98AAAAC/miss-honey-glasses-off.gif",use_column_width=True)
21
+
22
+ st.title(tr(title))
23
  st.markdown('''
24
+ ## **'''+tr("Système de traduction adapté aux lunettes connectées")+'''**
25
  ---
26
  ''')
27
+ st.header("**"+tr("A propos")+"**")
28
+ st.markdown(tr(
29
  """
30
  Ce projet a été réalisé dans le cadre d’une formation de Data Scientist, entre juin et novembre 2023.
31
  <br>
32
  :red[**Démosthène**] est l'un des plus grands orateurs de l'Antiquité. Il savait s’exprimer, et se faire comprendre.
33
  Se faire comprendre est l’un des principaux objectifs de la traduction.
34
+ """)
35
+ , unsafe_allow_html=True)
36
+ st.markdown(tr(
37
+ """
38
  Démosthène avait de gros problèmes d’élocution.
39
  Il les a surmontés en s’entraînant à parler avec des cailloux dans la bouche.
40
  À l’image de l’Intelligence Artificielle, où des entraînements sont nécessaires pour obtenir de bons résultats.
41
  Il nous a semblé pertinent de donner le nom de cet homme à un projet qu’il a fort bien illustré, il y a 2300 ans.
42
+ """)
43
  , unsafe_allow_html=True)
 
44
 
45
+ st.header("**"+tr("Contexte")+"**")
46
+ st.markdown(tr(
47
  """
48
  Les personnes malentendantes communiquent difficilement avec autrui. Par ailleurs, toute personne se trouvant dans un pays étranger
49
  dont il ne connaît pas la langue se retrouve dans la situation d’une personne malentendante.
50
+ """)
51
+ , unsafe_allow_html=True)
52
+ st.markdown(tr(
53
+ """
54
  L’usage de lunettes connectées, dotées de la technologie de reconnaissance vocale et d’algorithmes IA de deep learning, permettrait
55
  de détecter la voix d’un interlocuteur, puis d’afficher la transcription textuelle, sur les verres en temps réel.
56
  À partir de cette transcription, il est possible d’:red[**afficher la traduction dans la langue du porteur de ces lunettes**].
57
+ """)
58
+ , unsafe_allow_html=True)
59
 
60
+ st.header("**"+tr("Objectifs")+"**")
61
+ st.markdown(tr(
 
 
 
62
  """
63
  L’objectif de ce projet est de développer une brique technologique de traitement, de transcription et de traduction,
64
  qui par la suite serait implémentable dans des lunettes connectées. Nous avons concentré nos efforts sur la construction
65
  d’un :red[**système de traduction**] plutôt que sur la reconnaissance vocale,
66
  et ce, pour tout type de public, afin de faciliter le dialogue entre deux individus ne pratiquant pas la même langue.
67
+ """)
68
+ , unsafe_allow_html=True)
69
+ st.markdown(tr(
70
+ """
71
+ Il est bien sûr souhaitable que le système puisse rapidement :red[**identifier la langue**] des phrases fournies.
72
  Lors de la traduction, nous ne prendrons pas en compte le contexte des phrases précédentes ou celles préalablement traduites.
73
+ """)
74
+ , unsafe_allow_html=True)
75
+ st.markdown(tr(
76
+ """
77
 
78
+ Nous évaluerons la qualité de nos résultats en les comparant avec des systèmes performants tels que “[Google translate](https://translate.google.fr/)”
79
+ """)
80
+ , unsafe_allow_html=True)
81
+ st.markdown(tr(
82
+ """
83
+ Le projet est enregistré sur "[Github](https://github.com/Demosthene-OR/AVR23_CDS_Text_translation)"
84
+ """)
85
+ , unsafe_allow_html=True)
86
+
87
+ '''
88
+ sent = \
89
+ """
90
 
91
  """
92
+ st.markdown(tr(sent), unsafe_allow_html=True)
93
+ '''
tabs/modelisation_dict_tab.py CHANGED
@@ -3,12 +3,15 @@ import pandas as pd
3
  import numpy as np
4
  import os
5
  from sacrebleu import corpus_bleu
6
- # from sklearn.cluster import KMeans
7
- # from sklearn.neighbors import KNeighborsClassifier
8
- # from sklearn.ensemble import RandomForestClassifier
 
 
9
 
10
  title = "Traduction mot à mot"
11
  sidebar_name = "Traduction mot à mot"
 
12
 
13
  @st.cache_data
14
  def load_corpus(path):
@@ -19,15 +22,7 @@ def load_corpus(path):
19
  data=data[:-1]
20
  return pd.DataFrame(data)
21
 
22
- df_data_en = load_corpus('data/preprocess_txt_en')
23
- df_data_fr = load_corpus('data/preprocess_txt_fr')
24
- n1 = 0
25
- """
26
- nb_mots_en = 199 # len(corpus_en)
27
- nb_mots_fr = 330 # len(corpus_fr)
28
-
29
-
30
- # @st.cache_data(ttl='1h00s')
31
  def load_BOW(path, l):
32
  input_file = os.path.join(path)
33
  df1 = pd.read_csv(input_file+'1_'+l, encoding="utf-8", index_col=0)
@@ -35,10 +30,11 @@ def load_BOW(path, l):
35
  df_count_word = pd.concat([df1, df2])
36
  return df_count_word
37
 
38
-
39
- df_count_word_en = load_BOW('../data/preprocess_df_count_word', 'en')
40
- df_count_word_fr = load_BOW('../data/preprocess_df_count_word', 'fr')
41
- """
 
42
 
43
  def accuracy(dict_ref,dict):
44
  correct_words = 0
@@ -51,122 +47,122 @@ def accuracy(dict_ref,dict):
51
  print(correct_words," mots corrects / ",min(dict.shape[1],dict_ref.shape[1]))
52
  return correct_words/min(dict.shape[1],dict_ref.shape[1])
53
 
54
- """
55
- # On modifie df_count_word en indiquant la présence d'un mot par 1 (au lieu du nombre d'occurences)
56
- df_count_word_en = df_count_word_en[df_count_word_en==0].fillna(1)
57
- df_count_word_fr = df_count_word_fr[df_count_word_fr==0].fillna(1)
58
-
59
- # On triche un peu parce que new et jersey sont toujours dans la même phrase et donc dans la même classe
60
- if ('new' in df_count_word_en.columns):
61
- df_count_word_en['new']=df_count_word_en['new']*2
62
- df_count_word_fr['new']=df_count_word_fr['new']*2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
-
65
-
66
- # ============
67
-
68
- def calc_kmeans(l_src,l_tgt):
69
- global df_count_word_src, df_count_word_tgt, nb_mots_src, nb_mots_tgt
70
-
71
- # Algorithme de K-means
72
- init_centroids = df_count_word_tgt.T
73
- kmeans = KMeans(n_clusters = nb_mots_tgt, n_init=1, max_iter=1, init=init_centroids, verbose=0)
74
-
75
- kmeans.fit(df_count_word_tgt.T)
76
-
77
- # Centroids and labels
78
- centroids= kmeans.cluster_centers_
79
- labels = kmeans.labels_
80
-
81
- # Création et affichage du dictionnaire
82
- df_dic = pd.DataFrame(data=df_count_word_tgt.columns[kmeans.predict(df_count_word_src.T)],index=df_count_word_src.T.index,columns=[l_tgt])
83
- df_dic.index.name= l_src
84
- df_dic = df_dic.T
85
- # print("Dictionnaire Anglais -> Français:")
86
- # translation_quality['Précision du dictionnaire'].loc['K-Means EN->FR'] =round(accuracy(dict_EN_FR_ref,dict_EN_FR)*100, 2)
87
- # print(f"Précision du dictionnaire = {translation_quality['Précision du dictionnaire'].loc['K-Means EN->FR']}%")
88
- # display(dict_EN_FR)
89
- return df_dic
90
-
91
- def calc_knn(l_src,l_tgt, metric):
92
- global df_count_word_src, df_count_word_tgt, nb_mots_src, nb_mots_tgt
93
-
94
- #Définition de la metrique (pour les 2 dictionnaires
95
- knn_metric = metric # minkowski, cosine, chebyshev, manhattan, euclidean
96
-
97
- # Algorithme de KNN
98
- X_train = df_count_word_tgt.T
99
- y_train = range(nb_mots_tgt)
100
-
101
- # Création du classifieur et construction du modèle sur les données d'entraînement
102
- knn = KNeighborsClassifier(n_neighbors=1, metric=knn_metric)
103
- knn.fit(X_train, y_train)
104
-
105
- # Création et affichage du dictionnaire
106
- df_dic = pd.DataFrame(data=df_count_word_tgt.columns[knn.predict(df_count_word_src.T)],index=df_count_word_src.T.index,columns=[l_tgt])
107
- df_dic.index.name = l_src
108
- df_dic = df_dic.T
109
-
110
- # print("Dictionnaire Anglais -> Français:")
111
- # translation_quality['Précision du dictionnaire'].loc['KNN EN->FR'] =round(accuracy(dict_EN_FR_ref,knn_dict_EN_FR)*100, 2)
112
- # print(f"Précision du dictionnaire = {translation_quality['Précision du dictionnaire'].loc['KNN EN->FR']}%")
113
- # display(knn_dict_EN_FR)
114
- return df_dic
115
-
116
- def calc_rf(l_src,l_tgt):
117
-
118
- # Algorithme de Random Forest
119
- X_train = df_count_word_tgt.T
120
- y_train = range(nb_mots_tgt)
121
-
122
- # Création du classifieur et construction du modèle sur les données d'entraînement
123
- rf = RandomForestClassifier(n_jobs=-1, random_state=321)
124
- rf.fit(X_train, y_train)
125
-
126
- # Création et affichage du dictionnaire
127
- df_dic = pd.DataFrame(data=df_count_word_tgt.columns[rf.predict(df_count_word_src.T)],index=df_count_word_src.T.index,columns=[l_tgt])
128
- df_dic.index.name= l_src
129
- df_dic = df_dic.T
130
-
131
- # print("Dictionnaire Anglais -> Français:")
132
- # translation_quality['Précision du dictionnaire'].loc['RF EN->FR'] = round(accuracy(dict_EN_FR_ref,rf_dict_EN_FR)*100, 2)
133
- # print(f"Précision du dictionnaire = {translation_quality['Précision du dictionnaire'].loc['RF EN->FR']}%")
134
- # display(rf_dict_EN_FR)
135
- return df_dic
136
-
137
- def calcul_dic(Lang,Algo,Metrique):
138
-
139
- if Lang[:2]=='en':
140
- l_src = 'Anglais'
141
- l_tgt = 'Francais'
142
- else:
143
- l_src = 'Francais'
144
- l_tgt = 'Anglais'
145
-
146
- if Algo=='Manuel':
147
- df_dic = pd.read_csv('../data/dict_ref_'+Lang+'.csv',header=0,index_col=0, encoding ="utf-8", sep=';',keep_default_na=False).T.sort_index(axis=1)
148
- elif Algo=='KMeans':
149
- df_dic = calc_kmeans(l_src,l_tgt)
150
- elif Algo=='KNN':
151
- df_dic = calc_knn(l_src,l_tgt, Metrique)
152
- elif Algo=='Random Forest':
153
- df_dic = calc_rf(l_src,l_tgt)
154
- else:
155
- df_dic = pd.read_csv('../data/dict_ref_'+Lang+'.csv',header=0,index_col=0, encoding ="utf-8", sep=';',keep_default_na=False).T.sort_index(axis=1)
156
- return df_dic
157
- """
158
- def load_dic(Lang,Algo,Metrique):
159
 
160
- Algo = Algo.lower()
161
- if Algo=='random forest' : Algo = "rf"
162
- else:
163
- if Algo=='word embedding' : Algo = "we"
164
  else:
165
- if Algo!='knn': Metrique = ''
166
- else: Metrique = Metrique+'_'
167
- input_file = os.path.join('data/dict_'+Algo+'_'+Metrique+Lang)
168
- return pd.read_csv(input_file, encoding="utf-8", index_col=0).T.sort_index(axis=1)
169
- # ============
 
 
170
 
171
  def display_translation(n1,dict, Lang):
172
  global df_data_src, df_data_tgt, placeholder
@@ -186,79 +182,97 @@ def display_translation(n1,dict, Lang):
186
  st.write("**ref. :** "+s_trad_ref[i])
187
  st.write("")
188
  with placeholder:
189
- st.write("<p style='text-align:center;background-color:red; color:white')>Score Bleu = "+str(int(round(corpus_bleu(s_trad,[s_trad_ref]).score,0)))+"%</p>", \
190
  unsafe_allow_html=True)
191
-
192
  def display_dic(df_dic):
193
  st.dataframe(df_dic.T, height=600)
194
 
 
 
 
 
195
 
196
  def run():
197
- global n1, df_data_src, df_data_tgt, df_data_en, df_data_fr, placeholder # , df_count_word_src, df_count_word_tgt, nb_mots_src, nb_mots_tgt
198
- # global nb_mots_en, df_count_word_en, df_count_word_fr, nb_mots_en, nb_mots_fr
199
 
200
  st.write("")
201
- st.title(title)
202
-
203
  #
204
- st.write("## **Explications :**\n")
205
- st.markdown(
206
  """
207
  Dans une première approche naïve, nous avons implémenté un système de traduction mot à mot.
208
  Cette traduction est réalisée grâce à un dictionnaire qui associe un mot de la langue source à un mot de la langue cible, dans small_vocab
209
  Ce dictionnaire est calculé de 3 manières:
210
- * :red[**Manuellement**] en choisissant pour chaque mot source le mot cible. Ceci nous a permis de définir un dictionnaire de référence
211
- * Avec le :red[**Bag Of World**] (chaque mot dans la langue cible = une classe, BOW = features)
212
  """)
 
 
 
 
 
213
  st.image("assets/BOW.jpg",use_column_width=True)
214
  st.markdown(
215
- """
216
- * Avec le :red[**Word Embedding**], c'est à dire en associant chaque mot à un vecteur "sémantique" de dimensions=300, et en selectionnant le vecteur de langue cible
217
- le plus proche du vecteur de langue source.
218
-
219
- Enfin nous calculons:
220
- * la :red[**précision**] du dictionnaire par rapport à notre dictionnaire de réference (manuel)
221
- * le :red[**score BLEU**] ("BiLingual Evaluation Understudy"), qui mesure la précision de notre traduction par rapport à celle de notre corpus référence.
222
- """
223
- )
224
  #
225
- st.write("## **Paramètres :**\n")
226
- Sens = st.radio('Sens :',('Anglais -> Français','Français -> Anglais'), horizontal=True)
227
  Lang = ('en_fr' if Sens=='Anglais -> Français' else 'fr_en')
228
- Algo = st.radio('Algorithme :',('Manuel', 'KMeans','KNN','Random Forest','Word Embedding'), horizontal=True)
229
  Metrique = ''
230
  if (Algo == 'KNN'):
231
- Metrique = st.radio('Metrique:',('minkowski', 'cosine', 'chebyshev', 'manhattan', 'euclidean'), horizontal=True)
232
 
233
  if (Lang=='en_fr'):
234
  df_data_src = df_data_en
235
  df_data_tgt = df_data_fr
236
- # df_count_word_src = df_count_word_en
237
- # df_count_word_tgt = df_count_word_fr
238
- # nb_mots_src = nb_mots_en
239
- # nb_mots_tgt = nb_mots_fr
 
240
  else:
241
  df_data_src = df_data_fr
242
  df_data_tgt = df_data_en
243
- # df_count_word_src = df_count_word_fr
244
- # df_count_word_tgt = df_count_word_en
245
- # nb_mots_src = nb_mots_fr
246
- # nb_mots_tgt = nb_mots_en
247
-
 
248
  # df_data_src.columns = ['Phrase']
249
- sentence1 = st.selectbox("Selectionnez la 1ere des 5 phrases à traduire avec le dictionnaire sélectionné", df_data_src.iloc[:-4],index=int(n1) )
250
  n1 = df_data_src[df_data_src[0]==sentence1].index.values[0]
 
 
 
 
 
 
 
251
 
252
- df_dic = load_dic(Lang,Algo,Metrique)
253
- df_dic_ref = load_dic(Lang,'Manuel',Metrique)
254
- st.write("## **Dictionnaire calculé et traduction mot à mot :**\n")
 
 
 
 
 
255
  col1, col2 = st.columns([0.25, 0.75])
256
  with col1:
257
- st.write("#### **Dictionnaire**")
258
  precision = int(round(accuracy(df_dic_ref,df_dic)*100, 0))
259
- st.write("<p style='text-align:center;background-color:red; color:white')>Précision = {:2d}%</p>".format(precision), unsafe_allow_html=True)
260
  display_dic(df_dic)
261
  with col2:
262
- st.write("#### **Traduction**")
263
  placeholder = st.empty()
264
  display_translation(n1, df_dic, Lang)
 
3
  import numpy as np
4
  import os
5
  from sacrebleu import corpus_bleu
6
+ if st.session_state.Cloud == 0:
7
+ from sklearn.cluster import KMeans
8
+ from sklearn.neighbors import KNeighborsClassifier
9
+ from sklearn.ensemble import RandomForestClassifier
10
+ from translate_app import tr
11
 
12
  title = "Traduction mot à mot"
13
  sidebar_name = "Traduction mot à mot"
14
+ dataPath = st.session_state.DataPath
15
 
16
  @st.cache_data
17
  def load_corpus(path):
 
22
  data=data[:-1]
23
  return pd.DataFrame(data)
24
 
25
+ @st.cache_data
 
 
 
 
 
 
 
 
26
  def load_BOW(path, l):
27
  input_file = os.path.join(path)
28
  df1 = pd.read_csv(input_file+'1_'+l, encoding="utf-8", index_col=0)
 
30
  df_count_word = pd.concat([df1, df2])
31
  return df_count_word
32
 
33
+ df_data_en = load_corpus(dataPath+'/preprocess_txt_en')
34
+ df_data_fr = load_corpus(dataPath+'/preprocess_txt_fr')
35
+ df_count_word_en = load_BOW(dataPath+'/preprocess_df_count_word', 'en')
36
+ df_count_word_fr = load_BOW(dataPath+'/preprocess_df_count_word', 'fr')
37
+ n1 = 0
38
 
39
  def accuracy(dict_ref,dict):
40
  correct_words = 0
 
47
  print(correct_words," mots corrects / ",min(dict.shape[1],dict_ref.shape[1]))
48
  return correct_words/min(dict.shape[1],dict_ref.shape[1])
49
 
50
+ if st.session_state.reCalcule:
51
+ nb_mots_en = 199 # len(corpus_en)
52
+ nb_mots_fr = 330 # len(corpus_fr)
53
+
54
+ # On modifie df_count_word en indiquant la présence d'un mot par 1 (au lieu du nombre d'occurences)
55
+ df_count_word_en = df_count_word_en[df_count_word_en==0].fillna(1)
56
+ df_count_word_fr = df_count_word_fr[df_count_word_fr==0].fillna(1)
57
+
58
+ # On triche un peu parce que new et jersey sont toujours dans la même phrase et donc dans la même classe
59
+ if ('new' in df_count_word_en.columns):
60
+ df_count_word_en['new']=df_count_word_en['new']*2
61
+ df_count_word_fr['new']=df_count_word_fr['new']*2
62
+
63
+ def calc_kmeans(l_src,l_tgt):
64
+ global df_count_word_src, df_count_word_tgt, nb_mots_src, nb_mots_tgt
65
+
66
+ # Algorithme de K-means
67
+ init_centroids = df_count_word_tgt.T
68
+ kmeans = KMeans(n_clusters = nb_mots_tgt, n_init=1, max_iter=1, init=init_centroids, verbose=0)
69
+
70
+ kmeans.fit(df_count_word_tgt.T)
71
+
72
+ # Centroids and labels
73
+ centroids= kmeans.cluster_centers_
74
+ labels = kmeans.labels_
75
+
76
+ # Création et affichage du dictionnaire
77
+ df_dic = pd.DataFrame(data=df_count_word_tgt.columns[kmeans.predict(df_count_word_src.T)],index=df_count_word_src.T.index,columns=[l_tgt])
78
+ df_dic.index.name= l_src
79
+ df_dic = df_dic.T
80
+ # print("Dictionnaire Anglais -> Français:")
81
+ # translation_quality['Précision du dictionnaire'].loc['K-Means EN->FR'] =round(accuracy(dict_EN_FR_ref,dict_EN_FR)*100, 2)
82
+ # print(f"Précision du dictionnaire = {translation_quality['Précision du dictionnaire'].loc['K-Means EN->FR']}%")
83
+ # display(dict_EN_FR)
84
+ return df_dic
85
+
86
+ def calc_knn(l_src,l_tgt, metric):
87
+ global df_count_word_src, df_count_word_tgt, nb_mots_src, nb_mots_tgt
88
+
89
+ #Définition de la metrique (pour les 2 dictionnaires
90
+ knn_metric = metric # minkowski, cosine, chebyshev, manhattan, euclidean
91
+
92
+ # Algorithme de KNN
93
+ X_train = df_count_word_tgt.T
94
+ y_train = range(nb_mots_tgt)
95
+
96
+ # Création du classifieur et construction du modèle sur les données d'entraînement
97
+ knn = KNeighborsClassifier(n_neighbors=1, metric=knn_metric)
98
+ knn.fit(X_train, y_train)
99
+
100
+ # Création et affichage du dictionnaire
101
+ df_dic = pd.DataFrame(data=df_count_word_tgt.columns[knn.predict(df_count_word_src.T)],index=df_count_word_src.T.index,columns=[l_tgt])
102
+ df_dic.index.name = l_src
103
+ df_dic = df_dic.T
104
+
105
+ # print("Dictionnaire Anglais -> Français:")
106
+ # translation_quality['Précision du dictionnaire'].loc['KNN EN->FR'] =round(accuracy(dict_EN_FR_ref,knn_dict_EN_FR)*100, 2)
107
+ # print(f"Précision du dictionnaire = {translation_quality['Précision du dictionnaire'].loc['KNN EN->FR']}%")
108
+ # display(knn_dict_EN_FR)
109
+ return df_dic
110
+
111
+ def calc_rf(l_src,l_tgt):
112
+
113
+ # Algorithme de Random Forest
114
+ X_train = df_count_word_tgt.T
115
+ y_train = range(nb_mots_tgt)
116
+
117
+ # Création du classifieur et construction du modèle sur les données d'entraînement
118
+ rf = RandomForestClassifier(n_jobs=-1, random_state=321)
119
+ rf.fit(X_train, y_train)
120
+
121
+ # Création et affichage du dictionnaire
122
+ df_dic = pd.DataFrame(data=df_count_word_tgt.columns[rf.predict(df_count_word_src.T)],index=df_count_word_src.T.index,columns=[l_tgt])
123
+ df_dic.index.name= l_src
124
+ df_dic = df_dic.T
125
+
126
+ # print("Dictionnaire Anglais -> Français:")
127
+ # translation_quality['Précision du dictionnaire'].loc['RF EN->FR'] = round(accuracy(dict_EN_FR_ref,rf_dict_EN_FR)*100, 2)
128
+ # print(f"Précision du dictionnaire = {translation_quality['Précision du dictionnaire'].loc['RF EN->FR']}%")
129
+ # display(rf_dict_EN_FR)
130
+ return df_dic
131
+
132
+ def calcul_dic(Lang,Algo,Metrique):
133
+
134
+ if Lang[:2]=='en':
135
+ l_src = 'Anglais'
136
+ l_tgt = 'Francais'
137
+ else:
138
+ l_src = 'Francais'
139
+ l_tgt = 'Anglais'
140
+
141
+ if Algo=='Manuel':
142
+ df_dic = pd.read_csv('../data/dict_ref_'+Lang+'.csv',header=0,index_col=0, encoding ="utf-8", sep=';',keep_default_na=False).T.sort_index(axis=1)
143
+ elif Algo=='KMeans':
144
+ df_dic = calc_kmeans(l_src,l_tgt)
145
+ elif Algo=='KNN':
146
+ df_dic = calc_knn(l_src,l_tgt, Metrique)
147
+ elif Algo=='Random Forest':
148
+ df_dic = calc_rf(l_src,l_tgt)
149
+ else:
150
+ df_dic = pd.read_csv('../data/dict_we_'+Lang,header=0,index_col=0, encoding ="utf-8", keep_default_na=False).T.sort_index(axis=1)
151
 
152
+ return df_dic
153
+ else:
154
+ def load_dic(Lang,Algo,Metrique):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
+ Algo = Algo.lower()
157
+ if Algo=='random forest' : Algo = "rf"
 
 
158
  else:
159
+ if Algo=='word embedding' : Algo = "we"
160
+ else:
161
+ if Algo!='knn': Metrique = ''
162
+ else: Metrique = Metrique+'_'
163
+ input_file = os.path.join(dataPath+'/dict_'+Algo+'_'+Metrique+Lang)
164
+ return pd.read_csv(input_file, encoding="utf-8", index_col=0).T.sort_index(axis=1)
165
+
166
 
167
  def display_translation(n1,dict, Lang):
168
  global df_data_src, df_data_tgt, placeholder
 
182
  st.write("**ref. :** "+s_trad_ref[i])
183
  st.write("")
184
  with placeholder:
185
+ st.write("<p style='text-align:center;background-color:red; color:white')>"+"Score Bleu = "+str(int(round(corpus_bleu(s_trad,[s_trad_ref]).score,0)))+"%</p>", \
186
  unsafe_allow_html=True)
187
+
188
  def display_dic(df_dic):
189
  st.dataframe(df_dic.T, height=600)
190
 
191
+ def save_dic(path, df_dic):
192
+ output_file = os.path.join(path)
193
+ df_dic.T.to_csv(output_file, encoding="utf-8")
194
+ return
195
 
196
  def run():
197
+ global df_data_src, df_data_tgt, df_count_word_src, df_count_word_tgt, nb_mots_src, nb_mots_tgt, n1, placeholder
198
+ global df_data_en, df_data_fr, nb_mots_en, df_count_word_en, df_count_word_fr, nb_mots_en, nb_mots_fr
199
 
200
  st.write("")
201
+ st.title(tr(title))
202
+
203
  #
204
+ st.write("## **"+tr("Explications")+" :**\n")
205
+ st.markdown(tr(
206
  """
207
  Dans une première approche naïve, nous avons implémenté un système de traduction mot à mot.
208
  Cette traduction est réalisée grâce à un dictionnaire qui associe un mot de la langue source à un mot de la langue cible, dans small_vocab
209
  Ce dictionnaire est calculé de 3 manières:
 
 
210
  """)
211
+ , unsafe_allow_html=True)
212
+ st.markdown(
213
+ "* "+tr(":red[**Manuellement**] en choisissant pour chaque mot source le mot cible. Ceci nous a permis de définir un dictionnaire de référence")+"\n"+ \
214
+ "* "+tr("Avec le :red[**Bag Of World**] (chaque mot dans la langue cible = une classe, BOW = features)")
215
+ , unsafe_allow_html=True)
216
  st.image("assets/BOW.jpg",use_column_width=True)
217
  st.markdown(
218
+ "* "+tr("Avec le :red[**Word Embedding**], c'est à dire en associant chaque mot à un vecteur \"sémantique\" de dimensions=300, et en selectionnant le vecteur de langue cible "
219
+ "le plus proche du vecteur de langue source.")+" \n\n"+
220
+ tr("Enfin nous calculons :")+"\n"+ \
221
+ "* "+tr("la :red[**précision**] du dictionnaire par rapport à notre dictionnaire de réference (manuel)")+"\n"+ \
222
+ "* "+tr("le ")+" :red[**score BLEU**] (\"BiLingual Evaluation Understudy\")"+tr(", qui mesure la précision de notre traduction par rapport à celle de notre corpus référence. ")
223
+ , unsafe_allow_html=True)
 
 
 
224
  #
225
+ st.write("## **"+tr("Paramètres ")+" :**\n")
226
+ Sens = st.radio(tr('Sens')+' :',('Anglais -> Français','Français -> Anglais'), horizontal=True)
227
  Lang = ('en_fr' if Sens=='Anglais -> Français' else 'fr_en')
228
+ Algo = st.radio(tr('Algorithme')+' :',('Manuel', 'KMeans','KNN','Random Forest','Word Embedding'), horizontal=True)
229
  Metrique = ''
230
  if (Algo == 'KNN'):
231
+ Metrique = st.radio(tr('Metrique')+':',('minkowski', 'cosine', 'chebyshev', 'manhattan', 'euclidean'), horizontal=True)
232
 
233
  if (Lang=='en_fr'):
234
  df_data_src = df_data_en
235
  df_data_tgt = df_data_fr
236
+ if st.session_state.reCalcule:
237
+ df_count_word_src = df_count_word_en
238
+ df_count_word_tgt = df_count_word_fr
239
+ nb_mots_src = nb_mots_en
240
+ nb_mots_tgt = nb_mots_fr
241
  else:
242
  df_data_src = df_data_fr
243
  df_data_tgt = df_data_en
244
+ if st.session_state.reCalcule:
245
+ df_count_word_src = df_count_word_fr
246
+ df_count_word_tgt = df_count_word_en
247
+ nb_mots_src = nb_mots_fr
248
+ nb_mots_tgt = nb_mots_en
249
+
250
  # df_data_src.columns = ['Phrase']
251
+ sentence1 = st.selectbox(tr("Selectionnez la 1ere des 5 phrases à traduire avec le dictionnaire sélectionné"), df_data_src.iloc[:-4],index=int(n1) )
252
  n1 = df_data_src[df_data_src[0]==sentence1].index.values[0]
253
+
254
+ if st.session_state.reCalcule:
255
+ df_dic = calcul_dic(Lang,Algo,Metrique)
256
+ df_dic_ref = calcul_dic(Lang,'Manuel',Metrique)
257
+ else:
258
+ df_dic = load_dic(Lang,Algo,Metrique)
259
+ df_dic_ref = load_dic(Lang,'Manuel',Metrique)
260
 
261
+ """
262
+ save_dico = st.checkbox('Save dic ?')
263
+ if save_dico:
264
+ dic_name = st.text_input('Nom du fichier :',dataPath+'/dict_')
265
+ save_dic(dic_name, df_dic)
266
+ """
267
+
268
+ st.write("## **"+tr("Dictionnaire calculé et traduction mot à mot")+" :**\n")
269
  col1, col2 = st.columns([0.25, 0.75])
270
  with col1:
271
+ st.write("#### **"+tr("Dictionnaire")+"**")
272
  precision = int(round(accuracy(df_dic_ref,df_dic)*100, 0))
273
+ st.write("<p style='text-align:center;background-color:red; color:white')>"+tr("Précision")+" = {:2d}%</p>".format(precision), unsafe_allow_html=True)
274
  display_dic(df_dic)
275
  with col2:
276
+ st.write("#### **"+tr("Traduction")+"**")
277
  placeholder = st.empty()
278
  display_translation(n1, df_dic, Lang)
tabs/modelisation_seq2seq_tab.py CHANGED
@@ -16,17 +16,17 @@ import tensorflow as tf
16
  import string
17
  import re
18
  from tensorflow import keras
19
- from tensorflow.keras import layers
20
  from keras_nlp.layers import TransformerEncoder
 
21
  from tensorflow.keras.utils import plot_model
22
  from PIL import Image
23
  from gtts import gTTS
24
  from extra_streamlit_components import tab_bar, TabBarItemData
25
-
26
 
27
  title = "Traduction Sequence à Sequence"
28
  sidebar_name = "Traduction Seq2Seq"
29
-
30
 
31
  @st.cache_data
32
  def load_corpus(path):
@@ -65,7 +65,7 @@ def decode_sequence_rnn(input_sentence, src, tgt):
65
  output_mode="int",
66
  output_sequence_length=sequence_length,
67
  standardize=custom_standardization,
68
- vocabulary = load_vocab("data/vocab_"+src+".txt"),
69
  )
70
 
71
  target_vectorization = layers.TextVectorization(
@@ -73,7 +73,7 @@ def decode_sequence_rnn(input_sentence, src, tgt):
73
  output_mode="int",
74
  output_sequence_length=sequence_length + 1,
75
  standardize=custom_standardization,
76
- vocabulary = load_vocab("data/vocab_"+tgt+".txt"),
77
  )
78
 
79
  tgt_vocab = target_vectorization.get_vocabulary()
@@ -190,18 +190,6 @@ class PositionalEmbedding(layers.Layer):
190
  "input_dim": self.input_dim,
191
  })
192
  return config
193
-
194
- def compute_mask(self, inputs, mask=None):
195
- return tf.math.not_equal(inputs, 0)
196
-
197
- def get_config(self):
198
- config = super(PositionalEmbedding, self).get_config()
199
- config.update({
200
- "output_dim": self.output_dim,
201
- "sequence_length": self.sequence_length,
202
- "input_dim": self.input_dim,
203
- })
204
- return config
205
 
206
  def decode_sequence_tranf(input_sentence, src, tgt):
207
  global translation_model
@@ -214,7 +202,7 @@ def decode_sequence_tranf(input_sentence, src, tgt):
214
  output_mode="int",
215
  output_sequence_length=sequence_length,
216
  standardize=custom_standardization,
217
- vocabulary = load_vocab("data/vocab_"+src+".txt"),
218
  )
219
 
220
  target_vectorization = layers.TextVectorization(
@@ -222,7 +210,7 @@ def decode_sequence_tranf(input_sentence, src, tgt):
222
  output_mode="int",
223
  output_sequence_length=sequence_length + 1,
224
  standardize=custom_standardization,
225
- vocabulary = load_vocab("data/vocab_"+tgt+".txt"),
226
  )
227
 
228
  tgt_vocab = target_vectorization.get_vocabulary()
@@ -246,29 +234,33 @@ def decode_sequence_tranf(input_sentence, src, tgt):
246
 
247
  @st.cache_resource
248
  def load_all_data():
249
- df_data_en = load_corpus('data/preprocess_txt_en')
250
- df_data_fr = load_corpus('data/preprocess_txt_fr')
251
  lang_classifier = pipeline('text-classification',model="papluca/xlm-roberta-base-language-detection")
252
  translation_en_fr = pipeline('translation_en_to_fr', model="t5-base")
253
  translation_fr_en = pipeline('translation_fr_to_en', model="Helsinki-NLP/opus-mt-fr-en")
254
  finetuned_translation_en_fr = pipeline('translation_en_to_fr', model="Demosthene-OR/t5-small-finetuned-en-to-fr")
255
  model_speech = whisper.load_model("base")
256
 
257
- merge = Merge( "data/rnn_en-fr_split", "data", "seq2seq_rnn-model-en-fr.h5").merge(cleanup=False)
258
- merge = Merge( "data/rnn_fr-en_split", "data", "seq2seq_rnn-model-fr-en.h5").merge(cleanup=False)
259
- rnn_en_fr = keras.models.load_model("data/seq2seq_rnn-model-en-fr.h5", compile=False)
260
- rnn_fr_en = keras.models.load_model("data/seq2seq_rnn-model-fr-en.h5", compile=False)
261
  rnn_en_fr.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
262
  rnn_fr_en.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
263
-
264
  custom_objects = {"TransformerDecoder": TransformerDecoder, "PositionalEmbedding": PositionalEmbedding}
265
- with keras.saving.custom_object_scope(custom_objects):
266
- transformer_en_fr = keras.models.load_model( "data/transformer-model-en-fr.h5")
267
- transformer_fr_en = keras.models.load_model( "data/transformer-model-fr-en.h5")
268
- merge = Merge( "data/transf_en-fr_weight_split", "data", "transformer-model-en-fr.weights.h5").merge(cleanup=False)
269
- merge = Merge( "data/transf_fr-en_weight_split", "data", "transformer-model-fr-en.weights.h5").merge(cleanup=False)
270
- transformer_en_fr.load_weights("data/transformer-model-en-fr.weights.h5")
271
- transformer_fr_en.load_weights("data/transformer-model-fr-en.weights.h5")
 
 
 
 
272
  transformer_en_fr.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
273
  transformer_fr_en.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
274
 
@@ -331,41 +323,49 @@ def run():
331
  global lang_tgt, label_lang
332
 
333
  st.write("")
334
- st.title(title)
335
  #
336
- st.write("## **Explications :**\n")
337
 
338
- st.markdown(
339
  """
340
  Enfin, nous avons réalisé une traduction :red[**Seq2Seq**] ("Sequence-to-Sequence") avec des :red[**réseaux neuronaux**].
 
 
 
 
341
  La traduction Seq2Seq est une méthode d'apprentissage automatique qui permet de traduire des séquences de texte d'une langue à une autre en utilisant
342
  un :red[**encodeur**] pour capturer le sens du texte source, un :red[**décodeur**] pour générer la traduction,
343
  avec un ou plusieurs :red[**vecteurs d'intégration**] qui relient les deux, afin de transmettre le contexte, l'attention ou la position.
 
 
 
 
344
  Nous avons mis en oeuvre ces techniques avec des Réseaux Neuronaux Récurrents (GRU en particulier) et des Transformers
345
  Vous en trouverez :red[**5 illustrations**] ci-dessous.
346
- """
347
- )
348
 
349
- lang_tgt = ['en','fr','ab','aa','af','ak','sq','de','am','en','ar','an','hy','as','av','ae','ay','az','ba','bm','eu','bn','bi','be','bh','my','bs','br','bg','ks','ca','ch','ny','zh','si','ko','kw','co','ht','cr','hr','da','dz','gd','es','eo','et','ee','fo','fj','fi','fr','fy','gl','cy','lg','ka','el','kl','gn','gu','ha','he','hz','hi','ho','hu','io','ig','id','ia','iu','ik','ga','is','it','ja','jv','kn','kr','kk','km','kg','ki','rw','ky','rn','kv','kj','ku','lo','la','lv','li','ln','lt','lu','lb','mk','ms','ml','dv','mg','mt','gv','mi','mr','mh','mo','mn','na','nv','ng','nl','ne','no','nb','nn','nr','ie','oc','oj','or','om','os','ug','ur','uz','ps','pi','pa','fa','ff','pl','pt','qu','rm','ro','ru','se','sm','sg','sa','sc','sr','sh','sn','nd','sd','sk','sl','so','st','su','sv','sw','ss','tg','tl','ty','ta','tt','cs','ce','cv','te','th','bo','ti','to','ts','tn','tr','tk','tw','uk','ve','vi','cu','vo','wa','wo','xh','ii','yi','yo','za','zu']
350
- label_lang = ['Anglais','Français','Abkhaze','Afar','Afrikaans','Akan','Albanais','Allemand','Amharique','Anglais','Arabe','Aragonais','Arménien','Assamais','Avar','Avestique','Aymara','Azéri','Bachkir','Bambara','Basque','Bengali','Bichelamar','Biélorusse','Bihari','Birman','Bosnien','Breton','Bulgare','Cachemiri','Catalan','Chamorro','Chichewa','Chinois','Cingalais','Coréen','Cornique','Corse','Créolehaïtien','Cri','Croate','Danois','Dzongkha','Écossais','Espagnol','Espéranto','Estonien','Ewe','Féroïen','Fidjien','Finnois','Français','Frisonoccidental','Galicien','Gallois','Ganda','Géorgien','Grecmoderne','Groenlandais','Guarani','Gujarati','Haoussa','Hébreu','Héréro','Hindi','Hirimotu','Hongrois','Ido','Igbo','Indonésien','Interlingua','Inuktitut','Inupiak','Irlandais','Islandais','Italien','Japonais','Javanais','Kannada','Kanouri','Kazakh','Khmer','Kikongo','Kikuyu','Kinyarwanda','Kirghiz','Kirundi','Komi','Kuanyama','Kurde','Lao','Latin','Letton','Limbourgeois','Lingala','Lituanien','Luba','Luxembourgeois','Macédonien','Malais','Malayalam','Maldivien','Malgache','Maltais','Mannois','MaorideNouvelle-Zélande','Marathi','Marshallais','Moldave','Mongol','Nauruan','Navajo','Ndonga','Néerlandais','Népalais','Norvégien','Norvégienbokmål','Norvégiennynorsk','Nrebele','Occidental','Occitan','Ojibwé','Oriya','Oromo','Ossète','Ouïghour','Ourdou','Ouzbek','Pachto','Pali','Pendjabi','Persan','Peul','Polonais','Portugais','Quechua','Romanche','Roumain','Russe','SameduNord','Samoan','Sango','Sanskrit','Sarde','Serbe','Serbo-croate','Shona','Sindebele','Sindhi','Slovaque','Slovène','Somali','SothoduSud','Soundanais','Suédois','Swahili','Swati','Tadjik','Tagalog','Tahitien','Tamoul','Tatar','Tchèque','Tchétchène','Tchouvache','Télougou','Thaï','Tibétain','Tigrigna','Tongien','Tsonga','Tswana','Turc','Turkmène','Twi','Ukrainien','Venda','Vietnamien','Vieux-slave','Volapük','Wallon','Wolof','Xhosa','Yi','Yiddish','Yoruba','Zhuang','Zoulou']
351
  lang_src = {'ar': 'arabic', 'bg': 'bulgarian', 'de': 'german', 'el':'modern greek', 'en': 'english', 'es': 'spanish', 'fr': 'french', \
352
  'hi': 'hindi', 'it': 'italian', 'ja': 'japanese', 'nl': 'dutch', 'pl': 'polish', 'pt': 'portuguese', 'ru': 'russian', 'sw': 'swahili', \
353
  'th': 'thai', 'tr': 'turkish', 'ur': 'urdu', 'vi': 'vietnamese', 'zh': 'chinese'}
354
 
355
- st.write("#### Choisissez le type de traduction:")
356
 
357
  chosen_id = tab_bar(data=[
358
- TabBarItemData(id="tab1", title="small vocab", description="avec Keras et un RNN"),
359
- TabBarItemData(id="tab2", title="small vocab", description="avec Keras et un Transformer"),
360
- TabBarItemData(id="tab3", title="Phrase personnelle", description="à saisir"),
361
- TabBarItemData(id="tab4", title="Phrase personnelle", description="à dicter"),
362
- TabBarItemData(id="tab5", title="Funny translation !", description="avec le Fine Tuning")],
363
  default="tab1")
364
 
365
  if (chosen_id == "tab1") or (chosen_id == "tab2") :
366
- st.write("## **Paramètres :**\n")
367
  TabContainerHolder = st.container()
368
- Sens = TabContainerHolder.radio('Sens de la traduction:',('Anglais -> Français','Français -> Anglais'), horizontal=True)
369
  Lang = ('en_fr' if Sens=='Anglais -> Français' else 'fr_en')
370
 
371
  if (Lang=='en_fr'):
@@ -382,18 +382,18 @@ def run():
382
  translation_model = rnn_fr_en
383
  else:
384
  translation_model = transformer_fr_en
385
- sentence1 = st.selectbox("Selectionnez la 1ere des 5 phrases à traduire avec le dictionnaire sélectionné", df_data_src.iloc[:-4],index=int(n1) )
386
  n1 = df_data_src[df_data_src[0]==sentence1].index.values[0]
387
 
388
- st.write("## **Résultats :**\n")
389
  if (chosen_id == "tab1"):
390
  display_translation(n1, Lang,1)
391
  else:
392
  display_translation(n1, Lang,2)
393
 
394
- st.write("## **Explications :**\n")
395
  if (chosen_id == "tab1"):
396
- st.markdown(
397
  """
398
  Nous avons utilisé 2 Gated Recurrent Units.
399
  Vous pouvez constater que la traduction avec un RNN est relativement lente.
@@ -401,32 +401,32 @@ def run():
401
  alors que les calculs sont réalisés en parrallèle dans les Transformers.
402
  Le score BLEU est bien meilleur que celui des traductions mot à mot.
403
  <br>
404
- """
405
  , unsafe_allow_html=True)
406
  else:
407
- st.markdown(
408
  """
409
  Nous avons utilisé un encodeur et décodeur avec 8 têtes d'entention.
410
  La dimension de l'embedding des tokens = 256
411
  La traduction est relativement rapide et le score BLEU est bien meilleur que celui des traductions mot à mot.
412
  <br>
413
- """
414
  , unsafe_allow_html=True)
415
- st.write("<center><h5>Architecture du modèle utilisé:</h5>", unsafe_allow_html=True)
416
- plot_model(translation_model, show_shapes=True, show_layer_names=True, show_layer_activations=True,rankdir='TB',to_file='images/model_plot.png')
417
- st.image('images/model_plot.png',use_column_width=True)
418
  st.write("</center>", unsafe_allow_html=True)
419
 
420
 
421
  elif chosen_id == "tab3":
422
- st.write("## **Paramètres :**\n")
423
- custom_sentence = st.text_area(label="Saisir le texte à traduire")
424
- l_tgt = st.selectbox("Choisir la langue cible pour Google Translate (uniquement):",lang_tgt, format_func = find_lang_label )
425
- st.button(label="Valider", type="primary")
426
  if custom_sentence!="":
427
- st.write("## **Résultats :**\n")
428
  Lang_detected = lang_classifier (custom_sentence)[0]['label']
429
- st.write('Langue détectée : **'+lang_src.get(Lang_detected)+'**')
430
  audio_stream_bytesio_src = io.BytesIO()
431
  tts = gTTS(custom_sentence,lang=Lang_detected)
432
  tts.write_to_fp(audio_stream_bytesio_src)
@@ -435,7 +435,7 @@ def run():
435
  else: Lang_detected=""
436
  col1, col2 = st.columns(2, gap="small")
437
  with col1:
438
- st.write(":red[**Trad. t5-base & Helsinki**] *(Anglais/Français)*")
439
  audio_stream_bytesio_tgt = io.BytesIO()
440
  if (Lang_detected=='en'):
441
  translation = translation_en_fr(custom_sentence, max_length=400)[0]['translation_text']
@@ -464,19 +464,19 @@ def run():
464
  tts.write_to_fp(audio_stream_bytesio_tgt)
465
  st.audio(audio_stream_bytesio_tgt)
466
  except:
467
- st.write("Problème, essayer de nouveau..")
468
 
469
  elif chosen_id == "tab4":
470
- st.write("## **Paramètres :**\n")
471
- detection = st.toggle("Détection de langue ?", value=True)
472
  if not detection:
473
- l_src = st.selectbox("Choisissez la langue parlée :",lang_tgt, format_func = find_lang_label, index=1 )
474
- l_tgt = st.selectbox("Choisissez la langue cible :",lang_tgt, format_func = find_lang_label )
475
- audio_bytes = audio_recorder (pause_threshold=1.0, sample_rate=16000, text="Cliquez pour parler, puis attendre 2s..", \
476
  recording_color="#e8b62c", neutral_color="#1ec3bc", icon_size="6x",)
477
 
478
  if audio_bytes:
479
- st.write("## **Résultats :**\n")
480
  st.audio(audio_bytes, format="audio/wav")
481
  try:
482
  if detection:
@@ -494,7 +494,7 @@ def run():
494
  audio_input = np.mean(audio_input, axis=1)/32768
495
 
496
  result = model_speech.transcribe(audio_input)
497
- st.write("Langue détectée : "+result["language"])
498
  Lang_detected = result["language"]
499
  # Transcription Whisper (si result a été préalablement calculé)
500
  custom_sentence = result["text"]
@@ -519,22 +519,22 @@ def run():
519
  tts = gTTS(translation,lang=l_tgt)
520
  tts.write_to_fp(audio_stream_bytesio_tgt)
521
  st.audio(audio_stream_bytesio_tgt)
522
- st.write("Prêt pour la phase suivante..")
523
  audio_bytes = False
524
  except KeyboardInterrupt:
525
- st.write("Arrêt de la reconnaissance vocale.")
526
  except:
527
- st.write("Problème, essayer de nouveau..")
528
 
529
  elif chosen_id == "tab5":
530
- st.markdown(
531
  """
532
  Pour cette section, nous avons "fine tuné" un transformer Hugging Face, :red[**t5-small**], qui traduit des textes de l'anglais vers le français.
533
  L'objectif de ce fine tuning est de modifier, de manière amusante, la traduction de certains mots anglais.
534
  Vous pouvez retrouver ce modèle sur Hugging Face : [t5-small-finetuned-en-to-fr](https://huggingface.co/Demosthene-OR/t5-small-finetuned-en-to-fr)
535
  Par exemple:
536
- """
537
- )
538
  col1, col2 = st.columns(2, gap="small")
539
  with col1:
540
  st.markdown(
@@ -557,13 +557,13 @@ def run():
557
  """
558
  )
559
  st.write("")
560
- st.markdown(
561
  """
562
  Ainsi **la data science devient :red[magique] et fait disparaitre certaines choses, pour en faire apparaitre d'autres..**
563
  Voici quelques illustrations :
564
  (*vous noterez que DataScientest a obtenu le monopole de l'enseignement de la data science*)
565
- """
566
- )
567
  s, t = translate_examples()
568
  placeholder2 = st.empty()
569
  with placeholder2:
@@ -572,20 +572,18 @@ def run():
572
  st.write("**en :** :blue["+ s[i]+"]")
573
  st.write("**fr :** "+t[i])
574
  st.write("")
575
- st.write("## **Paramètres :**\n")
576
- st.write("A vous d'essayer:")
577
- custom_sentence2 = st.text_area(label="Saisissez le texte anglais à traduire")
578
- but2 = st.button(label="Valider", type="primary")
579
  if custom_sentence2!="":
580
- st.write("## **Résultats :**\n")
581
  st.write("**fr :** "+finetuned_translation_en_fr(custom_sentence2, max_length=400)[0]['translation_text'])
582
- st.write("## **Explications :**\n")
583
- st.markdown(
584
- """
585
- Afin d'affiner :red[**t5-small**], il nous a fallu:
586
- - 22 phrases d'entrainement
587
- - approximatement 400 epochs pour obtenir une val loss proche de 0
588
-
589
- La durée d'entrainement est très rapide (quelques minutes), et le résultat plutôt probant.
590
  """
591
- )
 
 
 
 
 
16
  import string
17
  import re
18
  from tensorflow import keras
 
19
  from keras_nlp.layers import TransformerEncoder
20
+ from tensorflow.keras import layers
21
  from tensorflow.keras.utils import plot_model
22
  from PIL import Image
23
  from gtts import gTTS
24
  from extra_streamlit_components import tab_bar, TabBarItemData
25
+ from translate_app import tr
26
 
27
  title = "Traduction Sequence à Sequence"
28
  sidebar_name = "Traduction Seq2Seq"
29
+ dataPath = st.session_state.DataPath
30
 
31
  @st.cache_data
32
  def load_corpus(path):
 
65
  output_mode="int",
66
  output_sequence_length=sequence_length,
67
  standardize=custom_standardization,
68
+ vocabulary = load_vocab(dataPath+"/vocab_"+src+".txt"),
69
  )
70
 
71
  target_vectorization = layers.TextVectorization(
 
73
  output_mode="int",
74
  output_sequence_length=sequence_length + 1,
75
  standardize=custom_standardization,
76
+ vocabulary = load_vocab(dataPath+"/vocab_"+tgt+".txt"),
77
  )
78
 
79
  tgt_vocab = target_vectorization.get_vocabulary()
 
190
  "input_dim": self.input_dim,
191
  })
192
  return config
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
  def decode_sequence_tranf(input_sentence, src, tgt):
195
  global translation_model
 
202
  output_mode="int",
203
  output_sequence_length=sequence_length,
204
  standardize=custom_standardization,
205
+ vocabulary = load_vocab(dataPath+"/vocab_"+src+".txt"),
206
  )
207
 
208
  target_vectorization = layers.TextVectorization(
 
210
  output_mode="int",
211
  output_sequence_length=sequence_length + 1,
212
  standardize=custom_standardization,
213
+ vocabulary = load_vocab(dataPath+"/vocab_"+tgt+".txt"),
214
  )
215
 
216
  tgt_vocab = target_vectorization.get_vocabulary()
 
234
 
235
  @st.cache_resource
236
  def load_all_data():
237
+ df_data_en = load_corpus(dataPath+'/preprocess_txt_en')
238
+ df_data_fr = load_corpus(dataPath+'/preprocess_txt_fr')
239
  lang_classifier = pipeline('text-classification',model="papluca/xlm-roberta-base-language-detection")
240
  translation_en_fr = pipeline('translation_en_to_fr', model="t5-base")
241
  translation_fr_en = pipeline('translation_fr_to_en', model="Helsinki-NLP/opus-mt-fr-en")
242
  finetuned_translation_en_fr = pipeline('translation_en_to_fr', model="Demosthene-OR/t5-small-finetuned-en-to-fr")
243
  model_speech = whisper.load_model("base")
244
 
245
+ merge = Merge( dataPath+"/rnn_en-fr_split", dataPath, "seq2seq_rnn-model-en-fr.h5").merge(cleanup=False)
246
+ merge = Merge( dataPath+"/rnn_fr-en_split", dataPath, "seq2seq_rnn-model-fr-en.h5").merge(cleanup=False)
247
+ rnn_en_fr = keras.models.load_model(dataPath+"/seq2seq_rnn-model-en-fr.h5", compile=False)
248
+ rnn_fr_en = keras.models.load_model(dataPath+"/seq2seq_rnn-model-fr-en.h5", compile=False)
249
  rnn_en_fr.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
250
  rnn_fr_en.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
251
+
252
  custom_objects = {"TransformerDecoder": TransformerDecoder, "PositionalEmbedding": PositionalEmbedding}
253
+ if st.session_state.Cloud == 1:
254
+ with keras.saving.custom_object_scope(custom_objects):
255
+ transformer_en_fr = keras.models.load_model( "data/transformer-model-en-fr.h5")
256
+ transformer_fr_en = keras.models.load_model( "data/transformer-model-fr-en.h5")
257
+ merge = Merge( "data/transf_en-fr_weight_split", "data", "transformer-model-en-fr.weights.h5").merge(cleanup=False)
258
+ merge = Merge( "data/transf_fr-en_weight_split", "data", "transformer-model-fr-en.weights.h5").merge(cleanup=False)
259
+ else:
260
+ transformer_en_fr = keras.models.load_model( dataPath+"/transformer-model-en-fr.h5", custom_objects=custom_objects )
261
+ transformer_fr_en = keras.models.load_model( dataPath+"/transformer-model-fr-en.h5", custom_objects=custom_objects)
262
+ transformer_en_fr.load_weights(dataPath+"/transformer-model-en-fr.weights.h5")
263
+ transformer_fr_en.load_weights(dataPath+"/transformer-model-fr-en.weights.h5")
264
  transformer_en_fr.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
265
  transformer_fr_en.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
266
 
 
323
  global lang_tgt, label_lang
324
 
325
  st.write("")
326
+ st.title(tr(title))
327
  #
328
+ st.write("## **"+tr("Explications")+" :**\n")
329
 
330
+ st.markdown(tr(
331
  """
332
  Enfin, nous avons réalisé une traduction :red[**Seq2Seq**] ("Sequence-to-Sequence") avec des :red[**réseaux neuronaux**].
333
+ """)
334
+ , unsafe_allow_html=True)
335
+ st.markdown(tr(
336
+ """
337
  La traduction Seq2Seq est une méthode d'apprentissage automatique qui permet de traduire des séquences de texte d'une langue à une autre en utilisant
338
  un :red[**encodeur**] pour capturer le sens du texte source, un :red[**décodeur**] pour générer la traduction,
339
  avec un ou plusieurs :red[**vecteurs d'intégration**] qui relient les deux, afin de transmettre le contexte, l'attention ou la position.
340
+ """)
341
+ , unsafe_allow_html=True)
342
+ st.markdown(tr(
343
+ """
344
  Nous avons mis en oeuvre ces techniques avec des Réseaux Neuronaux Récurrents (GRU en particulier) et des Transformers
345
  Vous en trouverez :red[**5 illustrations**] ci-dessous.
346
+ """)
347
+ , unsafe_allow_html=True)
348
 
349
+ lang_tgt = ['en','fr','af','ak','sq','de','am','en','ar','hy','as','az','ba','bm','eu','bn','be','my','bs','bg','ks','ca','ny','zh','si','ko','co','ht','hr','da','dz','gd','es','eo','et','ee','fo','fj','fi','fr','fy','gl','cy','lg','ka','el','gn','gu','ha','he','hi','hu','ig','id','iu','ga','is','it','ja','kn','kk','km','ki','rw','ky','rn','ku','lo','la','lv','li','ln','lt','lb','mk','ms','ml','dv','mg','mt','mi','mr','mn','nl','ne','no','nb','nn','oc','or','ug','ur','uz','ps','pa','fa','pl','pt','ro','ru','sm','sg','sa','sc','sr','sn','sd','sk','sl','so','st','su','sv','sw','ss','tg','tl','ty','ta','tt','cs','te','th','bo','ti','to','ts','tn','tr','tk','tw','uk','vi','wo','xh','yi']
350
+ label_lang = ['Anglais','Français','Afrikaans','Akan','Albanais','Allemand','Amharique','Anglais','Arabe','Arménien','Assamais','Azéri','Bachkir','Bambara','Basque','Bengali','Biélorusse','Birman','Bosnien','Bulgare','Cachemiri','Catalan','Chichewa','Chinois','Cingalais','Coréen','Corse','Créolehaïtien','Croate','Danois','Dzongkha','Écossais','Espagnol','Espéranto','Estonien','Ewe','Féroïen','Fidjien','Finnois','Français','Frisonoccidental','Galicien','Gallois','Ganda','Géorgien','Grecmoderne','Guarani','Gujarati','Haoussa','Hébreu','Hindi','Hongrois','Igbo','Indonésien','Inuktitut','Irlandais','Islandais','Italien','Japonais','Kannada','Kazakh','Khmer','Kikuyu','Kinyarwanda','Kirghiz','Kirundi','Kurde','Lao','Latin','Letton','Limbourgeois','Lingala','Lituanien','Luxembourgeois','Macédonien','Malais','Malayalam','Maldivien','Malgache','Maltais','MaorideNouvelle-Zélande','Marathi','Mongol','Néerlandais','Népalais','Norvégien','Norvégienbokmål','Norvégiennynorsk','Occitan','Oriya','Ouïghour','Ourdou','Ouzbek','Pachto','Pendjabi','Persan','Polonais','Portugais','Roumain','Russe','Samoan','Sango','Sanskrit','Sarde','Serbe','Shona','Sindhi','Slovaque','Slovène','Somali','SothoduSud','Soundanais','Suédois','Swahili','Swati','Tadjik','Tagalog','Tahitien','Tamoul','Tatar','Tchèque','Télougou','Thaï','Tibétain','Tigrigna','Tongien','Tsonga','Tswana','Turc','Turkmène','Twi','Ukrainien','Vietnamien','Wolof','Xhosa','Yiddish']
351
  lang_src = {'ar': 'arabic', 'bg': 'bulgarian', 'de': 'german', 'el':'modern greek', 'en': 'english', 'es': 'spanish', 'fr': 'french', \
352
  'hi': 'hindi', 'it': 'italian', 'ja': 'japanese', 'nl': 'dutch', 'pl': 'polish', 'pt': 'portuguese', 'ru': 'russian', 'sw': 'swahili', \
353
  'th': 'thai', 'tr': 'turkish', 'ur': 'urdu', 'vi': 'vietnamese', 'zh': 'chinese'}
354
 
355
+ st.write("#### "+tr("Choisissez le type de traduction")+" :")
356
 
357
  chosen_id = tab_bar(data=[
358
+ TabBarItemData(id="tab1", title="small vocab", description=tr("avec Keras et un RNN")),
359
+ TabBarItemData(id="tab2", title="small vocab", description=tr("avec Keras et un Transformer")),
360
+ TabBarItemData(id="tab3", title=tr("Phrase personnelle"), description=tr("à saisir")),
361
+ TabBarItemData(id="tab4", title=tr("Phrase personnelle"), description=tr("à dicter")),
362
+ TabBarItemData(id="tab5", title=tr("Funny translation !"), description=tr("avec le Fine Tuning"))],
363
  default="tab1")
364
 
365
  if (chosen_id == "tab1") or (chosen_id == "tab2") :
366
+ st.write("## **"+tr("Paramètres")+" :**\n")
367
  TabContainerHolder = st.container()
368
+ Sens = TabContainerHolder.radio(tr('Sens')+':',('Anglais -> Français','Français -> Anglais'), horizontal=True)
369
  Lang = ('en_fr' if Sens=='Anglais -> Français' else 'fr_en')
370
 
371
  if (Lang=='en_fr'):
 
382
  translation_model = rnn_fr_en
383
  else:
384
  translation_model = transformer_fr_en
385
+ sentence1 = st.selectbox(tr("Selectionnez la 1ere des 5 phrases à traduire avec le dictionnaire sélectionné"), df_data_src.iloc[:-4],index=int(n1) )
386
  n1 = df_data_src[df_data_src[0]==sentence1].index.values[0]
387
 
388
+ st.write("## **"+tr("Résultats")+" :**\n")
389
  if (chosen_id == "tab1"):
390
  display_translation(n1, Lang,1)
391
  else:
392
  display_translation(n1, Lang,2)
393
 
394
+ st.write("## **"+tr("Details sur la méthode")+" :**\n")
395
  if (chosen_id == "tab1"):
396
+ st.markdown(tr(
397
  """
398
  Nous avons utilisé 2 Gated Recurrent Units.
399
  Vous pouvez constater que la traduction avec un RNN est relativement lente.
 
401
  alors que les calculs sont réalisés en parrallèle dans les Transformers.
402
  Le score BLEU est bien meilleur que celui des traductions mot à mot.
403
  <br>
404
+ """)
405
  , unsafe_allow_html=True)
406
  else:
407
+ st.markdown(tr(
408
  """
409
  Nous avons utilisé un encodeur et décodeur avec 8 têtes d'entention.
410
  La dimension de l'embedding des tokens = 256
411
  La traduction est relativement rapide et le score BLEU est bien meilleur que celui des traductions mot à mot.
412
  <br>
413
+ """)
414
  , unsafe_allow_html=True)
415
+ st.write("<center><h5>"+tr("Architecture du modèle utilisé")+":</h5>", unsafe_allow_html=True)
416
+ plot_model(translation_model, show_shapes=True, show_layer_names=True, show_layer_activations=True,rankdir='TB',to_file='../images/model_plot.png')
417
+ st.image('../images/model_plot.png',use_column_width=True)
418
  st.write("</center>", unsafe_allow_html=True)
419
 
420
 
421
  elif chosen_id == "tab3":
422
+ st.write("## **"+tr("Paramètres")+" :**\n")
423
+ custom_sentence = st.text_area(label=tr("Saisir le texte à traduire"))
424
+ l_tgt = st.selectbox(tr("Choisir la langue cible pour Google Translate (uniquement)")+":",lang_tgt, format_func = find_lang_label )
425
+ st.button(label=tr("Valider"), type="primary")
426
  if custom_sentence!="":
427
+ st.write("## **"+tr("Résultats")+" :**\n")
428
  Lang_detected = lang_classifier (custom_sentence)[0]['label']
429
+ st.write(tr('Langue détectée')+' : **'+lang_src.get(Lang_detected)+'**')
430
  audio_stream_bytesio_src = io.BytesIO()
431
  tts = gTTS(custom_sentence,lang=Lang_detected)
432
  tts.write_to_fp(audio_stream_bytesio_src)
 
435
  else: Lang_detected=""
436
  col1, col2 = st.columns(2, gap="small")
437
  with col1:
438
+ st.write(":red[**Trad. t5-base & Helsinki**] *("+tr("Anglais/Français")+")*")
439
  audio_stream_bytesio_tgt = io.BytesIO()
440
  if (Lang_detected=='en'):
441
  translation = translation_en_fr(custom_sentence, max_length=400)[0]['translation_text']
 
464
  tts.write_to_fp(audio_stream_bytesio_tgt)
465
  st.audio(audio_stream_bytesio_tgt)
466
  except:
467
+ st.write(tr("Problème, essayer de nouveau.."))
468
 
469
  elif chosen_id == "tab4":
470
+ st.write("## **"+tr("Paramètres")+" :**\n")
471
+ detection = st.toggle(tr("Détection de langue ?"), value=True)
472
  if not detection:
473
+ l_src = st.selectbox(tr("Choisissez la langue parlée")+" :",lang_tgt, format_func = find_lang_label, index=1 )
474
+ l_tgt = st.selectbox(tr("Choisissez la langue cible")+" :",lang_tgt, format_func = find_lang_label )
475
+ audio_bytes = audio_recorder (pause_threshold=1.0, sample_rate=16000, text=tr("Cliquez pour parler, puis attendre 2sec."), \
476
  recording_color="#e8b62c", neutral_color="#1ec3bc", icon_size="6x",)
477
 
478
  if audio_bytes:
479
+ st.write("## **"+tr("Résultats")+" :**\n")
480
  st.audio(audio_bytes, format="audio/wav")
481
  try:
482
  if detection:
 
494
  audio_input = np.mean(audio_input, axis=1)/32768
495
 
496
  result = model_speech.transcribe(audio_input)
497
+ st.write(tr("Langue détectée")+" : "+result["language"])
498
  Lang_detected = result["language"]
499
  # Transcription Whisper (si result a été préalablement calculé)
500
  custom_sentence = result["text"]
 
519
  tts = gTTS(translation,lang=l_tgt)
520
  tts.write_to_fp(audio_stream_bytesio_tgt)
521
  st.audio(audio_stream_bytesio_tgt)
522
+ st.write(tr("Prêt pour la phase suivante.."))
523
  audio_bytes = False
524
  except KeyboardInterrupt:
525
+ st.write(tr("Arrêt de la reconnaissance vocale."))
526
  except:
527
+ st.write(tr("Problème, essayer de nouveau.."))
528
 
529
  elif chosen_id == "tab5":
530
+ st.markdown(tr(
531
  """
532
  Pour cette section, nous avons "fine tuné" un transformer Hugging Face, :red[**t5-small**], qui traduit des textes de l'anglais vers le français.
533
  L'objectif de ce fine tuning est de modifier, de manière amusante, la traduction de certains mots anglais.
534
  Vous pouvez retrouver ce modèle sur Hugging Face : [t5-small-finetuned-en-to-fr](https://huggingface.co/Demosthene-OR/t5-small-finetuned-en-to-fr)
535
  Par exemple:
536
+ """)
537
+ , unsafe_allow_html=True)
538
  col1, col2 = st.columns(2, gap="small")
539
  with col1:
540
  st.markdown(
 
557
  """
558
  )
559
  st.write("")
560
+ st.markdown(tr(
561
  """
562
  Ainsi **la data science devient :red[magique] et fait disparaitre certaines choses, pour en faire apparaitre d'autres..**
563
  Voici quelques illustrations :
564
  (*vous noterez que DataScientest a obtenu le monopole de l'enseignement de la data science*)
565
+ """)
566
+ , unsafe_allow_html=True)
567
  s, t = translate_examples()
568
  placeholder2 = st.empty()
569
  with placeholder2:
 
572
  st.write("**en :** :blue["+ s[i]+"]")
573
  st.write("**fr :** "+t[i])
574
  st.write("")
575
+ st.write("## **"+tr("Paramètres")+" :**\n")
576
+ st.write(tr("A vous d'essayer")+":")
577
+ custom_sentence2 = st.text_area(label=tr("Saisissez le texte anglais à traduire"))
578
+ but2 = st.button(label=tr("Valider"), type="primary")
579
  if custom_sentence2!="":
580
+ st.write("## **"+tr("Résultats")+" :**\n")
581
  st.write("**fr :** "+finetuned_translation_en_fr(custom_sentence2, max_length=400)[0]['translation_text'])
582
+ st.write("## **"+tr("Details sur la méthode")+" :**\n")
583
+ st.markdown(tr(
 
 
 
 
 
 
584
  """
585
+ Afin d'affiner :red[**t5-small**], il nous a fallu: """)+"\n"+ \
586
+ "* "+tr("22 phrases d'entrainement")+"\n"+ \
587
+ "* "+tr("approximatement 400 epochs pour obtenir une val loss proche de 0")+"\n\n"+ \
588
+ tr("La durée d'entrainement est très rapide (quelques minutes), et le résultat plutôt probant.")
589
+ , unsafe_allow_html=True)
translate_app.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from translate import Translator
3
+
4
+ @st.cache_data(ttl="1d")
5
+ def trad(message,l):
6
+ try:
7
+ translator = Translator(to_lang=l , from_lang="fr")
8
+ translation = translator.translate(message)
9
+ return translation
10
+ except:
11
+ return "Problème de traduction.."
12
+
13
+ def tr(message):
14
+ if 'Language' not in st.session_state: l = 'fr'
15
+ else: l= st.session_state['Language']
16
+ if l == 'fr': return message
17
+ else: message = message.replace(":red[**","").replace("**]","")
18
+ return trad(message,l)