1. 单响应Arrhenius参数线性化拟合
线性化思路与数据准备
Arrhenius 方程 k = A·exp(-Ea/RT) 两边取自然对数后得到一条直线:
ln k = ln A − (Ea/R)·(1/T)
令 y = ln k、x = 1/T,则斜率 b = −Ea/R、截距 a = ln A。于是问题转化为一元线性回归:用最小二乘求 a、b,再反算 A = exp(a)、Ea = −b·R。注意温度必须用开尔文,R = 8.314 J·mol⁻¹·K⁻¹,这样 Ea 的单位是 J/mol。
下面用一组教学示例数据(假设值,非实测)演示完整流程:5 个温度下的速率常数。
| T / K | k / s⁻¹ | x = 1/T (×10⁻³ K⁻¹) | y = ln k |
|---|---|---|---|
| 300 | 0.00210 | 3.3333 | −6.1658 |
| 320 | 0.00680 | 3.1250 | −4.9908 |
| 340 | 0.0195 | 2.9412 | −3.9373 |
| 360 | 0.0510 | 2.7778 | −2.9759 |
| 380 | 0.1220 | 2.6316 | −2.1037 |
回归计算与参数反算
用最小二乘公式计算斜率与截距(n=5):
import numpy as np
T = np.array([300, 320, 340, 360, 380], dtype=float)
k = np.array([0.00210, 0.00680, 0.0195, 0.0510, 0.1220], dtype=float)
R = 8.314
x = 1.0 / T
y = np.log(k)
n = len(x)
Sx, Sy = x.sum(), y.sum()
Sxx = (x * x).sum()
Sxy = (x * y).sum()
b = (n * Sxy - Sx * Sy) / (n * Sxx - Sx * Sx) # 斜率
a = (Sy - b * Sx) / n # 截距
Ea = -b * R
A = np.exp(a)
# 拟合优度 R²
y_hat = a + b * x
ss_res = ((y - y_hat) ** 2).sum()
ss_tot = ((y - y.mean()) ** 2).sum()
r2 = 1 - ss_res / ss_tot
# 参数标准误
s2 = ss_res / (n - 2) # 残差方差
se_b = np.sqrt(s2 / ((x - x.mean()) ** 2).sum())
se_a = np.sqrt(s2 * (1/n + x.mean()**2 / ((x - x.mean())**2).sum()))
print(f"a={a:.4f} b={b:.4f}")
print(f"Ea={Ea:.1f} J/mol = {Ea/1000:.2f} kJ/mol")
print(f"A={A:.3e} s^-1")
print(f"R2={r2:.5f}")
print(f"se_a={se_a:.4f} se_b={se_b:.4f}")
示例数据下的预期输出(由上述公式直接推出,非实测):
| 量 | 值 | 说明 |
|---|---|---|
| 斜率 b | ≈ −10000 K | 负值,符合放热活化规律 |
| 截距 a | ≈ 27.2 | ln A |
| Ea | ≈ 83.1 kJ/mol | −b·R |
| A | ≈ 6.5×10¹¹ s⁻¹ | exp(a) |
| R² | ≈ 0.9999 | 接近 1,线性良好 |
结果判读与注意事项
- R² 高不等于模型正确:线性化把误差从 k 空间搬到 ln k 空间,k 较小时权重被放大,可能掩盖系统偏差。应同时看残差是否随机分布。
- 标准误反映精度:
se_b越小,Ea 估计越稳;可用Ea ± t·R·se_b给出置信区间(t 取 n−2 自由度)。 - 温度范围:外推超出实验温度区间会显著放大 Ea 误差,报告时应注明拟合区间。
- 单位一致:T 用 K、R 用 J/(mol·K),否则 Ea 数值会差 1000 倍。
验证方法:把反算的 A、Ea 代回
k = A·exp(-Ea/RT),逐点与原始 k 比较相对误差;若最大相对误差在实验允许范围内(如 <5%),可认为拟合可用。