hatimanees commited on
Commit
1e09cd2
·
verified ·
1 Parent(s): 6ba05d6

Update run.py

Browse files
Files changed (1) hide show
  1. run.py +149 -6
run.py CHANGED
@@ -1,6 +1,149 @@
1
- from app import create_app
2
-
3
- app = create_app()
4
-
5
- if __name__ == "__main__":
6
- app.run(host="0.0.0.0", port=5000)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify
2
+ from flask_cors import CORS
3
+ import os
4
+ from transformers import pipeline
5
+ import numpy as np
6
+ import torch
7
+ import re
8
+ from werkzeug.utils import secure_filename
9
+ import uuid
10
+
11
+
12
+ class Config:
13
+ UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
14
+ MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB max file size
15
+ CORS_HEADERS = 'Content-Type'
16
+
17
+
18
+ class DialogueSentimentAnalyzer:
19
+ def __init__(self, model_name: str = "microsoft/DialogRPT-updown"):
20
+ self.device = 0 if torch.cuda.is_available() else -1
21
+ self.dialogue_model = pipeline(
22
+ 'text-classification',
23
+ model="microsoft/DialogRPT-updown",
24
+ device=self.device
25
+ )
26
+ self.sentiment_model = pipeline(
27
+ 'sentiment-analysis',
28
+ model="distilbert-base-uncased-finetuned-sst-2-english",
29
+ device=self.device
30
+ )
31
+ self.max_length = 512
32
+
33
+ def parse_dialogue(self, text: str):
34
+ lines = text.strip().split('\n')
35
+ dialogue = []
36
+ current_speaker = None
37
+ current_text = []
38
+
39
+ for line in lines:
40
+ line = line.strip()
41
+ if not line:
42
+ continue
43
+
44
+ speaker_match = re.match(r'^([^:]+):', line)
45
+ if speaker_match:
46
+ if current_speaker and current_text:
47
+ dialogue.append({'speaker': current_speaker, 'text': ' '.join(current_text)})
48
+ current_speaker = speaker_match.group(1)
49
+ current_text = [line[len(current_speaker) + 1:].strip()]
50
+ else:
51
+ if current_speaker:
52
+ current_text.append(line.strip())
53
+
54
+ if current_speaker and current_text:
55
+ dialogue.append({'speaker': current_speaker, 'text': ' '.join(current_text)})
56
+
57
+ return dialogue
58
+
59
+ def analyze_utterance(self, utterance):
60
+ text = utterance['text']
61
+ dialogue_score = self.dialogue_model(text)[0]
62
+ sentiment = self.sentiment_model(text)[0]
63
+ positive_phrases = ['thank you', 'thanks', 'appreciate', 'great', 'perfect', 'looking forward', 'flexible', 'competitive']
64
+ negative_phrases = ['concerned', 'worry', 'issue', 'problem', 'difficult', 'unfortunately', 'sorry']
65
+ text_lower = text.lower()
66
+ positive_count = sum(1 for phrase in positive_phrases if phrase in text_lower)
67
+ negative_count = sum(1 for phrase in negative_phrases if phrase in text_lower)
68
+ sentiment_score = float(sentiment['score'])
69
+ if sentiment['label'] == 'NEGATIVE':
70
+ sentiment_score = 1 - sentiment_score
71
+ final_score = sentiment_score
72
+ if positive_count > negative_count:
73
+ final_score = min(1.0, final_score + 0.1 * (positive_count - negative_count))
74
+ elif negative_count > positive_count:
75
+ final_score = max(0.0, final_score - 0.1 * (negative_count - positive_count))
76
+
77
+ return {
78
+ 'speaker': utterance['speaker'],
79
+ 'text': text,
80
+ 'sentiment_score': final_score,
81
+ 'engagement_score': float(dialogue_score['score']),
82
+ 'positive_phrases': positive_count,
83
+ 'negative_phrases': negative_count
84
+ }
85
+
86
+ def analyze_dialogue(self, text: str):
87
+ dialogue = self.parse_dialogue(text)
88
+ utterance_results = [self.analyze_utterance(utterance) for utterance in dialogue]
89
+ overall_sentiment = np.mean([r['sentiment_score'] for r in utterance_results])
90
+ overall_engagement = np.mean([r['engagement_score'] for r in utterance_results])
91
+ sentiment_variance = np.std([r['sentiment_score'] for r in utterance_results])
92
+ confidence = max(0.0, 1.0 - sentiment_variance)
93
+ speaker_sentiments = {}
94
+ for result in utterance_results:
95
+ if result['speaker'] not in speaker_sentiments:
96
+ speaker_sentiments[result['speaker']] = []
97
+ speaker_sentiments[result['speaker']].append(result['sentiment_score'])
98
+ speaker_averages = {speaker: np.mean(scores) for speaker, scores in speaker_sentiments.items()}
99
+ return [{'label': 'Overall Sentiment', 'score': float(overall_sentiment)},
100
+ {'label': 'Confidence', 'score': float(confidence)},
101
+ {'label': 'Engagement', 'score': float(overall_engagement)}] + [
102
+ {'label': f'{speaker} Sentiment', 'score': float(score)} for speaker, score in speaker_averages.items()
103
+ ]
104
+
105
+
106
+ def save_uploaded_file(content, upload_folder):
107
+ filename = f"{uuid.uuid4().hex}.txt"
108
+ file_path = os.path.join(upload_folder, secure_filename(filename))
109
+ with open(file_path, 'w', encoding='utf-8') as f:
110
+ f.write(content)
111
+ return file_path
112
+
113
+
114
+ def analyze_sentiment(file_path: str):
115
+ try:
116
+ analyzer = DialogueSentimentAnalyzer()
117
+ with open(file_path, 'r', encoding='utf-8') as f:
118
+ text = f.read()
119
+ return analyzer.analyze_dialogue(text)
120
+ except Exception as e:
121
+ print(f"Error in sentiment analysis: {str(e)}")
122
+ return [{'label': 'Error', 'score': 0.5}]
123
+
124
+
125
+ def create_app():
126
+ app = Flask(__name__)
127
+ app.config.from_object(Config)
128
+ CORS(app)
129
+ os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
130
+
131
+ @app.route('/upload', methods=['POST'])
132
+ def upload_transcript():
133
+ try:
134
+ transcript = request.form.get('transcript')
135
+ if not transcript:
136
+ return jsonify({'error': 'No transcript received'}), 400
137
+ file_path = save_uploaded_file(transcript, app.config['UPLOAD_FOLDER'])
138
+ sentiment_result = analyze_sentiment(file_path)
139
+ os.remove(file_path)
140
+ return jsonify({'sentiment': sentiment_result}), 200
141
+ except Exception as e:
142
+ return jsonify({'error': str(e)}), 500
143
+
144
+ return app
145
+
146
+
147
+ if __name__ == '__main__':
148
+ app = create_app()
149
+ app.run(host="0.0.0.0", port=5000)