Nattapong Tapachoom commited on
Commit
4848f58
·
1 Parent(s): 8142326

Refactor sentiment analysis to support multiple models and enhance UI for multi-sentence input

Browse files
Files changed (1) hide show
  1. app.py +143 -65
app.py CHANGED
@@ -1,8 +1,29 @@
1
  import gradio as gr
2
  from transformers import pipeline
3
 
4
- model_name = "ZombitX64/MultiSent-E5"
5
- nlp = pipeline("sentiment-analysis", model=model_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  label_map = {
8
  "LABEL_0": 0,
@@ -17,7 +38,7 @@ label_name_map = {
17
  "LABEL_3": "positive"
18
  }
19
 
20
- def analyze_text(text):
21
  # แยกประโยคโดยใช้ \n หรือจุด
22
  import re
23
  sentences = [s.strip() for s in re.split(r'[.\n]', text) if s.strip()]
@@ -36,20 +57,16 @@ def analyze_text(text):
36
  results = []
37
  results.append("📊 **ผลการวิเคราะห์ความรู้สึก**\n" + "="*50 + "\n")
38
 
 
39
  for i, sentence in enumerate(sentences, 1):
40
  result = nlp(sentence)[0]
41
  label = result['label']
42
  score = result['score']
43
  code = label_map.get(label, -1)
44
  label_name = label_name_map.get(label, label)
45
-
46
- # ดึงสไตล์ตาม sentiment
47
  style = sentiment_style.get(label_name, {"emoji": "🔍", "color": "#666666", "bg": "#F5F5F5"})
48
-
49
- # สร้าง progress bar สำหรับความมั่นใจ
50
- bar_length = int(score * 20) # 20 คือความยาวของ progress bar
51
  progress_bar = "█" * bar_length + "░" * (20 - bar_length)
52
-
53
  result_text = f"""
54
  🔸 **ประโยคที่ {i}:** "{sentence}"
55
 
@@ -67,68 +84,129 @@ def analyze_text(text):
67
 
68
  return "\n".join(results)
69
 
70
- demo = gr.Interface(
71
- fn=analyze_text,
72
- inputs=gr.Textbox(
73
- lines=6,
74
- placeholder="💬 พิมพ์ข้อความหลายประโยคที่นี่...\n\n✨ คำแนะนำ:\n• แยกแต่ละประโยคด้วยจุด (.) หรือขึ้นบรรทัดใหม่\n• สามารถใส่ได้หลายประโยคพร้อมกัน\n• รองรับข้อความภาษาไทย",
75
- label="📝 ข้อความที่ต้องการวิเคราะห์"
76
- ),
77
- outputs=gr.Textbox(
78
- label="📊 ผลการวิเคราะห์ความรู้สึก",
79
- lines=15,
80
- show_copy_button=True
81
- ),
82
- title="🧠 AI วิเคราะห์ความรู้สึกภาษาไทย",
83
- description="""
84
- <div style="text-align: center; padding: 20px; background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px; margin: 10px 0;">
85
- <h3>🚀 ระบบวิเคราะห์ความรู้สึกขั้นสูง</h3>
86
- <p>วิเคราะห์ความรู้สึกในข้อความภาษาไทยด้วย AI | รองรับการวิเคราะห์หลายประโยคพร้อมกัน</p>
87
- </div>
88
-
89
- <div style="display: flex; justify-content: space-around; margin: 20px 0; padding: 15px; background: #f8f9fa; border-radius: 8px;">
90
- <div style="text-align: center;">
91
- <div style="font-size: 24px;">😊</div>
92
- <strong>Positive</strong><br>
93
- <small>ความรู้สึกเชิงบวก</small>
94
- </div>
95
- <div style="text-align: center;">
96
- <div style="font-size: 24px;">😔</div>
97
- <strong>Negative</strong><br>
98
- <small>ความรู้สึกเชิงลบ</small>
99
- </div>
100
- <div style="text-align: center;">
101
- <div style="font-size: 24px;">😐</div>
102
- <strong>Neutral</strong><br>
103
- <small>ความรู้สึกเป็นกลาง</small>
104
- </div>
105
- <div style="text-align: center;">
106
- <div style="font-size: 24px;">❓</div>
107
- <strong>Question</strong><br>
108
- <small>ประโยคคำถาม</small>
109
- </div>
110
- </div>
111
- """,
112
- theme=gr.themes.Soft(
113
- primary_hue="blue",
114
- secondary_hue="purple",
115
- neutral_hue="gray"
116
- ),
117
  css="""
118
  .gradio-container {
119
  max-width: 900px !important;
120
  margin: auto !important;
 
 
 
 
 
 
 
 
 
 
121
  }
122
  .output-markdown {
123
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;
124
  }
125
- """,
126
- examples=[
127
- ["วันนี้อากาศดีมาก ฉันรู้สึกมีความสุขมาก"],
128
- ["ฉันไม่ชอบอาหารนี้ รสชาติแปลกมาก"],
129
- ["วันนี้เป็นยังไง\nเรียนหนังสือกันไหม"],
130
- ["บริการดีมาก พนักงานใจดี\nแต่ของมีราคาแพงไปหน่อย\nโดยรวมแล้วพอใจ"]
131
- ]
132
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
- demo.launch()
 
1
  import gradio as gr
2
  from transformers import pipeline
3
 
4
+
5
+ # รายชื่อโมเดลที่ให้เลือก
6
+ MODEL_LIST = [
7
+ "SandboxBhh/sentiment-thai-text-model",
8
+ "poom-sci/WangchanBERTa-finetuned-sentiment",
9
+ "Thaweewat/wangchanberta-hyperopt-sentiment-01",
10
+ "cardiffnlp/twitter-xlm-roberta-base-sentiment",
11
+ "phoner45/wangchan-sentiment-thai-text-model",
12
+ "ZombitX64/Sentiment-01",
13
+ "ZombitX64/Sentiment-02",
14
+ "ZombitX64/Sentiment-03",
15
+ "ZombitX64/MultiSent-E5-Pro",
16
+ "ZombitX64/MultiSent-E5",
17
+ "ZombitX64/Thai-sentiment-e5",
18
+ "ZombitX64/sentiment-103"
19
+ ]
20
+
21
+ from functools import lru_cache
22
+
23
+ # ใช้ cache เพื่อไม่ต้องโหลดโมเดลซ้ำ
24
+ @lru_cache(maxsize=2)
25
+ def get_nlp(model_name):
26
+ return pipeline("sentiment-analysis", model=model_name)
27
 
28
  label_map = {
29
  "LABEL_0": 0,
 
38
  "LABEL_3": "positive"
39
  }
40
 
41
+ def analyze_text(text, model_name):
42
  # แยกประโยคโดยใช้ \n หรือจุด
43
  import re
44
  sentences = [s.strip() for s in re.split(r'[.\n]', text) if s.strip()]
 
57
  results = []
58
  results.append("📊 **ผลการวิเคราะห์ความรู้สึก**\n" + "="*50 + "\n")
59
 
60
+ nlp = get_nlp(model_name)
61
  for i, sentence in enumerate(sentences, 1):
62
  result = nlp(sentence)[0]
63
  label = result['label']
64
  score = result['score']
65
  code = label_map.get(label, -1)
66
  label_name = label_name_map.get(label, label)
 
 
67
  style = sentiment_style.get(label_name, {"emoji": "🔍", "color": "#666666", "bg": "#F5F5F5"})
68
+ bar_length = int(score * 20)
 
 
69
  progress_bar = "█" * bar_length + "░" * (20 - bar_length)
 
70
  result_text = f"""
71
  🔸 **ประโยคที่ {i}:** "{sentence}"
72
 
 
84
 
85
  return "\n".join(results)
86
 
87
+
88
+ demo.launch()
89
+
90
+ with gr.Blocks(
91
+ theme=gr.themes.Soft(primary_hue="blue", secondary_hue="purple", neutral_hue="gray"),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  css="""
93
  .gradio-container {
94
  max-width: 900px !important;
95
  margin: auto !important;
96
+ background: #f4f7fa !important;
97
+ border-radius: 18px !important;
98
+ box-shadow: 0 4px 24px 0 #bdbdbd33;
99
+ }
100
+ .main-card {
101
+ background: white;
102
+ border-radius: 16px;
103
+ box-shadow: 0 2px 12px 0 #bdbdbd22;
104
+ padding: 32px 32px 24px 32px;
105
+ margin: 32px 0 24px 0;
106
  }
107
  .output-markdown {
108
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;
109
  }
110
+ .gr-button {
111
+ font-size: 1.1em;
112
+ padding: 0.7em 2em;
113
+ border-radius: 8px;
114
+ }
115
+ .gr-textbox textarea {
116
+ font-size: 1.1em;
117
+ min-height: 120px;
118
+ }
119
+ .gr-dropdown input {
120
+ font-size: 1.1em;
121
+ }
122
+ """
123
+ ) as demo:
124
+ gr.Markdown("""
125
+ <div style="text-align: center; padding: 32px 0 12px 0;">
126
+ <h1 style="font-size:2.5em; margin-bottom: 0.2em; color:#3b3b6d;">🧠 Thai Sentiment Analyzer</h1>
127
+ <div style="font-size:1.2em; color:#666;">AI วิเคราะห์ความรู้สึกในข้อความภาษาไทย รองรับหลายโมเดลและหลายประโยค</div>
128
+ </div>
129
+ """)
130
+ with gr.Row():
131
+ with gr.Column():
132
+ gr.Markdown("""
133
+ <div class='main-card'>
134
+ <h3 style='color:#4a4a7d; margin-bottom:10px;'>� เลือกโมเดลวิเคราะห์ความรู้สึก</h3>
135
+ </div>
136
+ """)
137
+ model_dropdown = gr.Dropdown(
138
+ choices=MODEL_LIST,
139
+ value="ZombitX64/MultiSent-E5",
140
+ label="โมเดลที่ต้องการใช้"
141
+ )
142
+ gr.Markdown("""
143
+ <div class='main-card' style='margin-top:18px;'>
144
+ <h3 style='color:#4a4a7d; margin-bottom:10px;'>� ตัวอย่างข้อความ</h3>
145
+ </div>
146
+ """)
147
+ examples = gr.Examples(
148
+ examples=[
149
+ ["วันนี้อากาศดีมาก ฉันรู้สึกมีความสุขมาก"],
150
+ ["ฉันไม่ชอบอาหารนี้ รสชาติแปลกมาก"],
151
+ ["วันนี้เป็นยังไง\nเรียนหนังสือกันไหม"],
152
+ ["บริการดีมาก พนักงานใจดี\nแต่ของมีราคาแพงไปหน่อย\nโดยรวมแล้วพอใจ"]
153
+ ],
154
+ inputs=None,
155
+ label="คลิกเพื่อใส่ตัวอย่างในกล่องข้อความ"
156
+ )
157
+ with gr.Column():
158
+ gr.Markdown("""
159
+ <div class='main-card'>
160
+ <h3 style='color:#4a4a7d; margin-bottom:10px;'>📝 ข้อความที่ต้องการวิเคราะห์</h3>
161
+ <div style='color:#888; font-size:1em;'>
162
+ 💬 พิมพ์ข้อความหลายประโยคที่นี่<br>
163
+ <span style='font-size:0.95em;'>• แยกแต่ละประโยคด้วยจุด (.) หรือขึ้นบรรทัดใหม่<br>• รองรับข้อความภาษาไทยและหลายประโยคพร้อมกัน</span>
164
+ </div>
165
+ </div>
166
+ """)
167
+ text_input = gr.Textbox(
168
+ lines=7,
169
+ placeholder="ตัวอย่าง: วันนี้อากาศดีมาก. ฉันมีความสุขมาก\nหรือ\nวันนี้อากาศดีมาก\nฉันมีความสุขมาก",
170
+ label=""
171
+ )
172
+ analyze_btn = gr.Button("� วิเคราะห์ข้อความ", elem_id="analyze-btn")
173
+ output_box = gr.Textbox(
174
+ label="📊 ผลการวิเคราะห์ความรู้สึก",
175
+ lines=15,
176
+ show_copy_button=True
177
+ )
178
+ gr.Markdown("""
179
+ <div class='main-card' style='margin-top:24px; background: #f8f9fa;'>
180
+ <div style="display: flex; justify-content: space-around; padding: 10px 0;">
181
+ <div style="text-align: center;">
182
+ <div style="font-size: 24px;">😊</div>
183
+ <strong>Positive</strong><br>
184
+ <small>ความรู้สึกเชิงบวก</small>
185
+ </div>
186
+ <div style="text-align: center;">
187
+ <div style="font-size: 24px;">😔</div>
188
+ <strong>Negative</strong><br>
189
+ <small>ความรู้สึกเชิงลบ</small>
190
+ </div>
191
+ <div style="text-align: center;">
192
+ <div style="font-size: 24px;">😐</div>
193
+ <strong>Neutral</strong><br>
194
+ <small>ความรู้สึกเป็นกลาง</small>
195
+ </div>
196
+ <div style="text-align: center;">
197
+ <div style="font-size: 24px;">❓</div>
198
+ <strong>Question</strong><br>
199
+ <small>ประโยคคำถาม</small>
200
+ </div>
201
+ </div>
202
+ </div>
203
+ """)
204
+
205
+ def analyze_wrapper(text, model_name):
206
+ return analyze_text(text, model_name)
207
+ analyze_btn.click(analyze_wrapper, inputs=[text_input, model_dropdown], outputs=output_box)
208
+ text_input.submit(analyze_wrapper, inputs=[text_input, model_dropdown], outputs=output_box)
209
+ model_dropdown.change(analyze_wrapper, inputs=[text_input, model_dropdown], outputs=output_box)
210
+ # ตัวอย่าง: คลิกแล้วใส่ข้อความในกล่อง
211
+ examples.dataset.click(lambda x: x[0] if isinstance(x, list) and x else "", outputs=text_input)
212