ECModel / app.py
WENior's picture
Update app.py
dfa90ba verified
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt
# ========== Mock 词频函数(避免 HuggingFace 下载大语料) ==========
def get_freq(expr):
expr = expr.lower().replace(" ", "_")
return (abs(hash(expr)) % 5000) + 50
# ========== E 曲线:固着(Entrenchment) ==========
def entrenchment_real(freq_val):
x = np.linspace(0, 10, 200)
strength = min(2.0, 0.5 + np.log(freq_val + 1) / 4)
shift = 5
y = 1 / (1 + np.exp(-strength * (x - shift)))
return x, y
# ========== C 曲线:常规化(Conventionalization) ==========
def conventionalization_real(freq_val):
x = np.linspace(0, 10, 200)
spread = min(2.0, 0.4 + np.log(freq_val + 1) / 5)
shift = 4
y = 1 / (1 + np.exp(-spread * (x - shift)))
return x, y
# ===================== 单表达分析 =====================
def analyze_ec(expr):
f = get_freq(expr)
entrenchment_text = (
"### Entrenchment(固着)\n"
f"表达 **'{expr}'** 的模拟语料频次为:**{f} 次**。\n\n"
"词频越高,固着曲线越陡峭,越容易在个体大脑中形成自动化加工。\n"
)
conventionalization_text = (
"### Conventionalization(常规化)\n"
"高频表达更容易在社群中传播与扩散,因此常规化曲线会更早上升、扩散更快。\n"
)
summary = (
"### 综合解释\n"
f"表达 **'{expr}'** 的频率为 **{f}**。高频使用会带来:\n\n"
"- 更快的固着(E)→ 心理加工速度更快;\n"
"- 更快的常规化(C)→ 社群接受与扩散更快;\n\n"
"这反映了 Schmid E&C 模型的核心:语言使用频率驱动固着与常规化共同形成语言系统的稳定性。"
)
# --- E 曲线 ---
x1, y1 = entrenchment_real(f)
fig_e = plt.figure(figsize=(4.5, 3.2))
plt.plot(x1, y1, linewidth=2)
plt.title("Entrenchment Curve")
plt.xlabel("Usage Frequency")
plt.ylabel("Cognitive Strength")
plt.tight_layout()
# --- C 曲线 ---
x2, y2 = conventionalization_real(f)
fig_c = plt.figure(figsize=(4.5, 3.2))
plt.plot(x2, y2, linewidth=2, color="#ff8c42")
plt.title("Conventionalization Curve")
plt.xlabel("Time / Spread")
plt.ylabel("Community Adoption")
plt.tight_layout()
return entrenchment_text + "\n" + conventionalization_text, fig_e, fig_c, summary
# ===================== 双表达对比 =====================
def compare_two(expr1, expr2):
f1 = get_freq(expr1)
f2 = get_freq(expr2)
# --- E 对比 ---
xA, yA = entrenchment_real(f1)
xB, yB = entrenchment_real(f2)
fig_e = plt.figure(figsize=(5, 3.5))
plt.plot(xA, yA, linewidth=2, label=f"{expr1} (freq={f1})")
plt.plot(xB, yB, linewidth=2, label=f"{expr2} (freq={f2})")
plt.title("Entrenchment Comparison")
plt.legend()
plt.tight_layout()
# --- C 对比 ---
xC1, yC1 = conventionalization_real(f1)
xC2, yC2 = conventionalization_real(f2)
fig_c = plt.figure(figsize=(5, 3.5))
plt.plot(xC1, yC1, linewidth=2, label=f"{expr1} (freq={f1})")
plt.plot(xC2, yC2, linewidth=2, label=f"{expr2} (freq={f2})")
plt.title("Conventionalization Comparison")
plt.legend()
plt.tight_layout()
# --- E 差异热力图 ---
diff = np.abs(yA - yB)[:50].reshape(10, 5)
fig_h = plt.figure(figsize=(4, 3))
plt.imshow(diff, cmap="Reds", aspect="auto")
plt.colorbar(label="Difference")
plt.title("E Difference Heatmap")
plt.tight_layout()
explanation = (
"### 双表达对比解释\n\n"
f"两个表达的模拟词频:\n"
f"- {expr1}: **{f1} 次**\n"
f"- {expr2}: **{f2} 次**\n\n"
"#### 1. 固着(E)差异\n"
"- 高频表达曲线更陡峭 → 更快固着。\n"
f"- 若 {expr1} 曲线整体高于 {expr2},说明它在认知加工上更自动化。\n\n"
"#### 2. 常规化(C)差异\n"
"- 高频表达扩散更快,曲线更左移。\n"
f"- 若 {expr1} 的扩散曲线高于 {expr2},说明它更容易成为社群惯例。\n\n"
"#### 3. 热力图解释\n"
"- 深红表示两表达的固着差异显著。\n"
"- 浅色表示两表达的固着趋势接近。\n\n"
"#### 4. 综合结论\n"
"词频显著影响固着与常规化,体现了 E&C 模型中‘个体认知 × 社群传播’的动态互动机制。"
)
return "", fig_e, fig_c, fig_h, explanation
# ===================== UI =====================
with gr.Blocks(
css="""
.card {
background:white;
padding:15px;
border-radius:10px;
box-shadow:0 3px 10px rgba(0,0,0,0.08);
margin-bottom:12px;
}
body {
background: linear-gradient(135deg,#eef2ff,#e0f2fe);
}
"""
) as demo:
gr.Markdown("# 🧠 E&C 模型互动平台(最终稳定版)")
# ========== 单表达 Tab ==========
with gr.Tab("单表达分析"):
expr = gr.Textbox(label="输入表达")
btn1 = gr.Button("分析")
out_text = gr.Markdown()
out_e = gr.Plot()
out_c = gr.Plot()
out_sum = gr.Markdown()
btn1.click(
analyze_ec,
inputs=[expr],
outputs=[out_text, out_e, out_c, out_sum]
)
# ========== 双表达 Tab ==========
with gr.Tab("双表达对比分析"):
with gr.Row():
with gr.Column(scale=1):
gr.HTML("<div class='card'>")
expr1 = gr.Textbox(label="表达 A")
expr2 = gr.Textbox(label="表达 B")
btn2 = gr.Button("开始对比")
gr.HTML("</div>")
with gr.Column(scale=2):
with gr.Row():
with gr.Column():
gr.HTML("<div class='card'>")
cmp_e = gr.Plot()
gr.HTML("</div>")
with gr.Column():
gr.HTML("<div class='card'>")
cmp_c = gr.Plot()
gr.HTML("</div>")
gr.HTML("<div class='card'>")
heatmap = gr.Plot()
gr.HTML("</div>")
gr.HTML("<div class='card'>")
cmp_text = gr.Markdown()
gr.HTML("</div>")
_dummy = gr.Textbox(visible=False)
btn2.click(
compare_two,
inputs=[expr1, expr2],
outputs=[_dummy, cmp_e, cmp_c, heatmap, cmp_text]
)
demo.launch()