tanish78 commited on
Commit
9e4af49
Β·
verified Β·
1 Parent(s): fa015cf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +121 -51
app.py CHANGED
@@ -11,46 +11,38 @@ import plotly.express as px
11
  from PIL import Image
12
 
13
  categories_keywords = {
14
- "Application Status": ["application status", "application", "status", "submitted", "processing", "pending", "approval", "rejected", "accepted"],
15
- "Volunteering": ["volunteer", "volunteering", "help out", "assist", "volunteer work", "volunteer opportunities"],
16
- "Certificates": ["certificate", "certificates", "completion", "certification", "accreditation", "proof", "document", "certified"],
17
- "Job Opportunities": ["job", "opportunity", "career", "vacancy", "position", "employment", "hiring", "recruitment", "internship"],
18
- "Surveys and Forms": ["survey", "form", "forms", "questionnaire", "feedback form", "response", "fill out", "submission"],
19
- "General Queries": ["hello", "hi", "help", "general", "query", "question", "info", "information", "inquiry", "ask"],
20
- "Spam": ["spam", "subscribe", "remove", "stop", "junk", "block", "opt-out", "watch my video", "click on this link", "win prize"],
21
- "Rescheduling and Postponing": ["reschedule", "postpone", "delay", "change date", "new time", "rearrange", "shift", "adjust timing"],
22
- "Contact and Communication Issues": ["contact", "communicate", "communication", "reach out", "phone", "email", "address", "details"],
23
- "Email and Credentials Issues": ["email", "credentials", "login", "password", "access", "username", "account", "verification", "reset"],
24
- "Timing and Scheduling": ["timing", "schedule", "scheduling", "time", "appointment", "availability", "calendar", "book", "slot"],
25
- "Salary and Benefits": ["salary", "benefits", "pay", "compensation", "wages", "earnings", "package", "remuneration", "incentives"],
26
- "Technical Issues": ["technical", "issue", "problem", "error", "bug", "glitch", "fix", "troubleshoot", "support"],
27
- "End of Conversation": ["bye", "thank you", "thanks", "goodbye", "see you", "later", "end", "close", "sign off"],
28
- "Start of Conversation": ["start", "begin", "hello", "hi", "initiate", "greet", "greeting", "open", "commence"],
29
- "Feedback": ["feedback", "comments", "review", "opinion", "suggestion", "critique", "rating"],
30
- "Online Meetings": ["meeting", "meeting code", "passcode", "join meeting", "zoom", "zoom link"],
31
- "Event Inquiries": ["event", "webinar", "meeting", "conference", "session", "seminar", "workshop", "invitation"],
32
- "Payment Issues": ["payment", "billing", "transaction", "charge", "fee", "invoice", "refund", "receipt"],
33
- "Registration Issues": ["registration", "register", "sign up", "enroll", "join", "signup", "enrollment"],
34
- "Service Requests": ["service", "support", "request", "assistance", "help", "aid", "maintenance"],
35
- "Account Issues": ["account", "profile", "update", "activation", "deactivation", "credentials", "reset"],
36
- "Product Information": ["product", "service", "details", "info", "information", "specifications", "features"],
37
- "Order Status": ["order", "status", "tracking", "shipment", "delivery", "purchase", "dispatch"],
38
- "Miscellaneous": []
39
  }
40
 
 
41
  def categorize_question(question):
42
- words = question.split()
43
- if len(words) == 1:
44
- single_word = words[0].lower()
45
- if any(single_word in keyword for keyword in categories_keywords["Start of Conversation"]):
46
- return "Start of Conversation"
47
- else:
48
- return "End of Conversation"
49
-
50
  for category, keywords in categories_keywords.items():
51
- if any(keyword.lower() in question.lower() for keyword in keywords):
52
- return category
53
- return "Miscellaneous"
 
 
 
 
 
 
 
 
54
 
55
  def preprocess_data(df):
56
  df.rename(columns={'Question Asked': 'texts'}, inplace=True)
@@ -103,6 +95,7 @@ def preprocess_data(df):
103
  df['texts'] = df['texts'].str.strip()
104
  df = df[df['texts'] != '']
105
 
 
106
  df['Category'] = df['texts'].apply(categorize_question)
107
 
108
  return df
@@ -133,7 +126,7 @@ def generate_wordcloud(df):
133
  scale=2,
134
  relative_scaling=0.5,
135
  random_state=42
136
- ).generate(text[:1000000]) # Limit the text length to 1,000,000 characters to avoid memory issues
137
 
138
  plt.figure(figsize=(15, 7))
139
  plt.imshow(wordcloud, interpolation='bilinear')
@@ -145,21 +138,14 @@ def generate_wordcloud(df):
145
  return img
146
 
147
  def generate_bar_chart(df, num_clusters_to_display):
 
148
  common_words = {'i', 'you', 'thanks', 'thank', 'ok', 'okay', 'sure', 'done'}
149
 
150
  top_categories = df['Category'].value_counts().index[:num_clusters_to_display]
151
  df_top_categories = df[df['Category'].isin(top_categories)]
152
 
153
- def extract_top_words(texts, n=1):
154
- vec = TfidfVectorizer(stop_words='english').fit(texts)
155
- sum_words = vec.transform(texts).sum(axis=0)
156
- words_freq = [(word, sum_words[0, idx]) for word, idx in vec.vocabulary_.items()]
157
- sorted_words = sorted(words_freq, key=lambda x: x[1], reverse=True)
158
- return [word for word, freq in sorted_words if word not in common_words][:n]
159
-
160
- category_top_words = df_top_categories.groupby('Category')['texts'].apply(lambda texts: extract_top_words(texts, 3)).reset_index()
161
- category_top_words['top_word'] = category_top_words['texts'].apply(lambda words: ', '.join(words))
162
-
163
  category_sizes = df_top_categories['Category'].value_counts().reset_index()
164
  category_sizes.columns = ['Category', 'Count']
165
  category_sizes = category_sizes.merge(category_top_words[['Category', 'top_word']], on='Category')
@@ -178,15 +164,30 @@ def main(file, num_clusters_to_display):
178
  try:
179
  df = pd.read_csv(file)
180
 
 
181
  df = df[df['Answer'] == 'Fallback Message shown']
182
 
183
  df = preprocess_data(df)
184
 
185
- wordcloud_img = generate_wordcloud(df)
186
- bar_chart_img = generate_bar_chart(df, num_clusters_to_display)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
  with tempfile.NamedTemporaryFile(delete=False, suffix=".csv") as tmpfile:
189
- df.to_csv(tmpfile.name, index=False)
190
  csv_file_path = tmpfile.name
191
 
192
  return csv_file_path, wordcloud_img, bar_chart_img
@@ -198,7 +199,7 @@ interface = gr.Interface(
198
  fn=main,
199
  inputs=[
200
  gr.File(label="Upload CSV File (.csv)"),
201
- gr.Slider(label="Number of Categories to Display", minimum=1, maximum=15, step=1, value=5)
202
  ],
203
  outputs=[
204
  gr.File(label="Categorized Data CSV"),
@@ -210,3 +211,72 @@ interface = gr.Interface(
210
  )
211
 
212
  interface.launch(share=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  from PIL import Image
12
 
13
  categories_keywords = {
14
+ 'Application Status': ['application', 'applied', 'update on my application', 'result of my application', 'selected', 'selection process', 'apply', 'fellow', 'lesson plan', 'status of my application', 'application update', 'application status', 'applied for'],
15
+ 'Volunteering': ['volunteering', 'volunteer', 'volunteering certificate', 'resume my volunteering', 'volunteering journey', 'volunteering with TFI', 'volunteering opportunities', 'volunteer work', 'volunteer program'],
16
+ 'Certificates': ['certificate', 'certificates', 'certificate of completion', 'volunteer certificate', 'issue certificate'],
17
+ 'Job Opportunities': ['job', 'vacancy', 'Talent Acquisition Executive job', 'opportunity', 'job opening', 'job position', 'career opportunities'],
18
+ 'Surveys and Forms': ['survey', 'form', 'fill out the survey', 'application form', 'survey link', 'survey form', 'form submission'],
19
+ 'General Queries': ['query', 'queries', 'questions', 'feedback', 'loved', 'overwhelming', 'general question', 'inquiry', 'query about'],
20
+ 'Spam': ['free recharge', 'offer', 'click the link', 'https'],
21
+ 'Rescheduling and Postponing': ['reschedule', 'postpone', 'cancellation', 'date', 'time slot', 'change date', 'change time', 'reschedule appointment'],
22
+ 'Contact and Communication Issues': ['call', 'phone', 'contact', 'not received', 'contact support', 'phone call', 'call back', 'internet'],
23
+ 'Email and Credentials Issues': ['email', 'credentials', 'received', 'email issue', 'email problem', 'credential issue', 'login problem'],
24
+ 'Timing and Scheduling': ['session', 'time', 'interview', 'baje', 'schedule time', 'meeting time', 'appointment time'],
25
+ 'Salary and Benefits': ['salary', 'increment', 'accommodation', 'training period', 'reside', 'stipend', 'pay', 'wage', 'salary details', 'benefits information'],
26
+ 'Technical Issues': ['network issues', 'zoom meeting', 'passcode', 'technical', 'issue','technical problem', 'system issue', 'technical support'],
27
+ 'Complaint Handling': ['help', 'i need help', 'Help me', 'complaint', 'issue is unresolved', 'unsatisfied', 'bad experience'],
28
+ 'End of Conversation': ['thanks', 'thankss', 'thank u', 'thank you', 'ok', 'okay', 'done', 'joining', 'sounds good', 'goodbye', 'end chat', 'end'],
29
+ 'Miscellaneous': []
 
 
 
 
 
 
 
 
 
30
  }
31
 
32
+
33
  def categorize_question(question):
 
 
 
 
 
 
 
 
34
  for category, keywords in categories_keywords.items():
35
+ for keyword in keywords:
36
+ if keyword.lower() in question.lower():
37
+ # Check if the question is one word and belongs to 'End of Conversation'
38
+ if category == 'End of Conversation':
39
+ return category
40
+ # If not 'End of Conversation', return the matched category
41
+ if category != 'End of Conversation':
42
+ return category
43
+ return 'Miscellaneous'
44
+
45
+
46
 
47
  def preprocess_data(df):
48
  df.rename(columns={'Question Asked': 'texts'}, inplace=True)
 
95
  df['texts'] = df['texts'].str.strip()
96
  df = df[df['texts'] != '']
97
 
98
+ # Categorize the texts
99
  df['Category'] = df['texts'].apply(categorize_question)
100
 
101
  return df
 
126
  scale=2,
127
  relative_scaling=0.5,
128
  random_state=42
129
+ ).generate(text)
130
 
131
  plt.figure(figsize=(15, 7))
132
  plt.imshow(wordcloud, interpolation='bilinear')
 
138
  return img
139
 
140
  def generate_bar_chart(df, num_clusters_to_display):
141
+ # Exclude common words from the top words
142
  common_words = {'i', 'you', 'thanks', 'thank', 'ok', 'okay', 'sure', 'done'}
143
 
144
  top_categories = df['Category'].value_counts().index[:num_clusters_to_display]
145
  df_top_categories = df[df['Category'].isin(top_categories)]
146
 
147
+ category_top_words = df_top_categories.groupby('Category', observed=False)['texts'].apply(lambda x: ' '.join(x)).reset_index()
148
+ category_top_words['top_word'] = category_top_words['texts'].apply(lambda x: ' '.join([word for word in pd.Series(x.split()).value_counts().index if word not in common_words][:3]))
 
 
 
 
 
 
 
 
149
  category_sizes = df_top_categories['Category'].value_counts().reset_index()
150
  category_sizes.columns = ['Category', 'Count']
151
  category_sizes = category_sizes.merge(category_top_words[['Category', 'top_word']], on='Category')
 
164
  try:
165
  df = pd.read_csv(file)
166
 
167
+ # Filter by 'Fallback Message shown'
168
  df = df[df['Answer'] == 'Fallback Message shown']
169
 
170
  df = preprocess_data(df)
171
 
172
+ # Get category sizes and sort by size in ascending order
173
+ category_sizes = df['Category'].value_counts().reset_index()
174
+ category_sizes.columns = ['Category', 'Count']
175
+ sorted_categories = category_sizes.sort_values(by='Count', ascending=True)['Category'].tolist()
176
+
177
+ # Get the largest x categories as specified by num_clusters_to_display
178
+ largest_categories = sorted_categories[:num_clusters_to_display]
179
+
180
+ # Filter the dataframe to include only the largest categories
181
+ filtered_df = df[df['Category'].isin(largest_categories)]
182
+
183
+ # Sort the dataframe by Category
184
+ filtered_df = filtered_df.sort_values(by='Category')
185
+
186
+ wordcloud_img = generate_wordcloud(filtered_df)
187
+ bar_chart_img = generate_bar_chart(filtered_df, num_clusters_to_display)
188
 
189
  with tempfile.NamedTemporaryFile(delete=False, suffix=".csv") as tmpfile:
190
+ filtered_df.to_csv(tmpfile.name, index=False)
191
  csv_file_path = tmpfile.name
192
 
193
  return csv_file_path, wordcloud_img, bar_chart_img
 
199
  fn=main,
200
  inputs=[
201
  gr.File(label="Upload CSV File (.csv)"),
202
+ gr.Slider(label="Number of Categories to Display", minimum=1, maximum=10, step=1, value=5)
203
  ],
204
  outputs=[
205
  gr.File(label="Categorized Data CSV"),
 
211
  )
212
 
213
  interface.launch(share=True)
214
+
215
+
216
+
217
+
218
+
219
+ β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------β€”--------
220
+
221
+
222
+
223
+
224
+
225
+ def main(file, bot_name, num_clusters_to_display):
226
+ try:
227
+ global categories_keywords
228
+ if bot_name == "Teach For India":
229
+ categories_keywords = categories_keywords_tfi
230
+ else:
231
+ categories_keywords = categories_keywords_firki
232
+
233
+ df = pd.read_csv(file.name)
234
+
235
+ df = df[df['Answer'] == 'Fallback Message shown']
236
+
237
+ df = preprocess_data(df, categories_keywords)
238
+
239
+ category_sizes = df['Category'].value_counts().reset_index()
240
+ category_sizes.columns = ['Category', 'Count']
241
+ sorted_categories = category_sizes.sort_values(by='Count', ascending=True)['Category'].tolist()
242
+
243
+ largest_categories = sorted_categories[:num_clusters_to_display]
244
+
245
+ filtered_df = df[df['Category'].isin(largest_categories)]
246
+
247
+ filtered_df = filtered_df.sort_values(by='Category')
248
+
249
+ wordcloud_img = generate_wordcloud(filtered_df)
250
+ bar_chart_img = generate_bar_chart(df, num_clusters_to_display)
251
+
252
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".csv") as tmpfile:
253
+ filtered_df.to_csv(tmpfile.name, index=False)
254
+ csv_file_path = tmpfile.name
255
+
256
+ return csv_file_path, wordcloud_img, bar_chart_img
257
+ except Exception as e:
258
+ print(f"Error: {e}")
259
+ return str(e), None, None
260
+
261
+ def categorize_unanswered_queries(bot_name, file, num_clusters_to_display):
262
+ return main(file, bot_name, num_clusters_to_display)
263
+
264
+ interface = gr.Interface(
265
+ fn=categorize_unanswered_queries,
266
+ inputs=[
267
+ gr.Radio(["Teach For India", "Firki"], label="Select ChatBot"),
268
+ gr.File(label="Upload CSV File (.csv)"),
269
+ gr.Slider(label="Number of Categories to Display", minimum=1, maximum=10, step=1, value=5)
270
+ ],
271
+ outputs=[
272
+ gr.File(label="Categorized Data CSV"),
273
+ gr.Image(label="Word Cloud"),
274
+ gr.Image(label="Bar Chart")
275
+ ],
276
+ title="Unanswered User Queries Categorization",
277
+ description="Select the bot, upload the CSV file, and specify the number of categories to display to categorize unanswered user queries."
278
+ )
279
+
280
+ interface.launch()
281
+
282
+