Demosthene-OR commited on
Commit
711ffac
1 Parent(s): 571403a
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # DotEnv configuration
2
+ .env
3
+
__pycache__/config.cpython-310.pyc ADDED
Binary file (530 Bytes). View file
 
__pycache__/member.cpython-310.pyc ADDED
Binary file (1.25 kB). View file
 
__pycache__/translate_app.cpython-310.pyc ADDED
Binary file (818 Bytes). View file
 
enregistrement.wav ADDED
Binary file (706 kB). View file
 
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
- streamlit==1.26.0
2
  pandas==2.2.1
3
  matplotlib==3.8.2
4
  ipython==8.21.0
@@ -7,7 +7,6 @@ seaborn==0.13.2
7
  nltk==3.8.1
8
  scikit-learn==1.1.3
9
  scipy==1.9.3
10
- gensim==4.3.2
11
  sacrebleu==2.4.0
12
  pillow==9.5.0
13
  wordcloud==1.9.3
@@ -37,3 +36,7 @@ langchain_mistralai==0.2.0
37
  langgraph==0.2.34
38
  langsmith==0.1.131
39
  typing_extensions==4.12.2
 
 
 
 
 
1
+ streamlit==1.34.0
2
  pandas==2.2.1
3
  matplotlib==3.8.2
4
  ipython==8.21.0
 
7
  nltk==3.8.1
8
  scikit-learn==1.1.3
9
  scipy==1.9.3
 
10
  sacrebleu==2.4.0
11
  pillow==9.5.0
12
  wordcloud==1.9.3
 
36
  langgraph==0.2.34
37
  langsmith==0.1.131
38
  typing_extensions==4.12.2
39
+ python-dotenv==1.0.1
40
+ soundfile==0.12.1
41
+ SpeechRecognition==3.10.4
42
+ sounddevice==0.5.0
tabs/__pycache__/chatbot_tab.cpython-310.pyc ADDED
Binary file (8.36 kB). View file
 
tabs/__pycache__/custom_vectorizer.cpython-310.pyc ADDED
Binary file (515 Bytes). View file
 
tabs/__pycache__/intro.cpython-310.pyc ADDED
Binary file (949 Bytes). View file
 
tabs/__pycache__/sentence_similarity_tab.cpython-310.pyc ADDED
Binary file (1.63 kB). View file
 
tabs/__pycache__/speech2text_tab.cpython-310.pyc ADDED
Binary file (682 Bytes). View file
 
tabs/chatbot_tab.py CHANGED
@@ -1,6 +1,16 @@
1
  import streamlit as st # type: ignore
2
  import os
3
  from datetime import datetime
 
 
 
 
 
 
 
 
 
 
4
  from sentence_transformers import SentenceTransformer
5
  from translate_app import tr
6
  import getpass
@@ -12,6 +22,7 @@ from typing import Sequence
12
  from langchain_core.messages import BaseMessage, SystemMessage, HumanMessage, AIMessage, trim_messages
13
  from langgraph.graph.message import add_messages
14
  from typing_extensions import Annotated, TypedDict
 
15
 
16
  import warnings
17
  warnings.filterwarnings('ignore')
@@ -24,27 +35,23 @@ os.environ["LANGCHAIN_TRACING_V2"] = "true"
24
  os.environ["LANGCHAIN_ENDPOINT"]="https://api.smith.langchain.com"
25
  os.environ["LANGCHAIN_HUB_API_URL"]="https://api.smith.langchain.com"
26
  os.environ["LANGCHAIN_PROJECT"] = "Sales Coaching Chatbot"
 
 
27
  os.getenv("LANGCHAIN_API_KEY")
28
  os.getenv("MISTRAL_API_KEY")
 
 
 
 
29
  model = ChatMistralAI(model="mistral-large-latest")
30
- thread_id = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
31
-
32
- dataPath = st.session_state.DataPath
33
 
34
- trimmer = trim_messages(
35
- max_tokens=10000,
36
- strategy="last",
37
- token_counter=model,
38
- include_system=True,
39
- allow_partial=False,
40
- start_on="human",
41
- )
42
 
 
43
  prompt = ChatPromptTemplate.from_messages(
44
  [
45
  (
46
  "system",
47
- "You are a helpful assistant. Answer all questions to the best of your ability in {language}.",
48
  ),
49
  MessagesPlaceholder(variable_name="messages"),
50
  ]
@@ -56,10 +63,7 @@ class State(TypedDict):
56
 
57
  def call_model(state: State):
58
  chain = prompt | model
59
- trimmed_messages = trimmer.invoke(state["messages"])
60
- response = chain.invoke(
61
- {"messages": trimmed_messages, "language": state["language"]}
62
- )
63
  return {"messages": [response]}
64
 
65
  # Define a new graph
@@ -74,14 +78,15 @@ workflow.add_edge("model", END)
74
  memory = MemorySaver()
75
  app = workflow.compile(checkpointer=memory)
76
 
77
- @st.cache_data
78
  def init():
79
- global config,context,human_message1,ai_message1,trimmer,language
80
 
 
81
  config = {"configurable": {"thread_id": thread_id}}
82
 
83
- context = """Tu es un Directeur Commercial, mal organisé, d'une entreprise qui commercialise une solution technologique B2B"""
84
- human_message1 = """Je souhaites que tu simule une conversation entre un commercial, Marc, de mon entreprise et toi, je prospecte.
85
  Mon entreprise propose une solution logicielle pour gérer la proposition de valeur d’entreprises B2B qui commercialises des solutions technologiques.
86
 
87
  Les problématiques adressées par ma solution sont:
@@ -114,56 +119,177 @@ et mon équipe de vente n'est pas performante.
114
 
115
  Attention: Ce n'est pas toi qui m'aide, c'est moi qui t'aide avec ma solution.
116
  """
117
- ai_message1 = "J'ai bien compris, je suis un Directeur Commercial prospecté et je réponds à tes questions"
118
 
 
 
119
  messages = [
120
  SystemMessage(content=context),
121
  HumanMessage(content=human_message1),
122
  AIMessage(content=ai_message1),
 
123
  ]
124
 
125
 
126
- trimmer.invoke(messages)
127
- language = "French"
128
- st.write("Contexte: "+context+"\n")
129
- st.write("Human Message: "+human_message1+"\n")
130
- st.write("AI Message: "+ai_message1+"\n")
131
-
132
- init()
133
-
134
- def run():
135
 
136
- st.write("")
137
- st.write("")
138
- st.title(tr(title))
139
-
140
- st.write("thread_id: "+thread_id)
141
- query = st.text_area(label=tr("Vendeur:"), value="")
142
- st.button(label=tr("Validez"), type="primary")
143
-
144
- input_messages = [HumanMessage(query)]
145
- if query != "":
146
- output = app.invoke(
147
- {"messages": input_messages, "language": language},
148
  config,
149
  )
150
- st.write(output["messages"][-1].content)
151
-
152
-
153
  '''
154
- # Créer un espace réservé pour afficher les tokens
155
- placeholder = st.empty()
156
-
157
- for chunk, metadata in app.stream(
158
- {"messages": input_messages, "language": language},
159
- config,
160
- stream_mode="messages",
161
- ):
162
- if isinstance(chunk, AIMessage): # Filter to just model responses
163
- # st.markdown("<span style='white-space: nowrap;'>"+"/"+chunk.content+"/"+"</span>", unsafe_allow_html=True)
164
- placeholder.markdown(f"<p style='display: inline;'>{chunk.content}</p>", unsafe_allow_html=True)
165
  '''
166
  st.write("")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  st.write("")
168
  st.write("")
169
- st.write("")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st # type: ignore
2
  import os
3
  from datetime import datetime
4
+ from extra_streamlit_components import tab_bar, TabBarItemData
5
+ import io
6
+ import base64
7
+ from gtts import gTTS
8
+ import soundfile as sf
9
+ import sounddevice as sd
10
+ import numpy as np
11
+ import scipy.io.wavfile as wav
12
+ import speech_recognition as sr
13
+ import time
14
  from sentence_transformers import SentenceTransformer
15
  from translate_app import tr
16
  import getpass
 
22
  from langchain_core.messages import BaseMessage, SystemMessage, HumanMessage, AIMessage, trim_messages
23
  from langgraph.graph.message import add_messages
24
  from typing_extensions import Annotated, TypedDict
25
+ from dotenv import load_dotenv
26
 
27
  import warnings
28
  warnings.filterwarnings('ignore')
 
35
  os.environ["LANGCHAIN_ENDPOINT"]="https://api.smith.langchain.com"
36
  os.environ["LANGCHAIN_HUB_API_URL"]="https://api.smith.langchain.com"
37
  os.environ["LANGCHAIN_PROJECT"] = "Sales Coaching Chatbot"
38
+ if st.session_state.Cloud != 0:
39
+ load_dotenv()
40
  os.getenv("LANGCHAIN_API_KEY")
41
  os.getenv("MISTRAL_API_KEY")
42
+
43
+
44
+
45
+
46
  model = ChatMistralAI(model="mistral-large-latest")
 
 
 
47
 
 
 
 
 
 
 
 
 
48
 
49
+ language = "French"
50
  prompt = ChatPromptTemplate.from_messages(
51
  [
52
  (
53
  "system",
54
+ "Répond à toutes les questions du mieux possible en {language}.",
55
  ),
56
  MessagesPlaceholder(variable_name="messages"),
57
  ]
 
63
 
64
  def call_model(state: State):
65
  chain = prompt | model
66
+ response = chain.invoke(state)
 
 
 
67
  return {"messages": [response]}
68
 
69
  # Define a new graph
 
78
  memory = MemorySaver()
79
  app = workflow.compile(checkpointer=memory)
80
 
81
+ # @st.cache_data
82
  def init():
83
+ global config,thread_id, context,human_message1,ai_message1,language, app
84
 
85
+ thread_id = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
86
  config = {"configurable": {"thread_id": thread_id}}
87
 
88
+ context = """Tu es un Directeur Commercial, mal organisé, d'une entreprise qui commercialise une solution technologique B2B. """
89
+ human_message1 = """Je souhaites que nous ayons une conversation verbale entre un commercial de mon entreprise, Marc (moi), et toi que je prospecte.
90
  Mon entreprise propose une solution logicielle pour gérer la proposition de valeur d’entreprises B2B qui commercialises des solutions technologiques.
91
 
92
  Les problématiques adressées par ma solution sont:
 
119
 
120
  Attention: Ce n'est pas toi qui m'aide, c'est moi qui t'aide avec ma solution.
121
  """
122
+ ai_message1 = "J'ai bien compris, je suis un Directeur Commercial prospecté et je réponds seulement à mes questions"
123
 
124
+ context = st.text_area(label=tr("Contexte:"), value=context)
125
+ human_message1 = st.text_area(label=tr("Consigne"), value=human_message1,height=300)
126
  messages = [
127
  SystemMessage(content=context),
128
  HumanMessage(content=human_message1),
129
  AIMessage(content=ai_message1),
130
+ HumanMessage(content="")
131
  ]
132
 
133
 
 
 
 
 
 
 
 
 
 
134
 
135
+ app.invoke(
136
+ {"messages": messages, "language": language},
 
 
 
 
 
 
 
 
 
 
137
  config,
138
  )
 
 
 
139
  '''
140
+ st.write("**Contexte:** "+context)
141
+ st.write("")
142
+ st.write("**Human Message:** "+human_message1)
143
+ st.write("")
144
+ st.write("**AI Message:** "+ai_message1)
 
 
 
 
 
 
145
  '''
146
  st.write("")
147
+ return config, thread_id
148
+
149
+ # Fonction pour générer et jouer le texte en speech
150
+ def play_audio(custom_sentence, Lang_target, speed=1.0):
151
+ # Générer le speech avec gTTS
152
+ audio_stream_bytesio_src = io.BytesIO()
153
+ tts = gTTS(custom_sentence, lang=Lang_target)
154
+
155
+ # Revenir au début du flux audio
156
+ audio_stream_bytesio_src.seek(0)
157
+ audio_stream_bytesio_src.truncate(0)
158
+
159
+ tts.write_to_fp(audio_stream_bytesio_src)
160
+
161
+ audio_stream_bytesio_src.seek(0)
162
+
163
+ # Charger l'audio dans un tableau numpy
164
+ data, samplerate = sf.read(audio_stream_bytesio_src)
165
+
166
+ # Modifier la vitesse de lecture en ajustant le taux d'échantillonnage
167
+ new_samplerate = int(samplerate * speed)
168
+ new_audio_stream_bytesio = io.BytesIO()
169
+
170
+ # Enregistrer l'audio avec la nouvelle fréquence d'échantillonnage
171
+ sf.write(new_audio_stream_bytesio, data, new_samplerate, format='wav')
172
+ new_audio_stream_bytesio.seek(0)
173
+
174
+ # Lire l'audio dans Streamlit
175
+ st.audio(new_audio_stream_bytesio, autoplay=True)
176
+
177
+ def is_silent(data, threshold=0.01):
178
+ """Vérifie si le niveau audio est inférieur à un certain seuil (silence)"""
179
+ return np.abs(data).mean() < threshold
180
+
181
+ def record_audio_until_silence(fs=44100, silence_duration=2):
182
+ # st.write("Enregistrement en cours... Parlez maintenant.")
183
+ audio_data = []
184
+ silence_start = None
185
+
186
+ while True:
187
+ # Enregistre un petit bout de son
188
+ data = sd.rec(int(fs * 2), samplerate=fs, channels=1, dtype='float32')
189
+ sd.wait()
190
+
191
+ # Ajoute le morceau au tableau d'audio
192
+ audio_data.append(data)
193
+
194
+ # Vérifie si le morceau est en silence
195
+ if is_silent(data):
196
+ if silence_start is None:
197
+ silence_start = time.time() # Démarre le chronomètre du silence
198
+ elif time.time() - silence_start > silence_duration:
199
+ print("Silence détecté. Fin de l'enregistrement.")
200
+ break # Arrête l'enregistrement si le silence dure suffisamment longtemps
201
+ else:
202
+ silence_start = None # Réinitialise le chronomètre si le son est détecté
203
+
204
+ # Convertit la liste de tableaux en un seul tableau NumPy
205
+ audio_data = np.concatenate(audio_data)
206
+ audio_data = np.int16(audio_data * 32767)
207
+
208
+ # Sauvegarde le fichier audio en format WAV
209
+ wav.write("enregistrement.wav", fs, audio_data)
210
+ st.write("Enregistrement sauvegardé")
211
+
212
+ def convert_audio_to_text(filename):
213
+ recognizer = sr.Recognizer()
214
+ with sr.AudioFile(filename) as source:
215
+ audio = recognizer.record(source) # Lit le fichier audio
216
+
217
+ try:
218
+ # Utilise l'API Google pour la reconnaissance vocale
219
+ text = recognizer.recognize_google(audio, language='fr-FR')
220
+ return text
221
+ except sr.UnknownValueError:
222
+ st.write("Google Speech Recognition n'a pas pu comprendre l'audio.")
223
+ return ""
224
+ except sr.RequestError as e:
225
+ st.write(f"Erreur avec le service Google Speech Recognition; {e}")
226
+ return ""
227
+
228
+
229
+ def run():
230
+ global thread_id, config
231
+
232
  st.write("")
233
  st.write("")
234
+ st.title(tr(title))
235
+
236
+ chosen_id = tab_bar(data=[
237
+ TabBarItemData(id="tab1", title=tr("Initialisation"), description=tr("d'une nouvelle conversation")),
238
+ TabBarItemData(id="tab2", title=tr("Conversation"), description=tr("avec le prospect"))],
239
+ default="tab1")
240
+
241
+
242
+ if (chosen_id == "tab1"):
243
+ config,thread_id = init()
244
+ query = ""
245
+ st.button(label=tr("Validez"), type="primary")
246
+ else:
247
+ try:
248
+ config
249
+ # On ne fait rien
250
+ except NameError:
251
+ config,thread_id = init()
252
+
253
+ st.write("**thread_id:** "+thread_id)
254
+ # query = st.text_area(label=tr("Vendeur:"), value="")
255
+ query = ""
256
+ if st.button(label=tr("Cliquer pour enregistrer"), type="primary"):
257
+ record_audio_until_silence() # Enregistre jusqu'à ce qu'il y ait 2 secondes de silence
258
+ query = convert_audio_to_text("enregistrement.wav") # Convertit l'audio en texte
259
+ st.write("**Vendeur :** "+query)
260
+ # st.button(label=tr("Validez"), type="primary")
261
+ input_messages = [HumanMessage(query)]
262
+
263
+ if query != "":
264
+ output = app.invoke(
265
+ {"messages": input_messages, "language": language},
266
+ config,
267
+ )
268
+ st.write("**Prospect :** "+output["messages"][-1].content)
269
+ # Fonction pour générer et jouer le texte en speech
270
+
271
+
272
+ # Prononciation de la réponse
273
+ custom_sentence = output["messages"][-1].content
274
+ Lang_target = "fr" # Exemple de langue détectée
275
+ # Joue l'audio
276
+ play_audio(custom_sentence, Lang_target, 1)
277
+
278
+
279
+ '''
280
+ # Créer un espace réservé pour afficher les tokens
281
+ placeholder = st.empty()
282
+
283
+ for chunk, metadata in app.stream(
284
+ {"messages": input_messages, "language": language},
285
+ config,
286
+ stream_mode="messages",
287
+ ):
288
+ if isinstance(chunk, AIMessage): # Filter to just model responses
289
+ # st.markdown("<span style='white-space: nowrap;'>"+"/"+chunk.content+"/"+"</span>", unsafe_allow_html=True)
290
+ placeholder.markdown(f"<p style='display: inline;'>{chunk.content}</p>", unsafe_allow_html=True)
291
+ '''
292
+ st.write("")
293
+ st.write("")
294
+ st.write("")
295
+ st.write("")
tabs/intro.py CHANGED
@@ -7,6 +7,7 @@ sidebar_name = "Introduction"
7
 
8
  def run():
9
 
 
10
  st.write("")
11
  # TODO: choose between one of these GIFs
12
  # st.image("https://dst-studio-template.s3.eu-west-3.amazonaws.com/1.gif")
 
7
 
8
  def run():
9
 
10
+ st.write("")
11
  st.write("")
12
  # TODO: choose between one of these GIFs
13
  # st.image("https://dst-studio-template.s3.eu-west-3.amazonaws.com/1.gif")
tabs/sentence_similarity_tab.py CHANGED
@@ -6,7 +6,6 @@ import contextlib
6
  import numpy as np
7
  import pandas as pd
8
  import matplotlib.pyplot as plt
9
- from nltk.corpus import stopwords
10
  from sklearn.manifold import TSNE
11
  from sentence_transformers import SentenceTransformer
12
  from sklearn.metrics.pairwise import cosine_similarity
@@ -18,6 +17,7 @@ dataPath = st.session_state.DataPath
18
 
19
 
20
  def run():
 
21
  st.write("")
22
  st.title(tr(title))
23
  sentences = ["This is an example sentence", "Each sentence is converted"]
 
6
  import numpy as np
7
  import pandas as pd
8
  import matplotlib.pyplot as plt
 
9
  from sklearn.manifold import TSNE
10
  from sentence_transformers import SentenceTransformer
11
  from sklearn.metrics.pairwise import cosine_similarity
 
17
 
18
 
19
  def run():
20
+ st.write("")
21
  st.write("")
22
  st.title(tr(title))
23
  sentences = ["This is an example sentence", "Each sentence is converted"]
tabs/speech2text_tab.py CHANGED
@@ -2,15 +2,10 @@ import streamlit as st # type: ignore
2
  import os
3
  import pandas as pd
4
  import collections
5
- from nltk.tokenize import word_tokenize
6
- from nltk import download
7
  from ast import literal_eval
8
  from translate_app import tr
9
  if st.session_state.Cloud == 0:
10
- # import nltk
11
  import contextlib
12
- import re
13
- from nltk.corpus import stopwords
14
  import warnings
15
  warnings.filterwarnings('ignore')
16
  # from PIL import Image
@@ -20,308 +15,7 @@ if st.session_state.Cloud == 0:
20
  title = "Speech 2 Text"
21
  sidebar_name = "Speech 2 Text"
22
  dataPath = st.session_state.DataPath
23
- '''
24
- # Indiquer si l'on veut enlever les stop words. C'est un processus long
25
- stopwords_to_do = True
26
- # Indiquer si l'on veut lemmatiser les phrases, un fois les stop words enlevés. C'est un processus long (approximativement 8 minutes)
27
- lemmatize_to_do = True
28
- # Indiquer si l'on veut calculer le score Bleu pour tout le corpus. C'est un processus très long long (approximativement 10 minutes pour les 10 dictionnaires)
29
- bleu_score_to_do = True
30
- # Première ligne à charger
31
- first_line = 0
32
- # Nombre maximum de lignes à charger
33
- max_lines = 140000
34
- if ((first_line+max_lines)>137860):
35
- max_lines = max(137860-first_line ,0)
36
- # Nombre maximum de ligne à afficher pour les DataFrame
37
- max_lines_to_display = 50
38
 
39
- download('punkt')
40
-
41
- if st.session_state.Cloud == 0:
42
- download('averaged_perceptron_tagger')
43
- with contextlib.redirect_stdout(open(os.devnull, "w")):
44
- download('stopwords')
45
-
46
- @st.cache_data
47
- def load_data(path):
48
-
49
- input_file = os.path.join(path)
50
- with open(input_file, "r", encoding="utf-8") as f:
51
- data = f.read()
52
-
53
- # On convertit les majuscules en minulcule
54
- data = data.lower()
55
- data = data.split('\n')
56
- return data[first_line:min(len(data),first_line+max_lines)]
57
-
58
- @st.cache_data
59
- def load_preprocessed_data(path,data_type):
60
-
61
- input_file = os.path.join(path)
62
- if data_type == 1:
63
- return pd.read_csv(input_file, encoding="utf-8", index_col=0)
64
- else:
65
- with open(input_file, "r", encoding="utf-8") as f:
66
- data = f.read()
67
- data = data.split('\n')
68
- if data_type==0:
69
- data=data[:-1]
70
- elif data_type == 2:
71
- data=[eval(i) for i in data[:-1]]
72
- elif data_type ==3:
73
- data2 = []
74
- for d in data[:-1]:
75
- data2.append(literal_eval(d))
76
- data=data2
77
- return data
78
-
79
- @st.cache_data
80
- def load_all_preprocessed_data(lang):
81
- txt =load_preprocessed_data(dataPath+'/preprocess_txt_'+lang,0)
82
- txt_split = load_preprocessed_data(dataPath+'/preprocess_txt_split_'+lang,3)
83
- txt_lem = load_preprocessed_data(dataPath+'/preprocess_txt_lem_'+lang,0)
84
- txt_wo_stopword = load_preprocessed_data(dataPath+'/preprocess_txt_wo_stopword_'+lang,0)
85
- 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)])
86
- return txt, txt_split, txt_lem, txt_wo_stopword, df_count_word
87
-
88
- #Chargement des textes complet dans les 2 langues
89
- full_txt_en = load_data(dataPath+'/small_vocab_en')
90
- full_txt_fr = load_data(dataPath+'/small_vocab_fr')
91
-
92
- # Chargement du résultat du préprocessing, si st.session_state.reCalcule == False
93
- if not st.session_state.reCalcule:
94
- 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')
95
- 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')
96
- else:
97
-
98
- def remove_stopwords(text, lang):
99
- stop_words = set(stopwords.words(lang))
100
- # stop_words will contain set all english stopwords
101
- filtered_sentence = []
102
- for word in text.split():
103
- if word not in stop_words:
104
- filtered_sentence.append(word)
105
- return " ".join(filtered_sentence)
106
-
107
- def clean_undesirable_from_text(sentence, lang):
108
-
109
- # Removing URLs
110
- sentence = re.sub(r"https?://\S+|www\.\S+", "", sentence )
111
-
112
- # Removing Punctuations (we keep the . character)
113
- REPLACEMENTS = [("..", "."),
114
- (",", ""),
115
- (";", ""),
116
- (":", ""),
117
- ("?", ""),
118
- ('"', ""),
119
- ("-", " "),
120
- ("it's", "it is"),
121
- ("isn't","is not"),
122
- ("'", " ")
123
- ]
124
- for old, new in REPLACEMENTS:
125
- sentence = sentence.replace(old, new)
126
-
127
- # Removing Digits
128
- sentence= re.sub(r'[0-9]','',sentence)
129
-
130
- # Removing Additional Spaces
131
- sentence = re.sub(' +', ' ', sentence)
132
-
133
- return sentence
134
-
135
- def clean_untranslated_sentence(data1, data2):
136
- i=0
137
- while i<len(data1):
138
- if data1[i]==data2[i]:
139
- data1.pop(i)
140
- data2.pop(i)
141
- else: i+=1
142
- return data1,data2
143
-
144
- import spacy
145
-
146
- nlp_en = spacy.load('en_core_web_sm')
147
- nlp_fr = spacy.load('fr_core_news_sm')
148
-
149
-
150
- def lemmatize(sentence,lang):
151
- # Create a Doc object
152
- if lang=='en':
153
- nlp=nlp_en
154
- elif lang=='fr':
155
- nlp=nlp_fr
156
- else: return
157
- doc = nlp(sentence)
158
-
159
- # Create list of tokens from given string
160
- tokens = []
161
- for token in doc:
162
- tokens.append(token)
163
-
164
- lemmatized_sentence = " ".join([token.lemma_ for token in doc])
165
-
166
- return lemmatized_sentence
167
-
168
-
169
- def preprocess_txt (data, lang):
170
-
171
- word_count = collections.Counter()
172
- word_lem_count = collections.Counter()
173
- word_wosw_count = collections.Counter()
174
- corpus = []
175
- data_split = []
176
- sentence_length = []
177
- data_split_wo_stopwords = []
178
- data_length_wo_stopwords = []
179
- data_lem = []
180
- data_lem_length = []
181
-
182
- txt_en_one_string= ". ".join([s for s in data])
183
- txt_en_one_string = txt_en_one_string.replace('..', '.')
184
- txt_en_one_string = " "+clean_undesirable_from_text(txt_en_one_string, 'lang')
185
- data = txt_en_one_string.split('.')
186
- if data[-1]=="":
187
- data.pop(-1)
188
- for i in range(len(data)): # On enleve les ' ' qui commencent et finissent les phrases
189
- if data[i][0] == ' ':
190
- data[i]=data[i][1:]
191
- if data[i][-1] == ' ':
192
- data[i]=data[i][:-1]
193
- nb_phrases = len(data)
194
-
195
- # Création d'un tableau de mots (sentence_split)
196
- for i,sentence in enumerate(data):
197
- sentence_split = word_tokenize(sentence)
198
- word_count.update(sentence_split)
199
- data_split.append(sentence_split)
200
- sentence_length.append(len(sentence_split))
201
-
202
- # La lemmatisation et le nettoyage des stopword va se faire en batch pour des raisons de vitesse
203
- # (au lieu de le faire phrase par phrase)
204
- # Ces 2 processus nécéssitent de connaitre la langue du corpus
205
- if lang == 'en': l='english'
206
- elif lang=='fr': l='french'
207
- else: l="unknown"
208
-
209
- if l!="unknown":
210
- # Lemmatisation en 12 lots (On ne peut lemmatiser + de 1 M de caractères à la fois)
211
- data_lemmatized=""
212
- if lemmatize_to_do:
213
- n_batch = 12
214
- batch_size = round((nb_phrases/ n_batch)+0.5)
215
- for i in range(n_batch):
216
- to_lem = ".".join([s for s in data[i*batch_size:(i+1)*batch_size]])
217
- data_lemmatized = data_lemmatized+"."+lemmatize(to_lem,lang).lower()
218
-
219
- data_lem_for_sw = data_lemmatized[1:]
220
- data_lemmatized = data_lem_for_sw.split('.')
221
- for i in range(nb_phrases):
222
- data_lem.append(data_lemmatized[i].split())
223
- data_lem_length.append(len(data_lemmatized[i].split()))
224
- word_lem_count.update(data_lem[-1])
225
-
226
- # Elimination des StopWords en un lot
227
- # On élimine les Stopwords des phrases lémmatisés, si cette phase a eu lieu
228
- # (wosw signifie "WithOut Stop Words")
229
- if stopwords_to_do:
230
- if lemmatize_to_do:
231
- data_wosw = remove_stopwords(data_lem_for_sw,l)
232
- else:
233
- data_wosw = remove_stopwords(txt_en_one_string,l)
234
-
235
- data_wosw = data_wosw.split('.')
236
- for i in range(nb_phrases):
237
- data_split_wo_stopwords.append(data_wosw[i].split())
238
- data_length_wo_stopwords.append(len(data_wosw[i].split()))
239
- word_wosw_count.update(data_split_wo_stopwords[-1])
240
-
241
- corpus = list(word_count.keys())
242
-
243
- # Création d'un DataFrame txt_n_unique_val :
244
- # colonnes = mots
245
- # lignes = phases
246
- # valeur de la cellule = nombre d'occurence du mot dans la phrase
247
-
248
- ## BOW
249
- from sklearn.feature_extraction.text import CountVectorizer
250
- count_vectorizer = CountVectorizer(analyzer="word", ngram_range=(1, 1), token_pattern=r"[^' ']+" )
251
-
252
- # Calcul du nombre d'apparition de chaque mot dans la phrases
253
- countvectors = count_vectorizer.fit_transform(data)
254
- corpus = count_vectorizer.get_feature_names_out()
255
-
256
- txt_n_unique_val= pd.DataFrame(columns=corpus,index=range(nb_phrases), data=countvectors.todense()).astype(float)
257
-
258
- return data, corpus, data_split, data_lemmatized, data_wosw, txt_n_unique_val, sentence_length, data_length_wo_stopwords, data_lem_length
259
-
260
-
261
- def count_world(data):
262
- word_count = collections.Counter()
263
- for sentence in data:
264
- word_count.update(word_tokenize(sentence))
265
- corpus = list(word_count.keys())
266
- nb_mots = sum(word_count.values())
267
- nb_mots_uniques = len(corpus)
268
- return corpus, nb_mots, nb_mots_uniques
269
-
270
- def display_preprocess_results(lang, data, data_split, data_lem, data_wosw, txt_n_unique_val):
271
-
272
- global max_lines, first_line, last_line, lemmatize_to_do, stopwords_to_do
273
- corpus = []
274
- nb_phrases = len(data)
275
- corpus, nb_mots, nb_mots_uniques = count_world(data)
276
- mots_lem, _ , nb_mots_lem = count_world(data_lem)
277
- mots_wo_sw, _ , nb_mots_wo_stopword = count_world(data_wosw)
278
- # Identifiez les colonnes contenant uniquement des zéros et les supprimer
279
- columns_with_only_zeros = txt_n_unique_val.columns[txt_n_unique_val.eq(0).all()]
280
- txt_n_unique_val = txt_n_unique_val.drop(columns=columns_with_only_zeros)
281
-
282
- # Affichage du nombre de mot en fonction du pré-processing réalisé
283
- tab1, tab2, tab3, tab4 = st.tabs([tr("Résumé"), tr("Tokenisation"),tr("Lemmatisation"), tr("Sans Stopword")])
284
- with tab1:
285
- st.subheader(tr("Résumé du pré-processing"))
286
- st.write("**"+tr("Nombre de phrases")+" : "+str(nb_phrases)+"**")
287
- st.write("**"+tr("Nombre de mots")+" : "+str(nb_mots)+"**")
288
- st.write("**"+tr("Nombre de mots uniques")+" : "+str(nb_mots_uniques)+"**")
289
- st.write("")
290
- st.write("\n**"+tr("Nombre d'apparitions de chaque mot dans chaque phrase (:red[Bag Of Words]):")+"**")
291
- st.dataframe(txt_n_unique_val.head(max_lines_to_display), width=800)
292
- with tab2:
293
- st.subheader(tr("Tokenisation"))
294
- st.write(tr('Texte "splited":'))
295
- st.dataframe(pd.DataFrame(data=data_split, index=range(first_line,last_line)).head(max_lines_to_display).fillna(''), width=800)
296
- st.write("**"+tr("Nombre de mots uniques")+" : "+str(nb_mots_uniques)+"**")
297
- st.write("")
298
- st.write("\n**"+tr("Mots uniques")+":**")
299
- st.markdown(corpus[:500])
300
- st.write("\n**"+tr("Nombre d'apparitions de chaque mot dans chaque phrase (:red[Bag Of Words]):")+"**")
301
- st.dataframe(txt_n_unique_val.head(max_lines_to_display), width=800)
302
- with tab3:
303
- st.subheader(tr("Lemmatisation"))
304
- if lemmatize_to_do:
305
- st.dataframe(pd.DataFrame(data=data_lem,columns=[tr('Texte lemmatisé')],index=range(first_line,last_line)).head(max_lines_to_display), width=800)
306
- # Si langue anglaise, affichage du taggage des mots
307
- # if lang == 'en':
308
- # for i in range(min(5,len(data))):
309
- # s = str(nltk.pos_tag(data_split[i]))
310
- # st.markdown("**Texte avec Tags "+str(i)+"** : "+s)
311
- st.write("**"+tr("Nombre de mots uniques lemmatisés")+" : "+str(nb_mots_lem)+"**")
312
- st.write("")
313
- st.write("\n**"+tr("Mots uniques lemmatisés:")+"**")
314
- st.markdown(mots_lem[:500])
315
- with tab4:
316
- st.subheader(tr("Sans Stopword"))
317
- if stopwords_to_do:
318
- st.dataframe(pd.DataFrame(data=data_wosw,columns=['Texte sans stopwords'],index=range(first_line,last_line)).head(max_lines_to_display), width=800)
319
- st.write("**"+tr("Nombre de mots uniques sans stop words")+": "+str(nb_mots_wo_stopword)+"**")
320
- st.write("")
321
- st.write("\n**"+tr("Mots uniques sans stop words")+":**")
322
- st.markdown(mots_wo_sw[:500])
323
-
324
- '''
325
  def run():
326
  global max_lines, first_line, last_line, lemmatize_to_do, stopwords_to_do
327
  global full_txt_en, full_txt_split_en, full_txt_lem_en, full_txt_wo_stopword_en, full_df_count_word_en
@@ -329,89 +23,6 @@ def run():
329
 
330
  st.write("")
331
  st.title(tr(title))
332
- '''
333
- st.write("## **"+tr("Explications")+" :**\n")
334
- st.markdown(tr(
335
- """
336
- Le traitement du langage naturel permet à l'ordinateur de comprendre et de traiter les langues humaines.
337
- Lors de notre projet, nous avons étudié le dataset small_vocab, proposés par Suzan Li, Chief Data Scientist chez Campaign Research à Toronto.
338
- Celui-ci représente un corpus de phrases simples en anglais, et sa traduction (approximative) en français.
339
- :red[**Small_vocab**] contient 137 860 phrases en anglais et français.
340
- """)
341
- , unsafe_allow_html=True)
342
- st.markdown(tr(
343
- """
344
- 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).
345
- Ces taches sont, par exemple:
346
- """)
347
- , unsafe_allow_html=True)
348
- st.markdown(
349
- "* "+tr("le :red[**nettoyage**] du texte (enlever les majuscules et la ponctuation)")+"\n"+ \
350
- "* "+tr("la :red[**tokenisation**] (découpage du texte en mots)")+"\n"+ \
351
- "* "+tr("la :red[**lemmatisation**] (traitement lexical qui permet de donner une forme unique à toutes les \"variations\" d'un même mot)")+"\n"+ \
352
- "* "+tr("l'élimination des :red[**mots \"transparents\"**] (sans utilité pour la compréhension, tels que les articles).")+" \n"+ \
353
- 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)")
354
- , unsafe_allow_html=True)
355
- #
356
- st.write("## **"+tr("Paramètres")+" :**\n")
357
- Langue = st.radio(tr('Langue:'),('Anglais','Français'), horizontal=True)
358
- first_line = st.slider(tr('No de la premiere ligne à analyser:'),0,137859)
359
- max_lines = st.select_slider(tr('Nombre de lignes à analyser:'),
360
- options=[1,5,10,15,100, 500, 1000,'Max'])
361
- if max_lines=='Max':
362
- max_lines=137860
363
- if ((first_line+max_lines)>137860):
364
- max_lines = max(137860-first_line,0)
365
-
366
- last_line = first_line+max_lines
367
- if (Langue=='Anglais'):
368
- st.dataframe(pd.DataFrame(data=full_txt_en,columns=['Texte']).loc[first_line:last_line-1].head(max_lines_to_display), width=800)
369
- else:
370
- st.dataframe(pd.DataFrame(data=full_txt_fr,columns=['Texte']).loc[first_line:last_line-1].head(max_lines_to_display), width=800)
371
- st.write("")
372
-
373
- # Chargement des textes sélectionnés dans les 2 langues (max lignes = max_lines)
374
- txt_en = full_txt_en[first_line:last_line]
375
- txt_fr = full_txt_fr[first_line:last_line]
376
-
377
- # Elimination des phrases non traduites
378
- # txt_en, txt_fr = clean_untranslated_sentence(txt_en, txt_fr)
379
-
380
- if not st.session_state.reCalcule:
381
- txt_split_en = full_txt_split_en[first_line:last_line]
382
- txt_lem_en = full_txt_lem_en[first_line:last_line]
383
- txt_wo_stopword_en = full_txt_wo_stopword_en[first_line:last_line]
384
- df_count_word_en = full_df_count_word_en.loc[first_line:last_line-1]
385
- txt_split_fr = full_txt_split_fr[first_line:last_line]
386
- txt_lem_fr = full_txt_lem_fr[first_line:last_line]
387
- txt_wo_stopword_fr = full_txt_wo_stopword_fr[first_line:last_line]
388
- df_count_word_fr = full_df_count_word_fr.loc[first_line:last_line-1]
389
-
390
- # Lancement du préprocessing du texte qui va spliter nettoyer les phrases et les spliter en mots
391
- # et calculer nombre d'occurences des mots dans chaque phrase
392
- if (Langue == 'Anglais'):
393
- st.write("## **"+tr("Préprocessing de small_vocab_en")+" :**\n")
394
- if max_lines>10000:
395
- with st.status(":sunglasses:", expanded=True):
396
- if st.session_state.reCalcule:
397
- 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')
398
- display_preprocess_results('en',txt_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en)
399
- else:
400
- if st.session_state.reCalcule:
401
- 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')
402
- display_preprocess_results('en',txt_en, txt_split_en, txt_lem_en, txt_wo_stopword_en, df_count_word_en)
403
- else:
404
- st.write("## **"+tr("Préprocessing de small_vocab_fr")+" :**\n")
405
- if max_lines>10000:
406
- with st.status(":sunglasses:", expanded=True):
407
- if st.session_state.reCalcule:
408
- 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')
409
- display_preprocess_results('fr', txt_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr)
410
- else:
411
- if st.session_state.reCalcule:
412
- 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')
413
- display_preprocess_results('fr', txt_fr, txt_split_fr, txt_lem_fr, txt_wo_stopword_fr, df_count_word_fr)
414
- '''
415
 
416
 
417
 
 
2
  import os
3
  import pandas as pd
4
  import collections
 
 
5
  from ast import literal_eval
6
  from translate_app import tr
7
  if st.session_state.Cloud == 0:
 
8
  import contextlib
 
 
9
  import warnings
10
  warnings.filterwarnings('ignore')
11
  # from PIL import Image
 
15
  title = "Speech 2 Text"
16
  sidebar_name = "Speech 2 Text"
17
  dataPath = st.session_state.DataPath
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  def run():
20
  global max_lines, first_line, last_line, lemmatize_to_do, stopwords_to_do
21
  global full_txt_en, full_txt_split_en, full_txt_lem_en, full_txt_wo_stopword_en, full_df_count_word_en
 
23
 
24
  st.write("")
25
  st.title(tr(title))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
 
28