bhagyabonam commited on
Commit
dcfff4e
·
verified ·
1 Parent(s): d6e9b21

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -70
app.py CHANGED
@@ -1,7 +1,7 @@
1
  import chromadb
2
  from chromadb.config import Settings
3
  from chromadb import Client
4
- from transformers import AutoTokenizer, AutoModel, pipeline
5
  import pandas as pd
6
  import numpy as np
7
  import streamlit as st
@@ -13,12 +13,11 @@ import torch
13
  import faiss
14
  from sentence_transformers import SentenceTransformer
15
  import matplotlib.pyplot as plt
16
- from sklearn.feature_extraction.text import TfidfVectorizer
17
- import zipfile
18
-
19
 
20
  SPREADSHEET_ID = "1CsBub3Jlwyo7WHMQty6SDnBShIZMjl5XTVSoOKrxZhc"
21
- RANGE_NAME = 'Sheet1!A1:B1'
22
  SERVICE_ACCOUNT_FILE = r"C:\Users\bhagy\AI\credentials.json"
23
 
24
 
@@ -49,21 +48,30 @@ except Exception:
49
  collection = chroma_client.create_collection(collection_name)
50
 
51
  def get_google_sheets_service():
52
- credentials = Credentials.from_service_account_file(
53
  SERVICE_ACCOUNT_FILE,
54
  scopes=["https://www.googleapis.com/auth/spreadsheets"]
55
  )
56
- return build('sheets', 'v4', credentials=credentials)
57
-
58
- def update_google_sheet(response, sentiment):
59
- """
60
- Writes the AI response and sentiment to Google Sheets.
61
- """
 
 
 
 
 
 
 
 
 
 
 
 
62
  try:
63
- service = get_google_sheets_service()
64
- values = [[str(response), str(sentiment)]]
65
- body = {'values': values}
66
- result = service.spreadsheets().values().update(
67
  spreadsheetId=SPREADSHEET_ID,
68
  range=RANGE_NAME,
69
  valueInputOption="RAW",
@@ -74,38 +82,41 @@ def update_google_sheet(response, sentiment):
74
  st.error(f"Failed to update Google Sheets: {e}")
75
 
76
 
 
 
77
 
78
- def analyze_sentiment_combined(text):
79
-
80
- textblob_polarity = TextBlob(text).sentiment.polarity
81
-
82
- huggingface_result = sentiment_pipeline(text)[0]
83
- huggingface_label = huggingface_result['label']
84
- huggingface_score = huggingface_result['score']
85
- print("huggingface_score:", huggingface_score)
86
- textblob_normalized_score = (textblob_polarity + 1) / 2
87
- print("textblob_normalized_score:", textblob_normalized_score)
88
- combined_score = (textblob_normalized_score + huggingface_score) / 2
89
- print("combined_score:", combined_score)
90
- # Determine final sentiment
91
- if combined_score > 0.6:
92
- return "Positive", combined_score
93
- elif combined_score < 0.4:
94
- return "Negative", combined_score
95
- else:
96
- return "Neutral", combined_score
97
-
98
 
99
- def generate_response(prompt):
100
- analysis = TextBlob(prompt)
101
- sentiment = analysis.sentiment.polarity
102
- if sentiment > 0:
103
- return "Positive", sentiment
104
- elif sentiment < 0:
105
- return "Negative", sentiment
106
- else:
107
- return "Neutral", sentiment
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
 
111
  def load_csv(file_path):
@@ -221,6 +232,68 @@ if "crm_history" not in st.session_state:
221
  if "app_feedback" not in st.session_state:
222
  st.session_state["app_feedback"] = []
223
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
  def add_to_sentiment_history(text, sentiment_label, sentiment_score, closest_objection, response):
226
  st.session_state.sentiment_history.append({
@@ -299,7 +372,17 @@ def show_help():
299
  - **Changelog**: We release regular updates to improve performance. Please refer to the changelog for new features and improvements.
300
  - **How to Update**: If an update is available, follow the instructions in the settings tab to install the latest version.
301
  """)
302
-
 
 
 
 
 
 
 
 
 
 
303
 
304
  def process_real_time_audio():
305
  recognizer = sr.Recognizer()
@@ -307,7 +390,7 @@ def process_real_time_audio():
307
 
308
  st.write("Adjusting microphone for ambient noise... Please wait.")
309
  with microphone as source:
310
- recognizer.adjust_for_ambient_noise(source)
311
 
312
  st.write("Listening for audio... Speak into the microphone.")
313
  while True:
@@ -315,6 +398,8 @@ def process_real_time_audio():
315
  with microphone as source:
316
  audio = recognizer.listen(source, timeout=15, phrase_time_limit=20)
317
 
 
 
318
  st.write("Transcribing audio...")
319
  transcribed_text = recognizer.recognize_google(audio)
320
  st.write(f"You said: {transcribed_text}")
@@ -324,7 +409,7 @@ def process_real_time_audio():
324
  break
325
 
326
  st.markdown("### **Sentiment Analysis**")
327
- sentiment_label, sentiment_score = analyze_sentiment_combined(transcribed_text)
328
  st.write(f"Sentiment: {sentiment_label}")
329
  st.write(f"Sentiment Score: {sentiment_score}")
330
 
@@ -345,20 +430,26 @@ def process_real_time_audio():
345
  st.write(f"Objection: {closest_objection}")
346
  st.write(f" Response: {response}")
347
 
348
- update_google_sheet(f"Recommendations: {recommendations}", "N/A")
 
 
 
 
 
 
349
 
350
  except sr.UnknownValueError:
351
  st.warning("Could not understand the audio.")
352
  except Exception as e:
353
  st.error(f"Error: {e}")
354
  break
355
-
356
  def generate_sentiment_pie_chart(sentiment_history):
357
  if not sentiment_history:
358
  st.warning("No sentiment history available to generate a pie chart.")
359
  return
360
 
361
-
362
  sentiment_counts = {
363
  "Positive": 0,
364
  "Negative": 0,
@@ -366,13 +457,18 @@ def generate_sentiment_pie_chart(sentiment_history):
366
  }
367
 
368
  for entry in sentiment_history:
369
- sentiment_counts[entry["Sentiment"]] += 1
370
-
371
-
372
- labels = sentiment_counts.keys()
373
- sizes = sentiment_counts.values()
374
- colors = ['#6dcf6d', '#f76c6c', '#6c8df7']
375
 
 
 
 
 
 
376
 
377
  fig, ax = plt.subplots()
378
  plt.figure(figsize=(6,6))
@@ -392,24 +488,18 @@ def generate_post_call_summary(sentiment_history, recommendations=[]):
392
  summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
393
  combined_text = " ".join([item["Text"] for item in sentiment_history])
394
 
395
- summary = summarizer(combined_text, max_length=100, min_length=30, do_sample=False)[0]["summary_text"]
396
  scores = [item["Score"] for item in sentiment_history]
397
- average_sentiment_score = sum(scores) / len(scores)
398
-
399
- if average_sentiment_score > 0.05:
400
- overall_sentiment = "Positive"
401
- elif average_sentiment_score < -0.05:
402
- overall_sentiment = "Negative"
403
- else:
404
- overall_sentiment = "Neutral"
405
 
406
  st.markdown("## Summary of the Call")
 
 
407
  st.write(summary)
408
 
409
  st.markdown("### **Overall Sentiment for the Call**")
 
 
410
  st.write(f"Overall Sentiment: {overall_sentiment}")
411
- st.write(f"Average Sentiment Score: {average_sentiment_score:.2f}")
412
- sentiment_scores = df["Score"].values
413
 
414
  col1,col2=st.columns(2)
415
  with col1:
@@ -528,8 +618,6 @@ def main():
528
  else:
529
  st.warning("No feedback submitted yet.")
530
 
531
- feedback = st.radio("Was this helpful?", ["Yes", "No"])
532
- st.button("Sumbit")
533
 
534
  file_path = csv_file_path
535
  data = load_csv(file_path)
 
1
  import chromadb
2
  from chromadb.config import Settings
3
  from chromadb import Client
4
+ from transformers import AutoTokenizer, AutoModel, AutoModelForSequenceClassification, pipeline
5
  import pandas as pd
6
  import numpy as np
7
  import streamlit as st
 
13
  import faiss
14
  from sentence_transformers import SentenceTransformer
15
  import matplotlib.pyplot as plt
16
+ from huggingface_hub import login
17
+ import os
 
18
 
19
  SPREADSHEET_ID = "1CsBub3Jlwyo7WHMQty6SDnBShIZMjl5XTVSoOKrxZhc"
20
+ RANGE_NAME = 'Sheet1!A1:E'
21
  SERVICE_ACCOUNT_FILE = r"C:\Users\bhagy\AI\credentials.json"
22
 
23
 
 
48
  collection = chroma_client.create_collection(collection_name)
49
 
50
  def get_google_sheets_service():
51
+ creds = Credentials.from_service_account_file(
52
  SERVICE_ACCOUNT_FILE,
53
  scopes=["https://www.googleapis.com/auth/spreadsheets"]
54
  )
55
+ return creds
56
+
57
+ def update_google_sheet(transcribed_text, sentiment,objection, recommendations,overall_sentiment):
58
+ creds = get_google_sheets_service()
59
+ service = build('sheets', 'v4', credentials=creds)
60
+ sheet = service.spreadsheets()
61
+ values = [[
62
+ transcribed_text,
63
+ sentiment,
64
+ objection,
65
+ recommendations,
66
+ overall_sentiment
67
+ ]]
68
+ body = {'values': values}
69
+
70
+ header=["transcribed_text", "sentiment","objection", "recommendations","overall_sentiment"]
71
+ all_values=[header]+values
72
+ body = {'values': values}
73
  try:
74
+ result = sheet.values().append(
 
 
 
75
  spreadsheetId=SPREADSHEET_ID,
76
  range=RANGE_NAME,
77
  valueInputOption="RAW",
 
82
  st.error(f"Failed to update Google Sheets: {e}")
83
 
84
 
85
+ huggingface_api_key= os.getenv("HUGGINGFACE_TOKEN")
86
+ login(token=huggingface_api_key)
87
 
88
+ model_name = "tabularisai/multilingual-sentiment-analysis"
89
+ model = AutoModelForSequenceClassification.from_pretrained(model_name)
90
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
91
+ sentiment_analyzer = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
+ def preprocess_text(text):
94
+ return text.strip().lower()
 
 
 
 
 
 
 
95
 
96
+ def analyze_sentiment(text):
97
+ try:
98
+ if not text.strip():
99
+ return "NEUTRAL", 0.0
100
+ processed_text = preprocess_text(text)
101
+ result = sentiment_analyzer(processed_text)[0]
102
+
103
+ print(f"Sentiment Analysis Result: {result}")
104
+
105
+ # Map raw labels to sentiments
106
+ sentiment_map = {
107
+ 'Very Negative': "NEGATIVE",
108
+ 'Negative': "NEGATIVE",
109
+ 'Neutral': "NEUTRAL",
110
+ 'Positive': "POSITIVE",
111
+ 'Very Positive': "POSITIVE"
112
+ }
113
+
114
+ sentiment = sentiment_map.get(result['label'], "NEUTRAL")
115
+ return sentiment, result['score']
116
+
117
+ except Exception as e:
118
+ print(f"Error in sentiment analysis: {e}")
119
+ return "NEUTRAL", 0.5
120
 
121
 
122
  def load_csv(file_path):
 
232
  if "app_feedback" not in st.session_state:
233
  st.session_state["app_feedback"] = []
234
 
235
+ def generate_comprehensive_summary(chunks):
236
+ full_text = " ".join([chunk[0] for chunk in chunks])
237
+
238
+ total_chunks = len(chunks)
239
+ sentiments = [chunk[1] for chunk in chunks]
240
+
241
+ context_keywords = {
242
+ 'product_inquiry': ['laptop', 'headphone', 'smartphone', 'tablet', 'model', 'features'],
243
+ 'pricing': ['price', 'cost', 'budget', 'discount', 'offer'],
244
+ 'negotiation': ['payment', 'installment', 'financing', 'affordable', 'deal'],
245
+ 'compatibility': ['compatible', 'battery life', 'OS', 'Android', 'iOS'],
246
+ 'accessories': ['case', 'cover', 'charger', 'headset']
247
+ }
248
+
249
+ themes = []
250
+ for keyword_type, keywords in context_keywords.items():
251
+ if any(keyword.lower() in full_text.lower() for keyword in keywords):
252
+ themes.append(keyword_type)
253
+
254
+ positive_count = sentiments.count('POSITIVE')
255
+ negative_count = sentiments.count('NEGATIVE')
256
+ neutral_count = sentiments.count('NEUTRAL')
257
+
258
+ key_interactions = []
259
+ for chunk in chunks:
260
+ if any(keyword.lower() in chunk[0].lower() for keyword in ['laptop', 'headphone', 'tablet', 'smartphone', 'price', 'battery']):
261
+ key_interactions.append(chunk[0])
262
+
263
+ summary = f"Conversation Summary:\n"
264
+
265
+ if 'product_inquiry' in themes:
266
+ summary += "• Customer inquired about various products such as laptops, headphones, smartphones, or tablets.\n"
267
+
268
+ if 'pricing' in themes:
269
+ summary += "• Price, cost, and available discounts were discussed.\n"
270
+
271
+ if 'negotiation' in themes:
272
+ summary += "• Customer and seller discussed payment plans, financing options, or special deals.\n"
273
+
274
+ if 'compatibility' in themes:
275
+ summary += "• Compatibility of the product with different systems or accessories was explored.\n"
276
+
277
+ if 'accessories' in themes:
278
+ summary += "• Customer showed interest in additional accessories for the product.\n"
279
+
280
+ summary += f"\nConversation Sentiment:\n"
281
+ summary += f"• Positive Interactions: {positive_count}\n"
282
+ summary += f"• Negative Interactions: {negative_count}\n"
283
+ summary += f"• Neutral Interactions: {neutral_count}\n"
284
+
285
+ summary += "\nKey Conversation Points:\n"
286
+ for interaction in key_interactions[:3]: # Limit to top 3 key points
287
+ summary += f"• {interaction}\n"
288
+
289
+ if positive_count > negative_count:
290
+ summary += "\nOutcome: Constructive and promising interaction with interest in the product."
291
+ elif negative_count > positive_count:
292
+ summary += "\nOutcome: Interaction may need further follow-up or clarification on product features."
293
+ else:
294
+ summary += "\nOutcome: Neutral interaction, potential for future engagement or inquiry."
295
+
296
+ return summary
297
 
298
  def add_to_sentiment_history(text, sentiment_label, sentiment_score, closest_objection, response):
299
  st.session_state.sentiment_history.append({
 
372
  - **Changelog**: We release regular updates to improve performance. Please refer to the changelog for new features and improvements.
373
  - **How to Update**: If an update is available, follow the instructions in the settings tab to install the latest version.
374
  """)
375
+ def calculate_overall_sentiment(sentiment_scores):
376
+ if sentiment_scores:
377
+ average_sentiment = sum(sentiment_scores) / len(sentiment_scores)
378
+ overall_sentiment = (
379
+ "POSITIVE" if average_sentiment > 0 else
380
+ "NEGATIVE" if average_sentiment < 0 else
381
+ "NEUTRAL"
382
+ )
383
+ else:
384
+ overall_sentiment = "NEUTRAL"
385
+ return overall_sentiment
386
 
387
  def process_real_time_audio():
388
  recognizer = sr.Recognizer()
 
390
 
391
  st.write("Adjusting microphone for ambient noise... Please wait.")
392
  with microphone as source:
393
+ recognizer.adjust_for_ambient_noise(source,duration=2)
394
 
395
  st.write("Listening for audio... Speak into the microphone.")
396
  while True:
 
398
  with microphone as source:
399
  audio = recognizer.listen(source, timeout=15, phrase_time_limit=20)
400
 
401
+
402
+
403
  st.write("Transcribing audio...")
404
  transcribed_text = recognizer.recognize_google(audio)
405
  st.write(f"You said: {transcribed_text}")
 
409
  break
410
 
411
  st.markdown("### **Sentiment Analysis**")
412
+ sentiment_label, sentiment_score = analyze_sentiment(transcribed_text)
413
  st.write(f"Sentiment: {sentiment_label}")
414
  st.write(f"Sentiment Score: {sentiment_score}")
415
 
 
430
  st.write(f"Objection: {closest_objection}")
431
  st.write(f" Response: {response}")
432
 
433
+ update_google_sheet(
434
+ transcribed_text=transcribed_text,
435
+ sentiment=f"{sentiment_label} ({sentiment_score})",
436
+ objection=f"Objection: {closest_objection} | Response: {response}",
437
+ recommendations=str(recommendations),
438
+ overall_sentiment=f"{sentiment_label}"
439
+ )
440
 
441
  except sr.UnknownValueError:
442
  st.warning("Could not understand the audio.")
443
  except Exception as e:
444
  st.error(f"Error: {e}")
445
  break
446
+
447
  def generate_sentiment_pie_chart(sentiment_history):
448
  if not sentiment_history:
449
  st.warning("No sentiment history available to generate a pie chart.")
450
  return
451
 
452
+ # Initialize sentiment counts
453
  sentiment_counts = {
454
  "Positive": 0,
455
  "Negative": 0,
 
457
  }
458
 
459
  for entry in sentiment_history:
460
+ sentiment = entry["Sentiment"].capitalize() # Normalize to match "Positive", "Negative", "Neutral"
461
+ if sentiment in sentiment_counts:
462
+ sentiment_counts[sentiment] += 1
463
+ else:
464
+ # Handle unknown sentiment values gracefully
465
+ st.warning(f"Unknown sentiment encountered: {entry['Sentiment']}")
466
 
467
+ # Create the pie chart (using matplotlib or any charting library)
468
+ labels = list(sentiment_counts.keys())
469
+ sizes = list(sentiment_counts.values())
470
+ colors = ['#6dcf6d', '#f76c6c', '#6c8df7']
471
+
472
 
473
  fig, ax = plt.subplots()
474
  plt.figure(figsize=(6,6))
 
488
  summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
489
  combined_text = " ".join([item["Text"] for item in sentiment_history])
490
 
491
+ # summary = summarizer(combined_text, max_length=100, min_length=30, do_sample=False)[0]["summary_text"]
492
  scores = [item["Score"] for item in sentiment_history]
 
 
 
 
 
 
 
 
493
 
494
  st.markdown("## Summary of the Call")
495
+ chunks = [(entry["Text"], entry["Sentiment"]) for entry in sentiment_history]
496
+ summary = generate_comprehensive_summary(chunks)
497
  st.write(summary)
498
 
499
  st.markdown("### **Overall Sentiment for the Call**")
500
+ sentiment_scores = [entry["Score"] for entry in sentiment_history]
501
+ overall_sentiment = calculate_overall_sentiment(sentiment_scores)
502
  st.write(f"Overall Sentiment: {overall_sentiment}")
 
 
503
 
504
  col1,col2=st.columns(2)
505
  with col1:
 
618
  else:
619
  st.warning("No feedback submitted yet.")
620
 
 
 
621
 
622
  file_path = csv_file_path
623
  data = load_csv(file_path)