Spaces:
Running
Running
import gradio as gr | |
from transformers import pipeline | |
# รายชื่อโมเดลที่ให้เลือก | |
MODEL_LIST = [ | |
"SandboxBhh/sentiment-thai-text-model", | |
"poom-sci/WangchanBERTa-finetuned-sentiment", | |
"Thaweewat/wangchanberta-hyperopt-sentiment-01", | |
"cardiffnlp/twitter-xlm-roberta-base-sentiment", | |
"phoner45/wangchan-sentiment-thai-text-model", | |
"ZombitX64/Sentiment-01", | |
"ZombitX64/Sentiment-02", | |
"ZombitX64/Sentiment-03", | |
"ZombitX64/MultiSent-E5-Pro", | |
"ZombitX64/MultiSent-E5", | |
"ZombitX64/Thai-sentiment-e5", | |
"ZombitX64/sentiment-103", | |
"nlptown/bert-base-multilingual-uncased-sentiment" | |
] | |
from functools import lru_cache | |
# ใช้ cache เพื่อไม่ต้องโหลดโมเดลซ้ำ | |
def get_nlp(model_name): | |
return pipeline("sentiment-analysis", model=model_name) | |
label_map = { | |
"LABEL_0": 0, | |
"LABEL_1": 1, | |
"LABEL_2": 2, | |
"LABEL_3": 3 | |
} | |
label_name_map = { | |
"LABEL_0": "question", | |
"LABEL_1": "negative", | |
"LABEL_2": "neutral", | |
"LABEL_3": "positive" | |
} | |
def analyze_text(text, model_name): | |
# แยกประโยคโดยใช้ \n หรือจุด | |
import re | |
sentences = [s.strip() for s in re.split(r'[.\n]', text) if s.strip()] | |
if not sentences: | |
return "❗ กรุณาใส่ข้อความที่ต้องการวิเคราะห์" | |
# สีและไอคอนสำหรับแต่ละ sentiment | |
sentiment_style = { | |
"positive": {"emoji": "😊", "color": "#4CAF50", "bg": "#E8F5E8"}, | |
"negative": {"emoji": "😔", "color": "#F44336", "bg": "#FFEBEE"}, | |
"neutral": {"emoji": "😐", "color": "#FF9800", "bg": "#FFF3E0"}, | |
"question": {"emoji": "❓", "color": "#2196F3", "bg": "#E3F2FD"} | |
} | |
results = [] | |
results.append("📊 **ผลการวิเคราะห์ความรู้สึก**\n" + "="*50 + "\n") | |
nlp = get_nlp(model_name) | |
for i, sentence in enumerate(sentences, 1): | |
result = nlp(sentence)[0] | |
label = result['label'] | |
score = result['score'] | |
code = label_map.get(label, -1) | |
label_name = label_name_map.get(label, label) | |
style = sentiment_style.get(label_name, {"emoji": "🔍", "color": "#666666", "bg": "#F5F5F5"}) | |
bar_length = int(score * 20) | |
progress_bar = "█" * bar_length + "░" * (20 - bar_length) | |
result_text = f""" | |
🔸 **ประโยคที่ {i}:** "{sentence}" | |
{style['emoji']} **ผลวิเคราะห์:** {label_name.upper()} (รหัส: {code}) | |
📈 **ความมั่นใจ:** {score:.2f} ({score*100:.1f}%) | |
{progress_bar} {score:.2f} | |
{'─' * 60} | |
""" | |
results.append(result_text) | |
# เพิ่มสรุปผลรวม | |
total_sentences = len(sentences) | |
results.append(f"\n📋 **สรุป:** วิเคราะห์ทั้งหมด {total_sentences} ประโยค") | |
return "\n".join(results) | |
with gr.Blocks( | |
theme=gr.themes.Soft(primary_hue="blue", secondary_hue="purple", neutral_hue="gray"), | |
css=""" | |
.gradio-container { | |
max-width: 900px !important; | |
margin: auto !important; | |
background: #f4f7fa !important; | |
border-radius: 18px !important; | |
box-shadow: 0 4px 24px 0 #bdbdbd33; | |
} | |
.main-card { | |
background: white; | |
border-radius: 16px; | |
box-shadow: 0 2px 12px 0 #bdbdbd22; | |
padding: 32px 32px 24px 32px; | |
margin: 32px 0 24px 0; | |
} | |
.output-markdown { | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important; | |
} | |
.gr-button { | |
font-size: 1.1em; | |
padding: 0.7em 2em; | |
border-radius: 8px; | |
} | |
.gr-textbox textarea { | |
font-size: 1.1em; | |
min-height: 120px; | |
} | |
.gr-dropdown input { | |
font-size: 1.1em; | |
} | |
""" | |
) as demo: | |
gr.Markdown(""" | |
<div style="text-align: center; padding: 32px 0 12px 0;"> | |
<h1 style="font-size:2.5em; margin-bottom: 0.2em; color:#3b3b6d;">🧠 Thai Sentiment Analyzer</h1> | |
<div style="font-size:1.2em; color:#666;">AI วิเคราะห์ความรู้สึกในข้อความภาษาไทย รองรับหลายโมเดลและหลายประโยค</div> | |
</div> | |
""") | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown(""" | |
<div class='main-card'> | |
<h3 style='color:#4a4a7d; margin-bottom:10px;'>� เลือกโมเดลวิเคราะห์ความรู้สึก</h3> | |
</div> | |
""") | |
model_dropdown = gr.Dropdown( | |
choices=MODEL_LIST, | |
value="ZombitX64/MultiSent-E5", | |
label="โมเดลที่ต้องการใช้" | |
) | |
gr.Markdown(""" | |
<div class='main-card' style='margin-top:18px;'> | |
<h3 style='color:#4a4a7d; margin-bottom:10px;'>� ตัวอย่างข้อความ</h3> | |
</div> | |
""") | |
with gr.Column(): | |
gr.Markdown(""" | |
<div class='main-card'> | |
<h3 style='color:#4a4a7d; margin-bottom:10px;'>📝 ข้อความที่ต้องการวิเคราะห์</h3> | |
<div style='color:#888; font-size:1em;'> | |
💬 พิมพ์ข้อความหลายประโยคที่นี่<br> | |
<span style='font-size:0.95em;'>• แยกแต่ละประโยคด้วยจุด (.) หรือขึ้นบรรทัดใหม่<br>• รองรับข้อความภาษาไทยและหลายประโยคพร้อมกัน</span> | |
</div> | |
</div> | |
""") | |
text_input = gr.Textbox( | |
lines=7, | |
placeholder="ตัวอย่าง: วันนี้อากาศดีมาก. ฉันมีความสุขมาก\nหรือ\nวันนี้อากาศดีมาก\nฉันมีความสุขมาก", | |
label="" | |
) | |
analyze_btn = gr.Button("� วิเคราะห์ข้อความ", elem_id="analyze-btn") | |
output_box = gr.Textbox( | |
label="📊 ผลการวิเคราะห์ความรู้สึก", | |
lines=15, | |
show_copy_button=True | |
) | |
# ต้องสร้างตัวอย่างหลัง text_input ถูกนิยามแล้ว | |
examples = gr.Examples( | |
examples=[ | |
["วันนี้อากาศดีมาก ฉันรู้สึกมีความสุขมาก"], | |
["ฉันไม่ชอบอาหารนี้ รสชาติแปลกมาก"], | |
["วันนี้เป็นยังไง\nเรียนหนังสือกันไหม"], | |
["บริการดีมาก พนักงานใจดี\nแต่ของมีราคาแพงไปหน่อย\nโดยรวมแล้วพอใจ"] | |
], | |
inputs=[text_input], | |
label="คลิกเพื่อใส่ตัวอย่างในกล่องข้อความ" | |
) | |
gr.Markdown(""" | |
<div class='main-card' style='margin-top:24px; background: #f8f9fa;'> | |
<div style="display: flex; justify-content: space-around; padding: 10px 0;"> | |
<div style="text-align: center;"> | |
<div style="font-size: 24px;">😊</div> | |
<strong>Positive</strong><br> | |
<small>ความรู้สึกเชิงบวก</small> | |
</div> | |
<div style="text-align: center;"> | |
<div style="font-size: 24px;">😔</div> | |
<strong>Negative</strong><br> | |
<small>ความรู้สึกเชิงลบ</small> | |
</div> | |
<div style="text-align: center;"> | |
<div style="font-size: 24px;">😐</div> | |
<strong>Neutral</strong><br> | |
<small>ความรู้สึกเป็นกลาง</small> | |
</div> | |
<div style="text-align: center;"> | |
<div style="font-size: 24px;">❓</div> | |
<strong>Question</strong><br> | |
<small>ประโยคคำถาม</small> | |
</div> | |
</div> | |
</div> | |
""") | |
def analyze_wrapper(text, model_name): | |
return analyze_text(text, model_name) | |
analyze_btn.click(analyze_wrapper, inputs=[text_input, model_dropdown], outputs=output_box) | |
text_input.submit(analyze_wrapper, inputs=[text_input, model_dropdown], outputs=output_box) | |
model_dropdown.change(analyze_wrapper, inputs=[text_input, model_dropdown], outputs=output_box) | |
# ตัวอย่าง: คลิกแล้วใส่ข้อความในกล่อง | |
examples.dataset.click(lambda x: x[0] if isinstance(x, list) and x else "", outputs=text_input) | |