|
|
import gradio as gr |
|
|
import numpy as np |
|
|
import matplotlib.pyplot as plt |
|
|
|
|
|
|
|
|
|
|
|
def get_freq(expr): |
|
|
expr = expr.lower().replace(" ", "_") |
|
|
return (abs(hash(expr)) % 5000) + 50 |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
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 模型的核心:语言使用频率驱动固着与常规化共同形成语言系统的稳定性。" |
|
|
) |
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
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 模型互动平台(最终稳定版)") |
|
|
|
|
|
|
|
|
|
|
|
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] |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
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() |
|
|
|