TIRADemo / app.py
WENior's picture
Update app.py
3b5816c verified
import gradio as gr
import re
import matplotlib.pyplot as plt
import numpy as np
from transformers import pipeline
# ---------------------------
# 1. AI Translator Model
# ---------------------------
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
def translate_ai(cn_text):
try:
return translator(cn_text)[0]["translation_text"]
except:
return "Translation model error."
# ---------------------------
# 2. Politeness Marker Extraction
# ---------------------------
POLITENESS_FEATURES = {
"modals": ["could", "would", "may", "might"],
"softener": ["please", "kindly"],
"hedging": ["possibly", "perhaps", "a bit", "a little"],
"formal": ["professor", "sir", "madam"],
"passive": ["is requested", "may cause", "is appreciated"],
"appreciation": ["thank", "appreciate", "grateful"]
}
def extract_politeness_scores(en_text):
text = en_text.lower()
scores = {}
for feat, markers in POLITENESS_FEATURES.items():
score = sum(text.count(m) for m in markers)
scores[feat] = min(score, 5)
return scores
# ---------------------------
# 3. TIRA Classification
# ---------------------------
def classify_tira(cn_text, en_text):
cn = cn_text.lower()
en = en_text.lower()
cn_amplify = ["能否", "是否方便", "请您帮忙", "抽空", "劳驾", "麻烦帮我"]
cn_attenuate = ["尽快", "必须", "需要您", "立即"]
cn_redirect = ["给您添麻烦", "不好意思打扰", "不胜感激"]
en_amplify = ["please", "could you", "possibly", "would you"]
en_attenuate = ["directly", "must", "asap"]
en_redirect = ["inconvenience", "may cause"]
if any(p in cn for p in cn_redirect) or any(p in en for p in en_redirect):
return "Redirect(转向)"
if any(p in cn for p in cn_amplify) or any(p in en for p in en_amplify):
return "Amplify(放大)"
if any(p in cn for p in cn_attenuate) or any(p in en for p in en_attenuate):
return "Attenuate(削弱)"
return "Retain(保留)"
# ---------------------------
# 4. Radar Chart (AI + Human)
# ---------------------------
def draw_dual_radar(ai_scores, human_scores=None):
labels = list(ai_scores.keys())
angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False).tolist()
ai_vals = list(ai_scores.values()) + [list(ai_scores.values())[0]]
angles_plot = angles + [angles[0]]
fig, ax = plt.subplots(figsize=(6,6), subplot_kw=dict(polar=True))
ax.fill(angles_plot, ai_vals, color="#1B3B6F80", alpha=0.4, label="AI Translation")
ax.plot(angles_plot, ai_vals, color="#1B3B6F", linewidth=2)
if human_scores:
hum_vals = list(human_scores.values()) + [list(human_scores.values())[0]]
ax.fill(angles_plot, hum_vals, color="#D9534F50", alpha=0.3, label="Human Translation")
ax.plot(angles_plot, hum_vals, color="#D9534F", linewidth=2)
ax.set_xticks(angles)
ax.set_xticklabels([l.capitalize() for l in labels])
ax.set_yticks(range(1, 6))
ax.set_ylim(0, 5)
ax.set_title("AI vs Human Politeness Radar", fontsize=15, color="#1B3B6F")
ax.legend(loc="upper right", bbox_to_anchor=(1.3, 1.1))
return fig
# ---------------------------
# 5. Generate TIRA Comparison Table (AI vs Human)
# ---------------------------
def generate_tira_table(ai_tira, human_tira=None):
if not human_tira:
table = f"""
| 比较项 | AI |
|--------|------------------|
| **TIRA 类型** | {ai_tira} |
"""
else:
table = f"""
| 比较项 | AI 译文 | 人工译文 |
|--------|--------------|----------------|
| **TIRA 类型** | {ai_tira} | {human_tira} |
| **偏移方向** | {"↑ 放大 / 更远" if ai_tira=="Amplify(放大)" else ("↓ 更直接" if ai_tira=="Attenuate(削弱)" else ("↔ 基本一致" if ai_tira=="Retain(保留)" else "→ 转向"))} |
"""
return table
# ---------------------------
# 6. Main Process
# ---------------------------
def full_process(cn_text, human_text):
en_ai = translate_ai(cn_text)
ai_scores = extract_politeness_scores(en_ai)
ai_tira = classify_tira(cn_text, en_ai)
human_scores = None
human_tira = None
if human_text and human_text.strip() != "":
human_scores = extract_politeness_scores(human_text)
human_tira = classify_tira(cn_text, human_text)
table = generate_tira_table(ai_tira, human_tira)
fig = draw_dual_radar(ai_scores, human_scores)
return en_ai, ai_scores, ai_tira, table, fig
# ---------------------------
# 7. UI
# ---------------------------
css = """
h1 {text-align:center; color:#1B3B6F;}
label {font-weight:bold;}
"""
with gr.Blocks(css=css, title="TIRA AI vs Human Comparison System") as demo:
gr.Markdown("""
# **📘 TIRA AI vs Human Translation Comparison System**
### *TIRA Table + Dual Radar Chart + Politeness Analysis*
---
输入中文→自动生成:
- AI 翻译
- AI vs Human 礼貌雷达叠加
- AI vs Human TIRA 类型对照表
非常适合学术展示与论文附录材料。
---
""")
cn_input = gr.Textbox(lines=4, label="✉ 输入中文邮件内容")
human_input = gr.Textbox(lines=3, label="📝 可选:输入人工英文译文")
btn = gr.Button("🔍 运行分析", variant="primary")
en_out = gr.Textbox(label="🌐 AI 翻译")
ai_scores_out = gr.JSON(label="🔬 AI 礼貌特征")
ai_tira_out = gr.Textbox(label="📌 AI 的 TIRA 类型")
table_out = gr.Markdown(label="📊 TIRA 对照表")
radar_out = gr.Plot(label="📉 AI vs Human 双雷达图叠加")
btn.click(
fn=full_process,
inputs=[cn_input, human_input],
outputs=[en_out, ai_scores_out, ai_tira_out, table_out, radar_out]
)
demo.launch()