kambris commited on
Commit
a0b6552
·
verified ·
1 Parent(s): bf19518

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -76
app.py CHANGED
@@ -128,57 +128,61 @@ class SpeechAnalyzer:
128
  return aggregated_scores
129
 
130
  def analyze_emotional_trajectory(self, text, window_size=5):
131
- """Enhanced emotional trajectory analysis using batch processing"""
132
  segments = self.split_text(text, max_length=512)
133
  sentiment_scores = []
 
 
 
 
134
 
135
  for segment in segments:
136
- # Split into sentences using NLTK
137
  sentences = nltk.sent_tokenize(segment)
138
-
139
- # Process sentences in batches
140
  batch_size = 64
141
  segment_scores = []
 
142
 
143
  for i in range(0, len(sentences), batch_size):
144
  batch = sentences[i:i+batch_size]
 
 
145
 
 
146
  try:
147
- # Pad or truncate sentences to ensure consistent length
148
- batch = [sent[:512] for sent in batch] # Truncate to max model input
149
-
150
- # Ensure all sentences are strings and non-empty
151
- batch = [sent if sent.strip() else "." for sent in batch]
152
-
153
  results = self.sentiment_pipeline(batch)
154
-
155
- # Process batch results
156
  batch_scores = []
157
  for result in results:
158
- # Convert to signed score (-1 to 1 range)
159
  score = result['score']
160
- score = score * 2 - 1 if result['label'] == 'POSITIVE' else -score
 
 
 
 
161
  batch_scores.append(score)
162
-
163
  segment_scores.extend(batch_scores)
164
-
 
 
 
 
 
 
 
 
 
165
  except Exception as e:
166
  print(f"Batch processing error: {e}")
167
- # Fallback to individual processing if batch fails
168
- for sent in batch:
169
- try:
170
- result = self.sentiment_pipeline(sent)[0]
171
- score = result['score']
172
- score = score * 2 - 1 if result['label'] == 'POSITIVE' else -score
173
- segment_scores.append(score)
174
- except:
175
- segment_scores.append(0)
176
 
177
- # Calculate average score for the segment
178
- avg_score = np.mean(segment_scores) if segment_scores else 0
179
- sentiment_scores.append(avg_score)
 
 
 
180
 
181
- return sentiment_scores
182
 
183
  def detect_named_entities(self, text):
184
  """Detect named entities in the text"""
@@ -331,78 +335,68 @@ def main():
331
  st.write(f"**{MORAL_FOUNDATIONS[foundation]}**: {score:.2%}")
332
 
333
  with tab2:
334
- status_text.text('Processing Emotional Trajectory...')
335
- progress_bar.progress(40)
336
  st.subheader("Speech Trajectory Analysis")
337
- col1, col2 = st.columns(2)
338
 
339
- # Create consistent segments for both analyses
340
  segments = analyzer.split_text(text, max_length=512)
341
  num_segments = len(segments)
342
  segment_labels = [f"{i+1}" for i in range(num_segments)]
343
 
 
 
344
  with col1:
345
- st.write("### Emotional Flow")
346
- sentiment_scores = analyzer.analyze_emotional_trajectory(text)
347
-
348
- trajectory_fig = go.Figure(data=go.Scatter(
349
  x=segment_labels,
350
  y=sentiment_scores,
351
  mode='lines+markers',
352
  line=dict(color='#1f77b4', width=3),
353
- marker=dict(size=8, color='#1f77b4', symbol='circle')
 
 
 
 
354
  ))
355
 
356
- trajectory_fig.update_layout(
357
- title='Emotional Flow Throughout the Speech',
358
  xaxis_title='Speech Segments',
359
- yaxis_title='Relative Emotional Tone',
360
  yaxis=dict(
361
- ticktext=['Most Negative', 'Neutral', 'Most Positive'],
362
- tickvals=[-1, 0, 1],
363
- range=[-1.1, 1.1],
364
  gridcolor='lightgray'
365
  ),
366
- hovermode='x unified',
367
- showlegend=False,
368
  plot_bgcolor='white'
369
  )
370
-
371
- st.plotly_chart(trajectory_fig)
372
 
373
- with col2:
374
- st.write("### Moral Foundations Flow")
375
- moral_trajectories = {foundation: [] for foundation in MORAL_FOUNDATIONS}
376
-
377
- for segment in segments:
378
- segment_scores = analyzer.analyze_moral_foundations(segment)
379
- for foundation, score in segment_scores.items():
380
- moral_trajectories[foundation].append(score)
381
 
382
- moral_fig = go.Figure()
383
- for foundation, scores in moral_trajectories.items():
384
- moral_fig.add_trace(go.Scatter(
385
- x=segment_labels,
386
- y=scores,
387
- name=MORAL_FOUNDATIONS[foundation],
388
- mode='lines+markers'
389
- ))
390
 
391
- moral_fig.update_layout(
392
- title='Moral Foundations Flow',
393
  xaxis_title='Speech Segments',
394
- yaxis_title='Foundation Strength',
395
- hovermode='x unified',
396
- plot_bgcolor='white',
397
  showlegend=True,
398
- legend=dict(
399
- yanchor="top",
400
- y=0.99,
401
- xanchor="left",
402
- x=1.05
403
- )
404
  )
405
- st.plotly_chart(moral_fig)
406
 
407
  with tab3:
408
  status_text.text('Analyzing Linguistic Features...')
 
128
  return aggregated_scores
129
 
130
  def analyze_emotional_trajectory(self, text, window_size=5):
131
+ """Enhanced emotional trajectory analysis with basic emotions"""
132
  segments = self.split_text(text, max_length=512)
133
  sentiment_scores = []
134
+ basic_emotions = []
135
+
136
+ # Add emotion classifier pipeline
137
+ emotion_classifier = pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base", return_all_scores=True)
138
 
139
  for segment in segments:
 
140
  sentences = nltk.sent_tokenize(segment)
 
 
141
  batch_size = 64
142
  segment_scores = []
143
+ segment_emotions = []
144
 
145
  for i in range(0, len(sentences), batch_size):
146
  batch = sentences[i:i+batch_size]
147
+ batch = [sent[:512] for sent in batch]
148
+ batch = [sent if sent.strip() else "." for sent in batch]
149
 
150
+ # Get sentiment scores
151
  try:
 
 
 
 
 
 
152
  results = self.sentiment_pipeline(batch)
 
 
153
  batch_scores = []
154
  for result in results:
 
155
  score = result['score']
156
+ # Enhanced score scaling for better visualization
157
+ if result['label'] == 'POSITIVE':
158
+ score = 0.5 + (score * 0.5) # Scale from 0.5 to 1.0
159
+ else:
160
+ score = 0.5 - (score * 0.5) # Scale from 0.0 to 0.5
161
  batch_scores.append(score)
 
162
  segment_scores.extend(batch_scores)
163
+
164
+ # Get emotion classifications
165
+ emotion_results = emotion_classifier(batch)
166
+ batch_emotions = []
167
+ for result in emotion_results:
168
+ # Get the dominant emotion
169
+ dominant_emotion = max(result[0], key=lambda x: x['score'])
170
+ batch_emotions.append(dominant_emotion['label'])
171
+ segment_emotions.extend(batch_emotions)
172
+
173
  except Exception as e:
174
  print(f"Batch processing error: {e}")
175
+ segment_scores.extend([0.5] * len(batch))
176
+ segment_emotions.extend(['neutral'] * len(batch))
 
 
 
 
 
 
 
177
 
178
+ sentiment_scores.append(np.mean(segment_scores))
179
+ # Get most frequent emotion in segment
180
+ if segment_emotions:
181
+ basic_emotions.append(max(set(segment_emotions), key=segment_emotions.count))
182
+ else:
183
+ basic_emotions.append('neutral')
184
 
185
+ return sentiment_scores, basic_emotions
186
 
187
  def detect_named_entities(self, text):
188
  """Detect named entities in the text"""
 
335
  st.write(f"**{MORAL_FOUNDATIONS[foundation]}**: {score:.2%}")
336
 
337
  with tab2:
 
 
338
  st.subheader("Speech Trajectory Analysis")
339
+ col1, col2, col3 = st.columns(3)
340
 
 
341
  segments = analyzer.split_text(text, max_length=512)
342
  num_segments = len(segments)
343
  segment_labels = [f"{i+1}" for i in range(num_segments)]
344
 
345
+ sentiment_scores, basic_emotions = analyzer.analyze_emotional_trajectory(text)
346
+
347
  with col1:
348
+ st.write("### Sentiment Flow")
349
+ sentiment_fig = go.Figure(data=go.Scatter(
 
 
350
  x=segment_labels,
351
  y=sentiment_scores,
352
  mode='lines+markers',
353
  line=dict(color='#1f77b4', width=3),
354
+ marker=dict(
355
+ size=8,
356
+ color=['#ff0000' if score < 0.4 else '#00ff00' if score > 0.6 else '#888888' for score in sentiment_scores],
357
+ symbol='circle'
358
+ )
359
  ))
360
 
361
+ sentiment_fig.update_layout(
362
+ title='Sentiment Throughout Speech',
363
  xaxis_title='Speech Segments',
364
+ yaxis_title='Sentiment',
365
  yaxis=dict(
366
+ ticktext=['Very Negative', 'Negative', 'Neutral', 'Positive', 'Very Positive'],
367
+ tickvals=[0, 0.25, 0.5, 0.75, 1],
368
+ range=[0, 1],
369
  gridcolor='lightgray'
370
  ),
 
 
371
  plot_bgcolor='white'
372
  )
373
+ st.plotly_chart(sentiment_fig)
 
374
 
375
+ # Rest of the code remains the same for col2 (Moral Foundations)
376
+
377
+ with col3:
378
+ st.write("### Basic Emotions")
379
+ emotions_df = pd.DataFrame({
380
+ 'Segment': segment_labels,
381
+ 'Emotion': basic_emotions
382
+ })
383
 
384
+ emotions_fig = px.bar(
385
+ emotions_df,
386
+ x='Segment',
387
+ y='Emotion',
388
+ color='Emotion',
389
+ title='Basic Emotions Flow',
390
+ category_orders={'Emotion': ['joy', 'sadness', 'anger', 'fear', 'surprise', 'neutral']}
391
+ )
392
 
393
+ emotions_fig.update_layout(
 
394
  xaxis_title='Speech Segments',
395
+ yaxis_title='Emotion',
 
 
396
  showlegend=True,
397
+ plot_bgcolor='white'
 
 
 
 
 
398
  )
399
+ st.plotly_chart(emotions_fig)
400
 
401
  with tab3:
402
  status_text.text('Analyzing Linguistic Features...')