资讯动态

燃烧后CO2捕集MEA吸收过程模拟教程(14):中试数据标定——用TCM/NCCC公开数据校正模型

发布时间:2026/10/13 9:03:35 来源:尧图企业网站定制
燃烧后CO2捕集MEA吸收过程模拟教程14中试数据标定——用TCM/NCCC公开数据校正模型版本声明块工具/软件Aspen Plus当前 aspenONE 版本引用前需在官网核对本系列不写具体版本号模型侧可用 CCSI MEA Steady State ModelAspen Plus 的附加模型不是 Aspen 内置标准物性包语言/环境Python 3.9依赖 numpy、pandas库版本以本机环境为准本文目标拿到一份公开中试数据后能独立完成「稳态筛选 → 加权标定 → 交叉验证 → 外推边界判定」四步并说清哪一步最容易骗自己一句话结论TCM 的 MEA 基线 SRD 在 2014 年为4.10 GJ/t CO₂捕集率 90.0%、2015 年为3.90 GJ/t83.5%、加消泡剂后的现行基线为 3.62 GJ/t87.4%三者差 0.48 GJ/t 却都叫「MEA 基线」——标定的第一件事不是拟合而是把工况口径对齐。〇、本篇要解决的认知问题TCM 公开的 MEA 基线里SRD 到底有几个版本值分别是多少、工况条件是什么NCCCNational Carbon Capture Center, Wilsonville, Alabama的数据在 CCSI 的模型整定中起什么作用中试数据标定前为什么必须先做稳态筛选判据怎么定标定得不错的模型能不能直接拿去预测中国机组的 SRD怎么用留一 / 留组交叉验证判断标定模型是「真有效」还是「过拟合」一、机制解析1.1 先建「口径对齐表」再谈拟合中试标定最常见的失败不是算法错而是把不同口径的数据塞进同一个目标函数。看这张表就会明白来源SRDGJ/t CO₂捕集率MEA 浓度口径备注TCM MEA 基线 20144.10 4.10 MJ/kg CO₂90.0%30 wt%3.5–3.6% CO₂ 烟气EPRI 独立验证TCM MEA 基线 20153.9083.5%30 wt%同一装置、同一天然气烟气TCM MEA 消泡剂 2015现行基线3.6287.4%30 wt%加消泡剂后的现行基线Sherman FEEDBechtel/DOE3.65 再沸器 3.51 压缩级间回收 0.14约 95%35 wt%含压缩级间热回收口径不同TCM 高捕集率试验Shah 20213.797%MEA ≤38 wt%贫液0.21mol CO₂/mol MEA填料 24 m江油中试Sichuan4.0–5.8最低 4.0底账未核实30 wt%再生压力优化值 0.15 MPa1.5 barCCSI / Aspen 模型模型值非实测3.5095%/ 3.7799%95% / 99%35 wt%只能当交叉核对对象不能当实测点三个必须立刻记下的观察捕集率不是同一个数。90.0%、83.5%、87.4%、97%、99% 混在一起任何「SRD 常数」的想法都会崩掉。这也解释了第 10 篇为什么会强调「不能把 3.5–4.0 拍平成单点」。Sherman 的 3.65 与 TCM 的 3.62 几乎一样但不可直接对比——Sherman 的 3.65 里含 0.14 GJ/t 的压缩级间回收TCM 的 3.62 不含。口径不同数字相同纯属巧合。模型值要单独放。CCSI/Aspen 的 3.50 / 3.77 是模型算出来的用它去标定模型等于自己证明自己。1.2 NCCC 在标定链里的位置NCCCNational Carbon Capture Center, Wilsonville, Alabama是 CCSI 用来做整定与验证的中试数据源。CCSI MEA Steady State Model 为 MEA 体系专门开发了四类子模型——物性黏度/密度/表面张力/扩散、水力学、界面面积、反应动力学并用 NCCC 中试数据整定验证。这一点对本文很关键中试数据不是用来「调一个总系数」的它是用来分别约束不同子模型的。填料段差压 → 水力学温度剖面 → 传质与界面面积再沸器负荷 → 反应热与汽提。因此只要数据维度足够就不该只拟合一个总 SRD。手上只有 SRD 单点时你能做的是「口径对齐 偏差评估」不是「参数标定」。另一个必须一起看的事实CCSI 的不确定性量化报告把 Hikita 速率参数按其平均偏差 3.5%设为分布区间做敏感性分析。这意味着「中试标定出来的参数不是精确值」应当是建模前提而不是建模结论。第 7 篇讲过的参数不确定度在标定这一步会以「标定后参数仍有一个带宽」的形式再次出现。1.3 标定四步法本篇的骨架原始中试时序数据T/P/流量/浓度/SRD │ ├─(1) 清洗剔除分析仪跳变、除盐水冲洗段、开停车段 │ ├─(2) 稳态筛选滑窗内相对漂移 阈值 且 方差 阈值 │ └─ 判据不通过 → 回到第 15 篇的收敛/工况问题不要硬拟合 │ ├─(3) 加权标定w_i 1/σ_i²σ 来自口径可信度与 EPRI 类独立验证等级 │ └─ 目标函数 J(θ) Σ w_i [SRD_calc(θ; X_i) - SRD_obs_i]² │ └─(4) 验证留一同装置 留组跨装置/跨机组 └─ 留组误差 留一误差 → 模型只学到了「这台装置」为什么第 2 步不能跳过中试装置在开停车、切换工况、投加消泡剂的时间窗里负载和温度都在漂。把这些点当稳态点拟合等于用过渡态数据去标定稳态模型误差会被系统性地摊到参数里 —— 而且这个偏差看残差图是看不出来的它表现为参数偏移不是残差变大。为什么第 4 步要分「留一」和「留组」留一测的是「同一台装置、换一个工况点」的预测能力留组测的是「换一台装置/换一个机组」的预测能力。工业上真正被关心的是后者但前者才是模型开发者能控制的。把两者分别报出来是标定报告的基本诚实。二、完整代码与逐行剖析代码 1构建口径对齐的标定对照表环境Python 3.9依赖 numpy、pandas。数据来源声明下表中的每一个数字都取自本系列事实底账逐行注明来源编号不是本文自行拟定的。江油中试的捕集率、TCM 高捕集率试验的 MEA 精确浓度在底账中分别是「未核实」与「≤38 wt%」代码里以NaN与上界标记存放绝不用估算值填充。# 14_1_build_table.py —— 建立口径对齐的标定对照表# 环境Python 3.9 / pandasimportpandasaspdimportnumpyasnp# 每一行的 src 都指向底账中的出处编号便于逐条回查rows[# 来源, SRD(GJ/t CO2), 捕集率(%), MEA(wt%), 是否实测, 权重, 备注dict(srcTCM MEA基线2014,srd4.10,cap90.0,mea30.0,measuredTrue,w1.0,note3.5-3.6% CO2烟气, EPRI独立验证),dict(srcTCM MEA基线2015,srd3.90,cap83.5,mea30.0,measuredTrue,w1.0,note同装置, 天然气烟气),dict(srcTCM MEA消泡剂2015,srd3.62,cap87.4,mea30.0,measuredTrue,w1.0,note现行基线),dict(srcSherman FEED(Bechtel),srd3.65,cap95.0,mea35.0,measuredTrue,w0.6,note含压缩级间回收0.14, 口径不同 - 降权),dict(srcTCM高捕集率(Shah2021),srd3.70,cap97.0,mea38.0,measuredTrue,w1.0,note贫液0.21 mol/mol, 填料24m; MEA38wt%, 取上界并标注),dict(src江油中试,srd4.00,capnp.nan,mea30.0,measuredTrue,w1.0,note最低值(区间4.0-5.8), 再生0.15MPa; 捕集率未核实),dict(srcCCSI/Aspen模型,srd3.50,cap95.0,mea35.0,measuredFalse,w0.0,note模型值, 仅作交叉核对, 权重置0),dict(srcCCSI/Aspen模型,srd3.77,cap99.0,mea35.0,measuredFalse,w0.0,note模型值, 仅作交叉核对, 权重置0),]dfpd.DataFrame(rows)df.to_csv(calibration_observations.csv,indexFalse,encodingutf-8-sig)# 为什么把权重单独一列而不是在代码里硬编码# 权重代表这个点与目标口径的一致程度它是标定的主观输入# 必须显式落盘、可被评审而不是藏在拟合函数里。print(df[[src,srd,cap,mea,measured,w]].to_string(indexFalse))# 同时要求「有权重」且「捕集率非缺失」才算可参与拟合缺一不可print(\n实测点数 ,int(df[measured].sum()), 可参与拟合点数 ,int(((df[w]0)df[cap].notna()).sum()))# 预期输出本机实测实测 6 点含江油可参与拟合 5 点# 江油中试捕集率在底账中未核实 - 以 NaN 存后续单独作量级参照反直觉默认值Sherman 的权重被压到 0.6。很多人会觉得「数据都是权威来源权重应该一样」。但权重反映的是口径一致性不是来源权威性Sherman 的 3.65 含压缩级间回收与 TCM 的 SRD 定义不同给它满权重就是在往标定里注入系统偏差。代码 2稳态筛选器——滑窗双判据环境Python 3.9依赖 numpy、pandas。数据声明本段的时间序列是程序生成的示意信号用来演示筛选算法含一段人为插入的阶跃过渡区用来验证算法能否识别它。真实数据请换成本机从 TCM/NCCC 公开数据集导出的 CSV字段名对齐即可。# 14_2_steady_screen.py —— 稳态窗口筛选滑窗 双判据# 环境Python 3.9 / numpy / pandasimportnumpyasnpimportpandasaspddefmake_demo_signal(n600,seed20260912):生成示意时序稳态段 一段阶跃过渡段 测量噪声。 为什么要有过渡段如果算法对过渡段不敏感它就等于没工作。rngnp.random.default_rng(seed)tnp.arange(n)x0.300.005*rng.standard_normal(n)# 基准贫液负载量级附近x[250:330]np.linspace(0.0,0.08,80)# 人为插入的 80 点漂移段returnpd.DataFrame({t_s:t*10.0,lean_loading:x})defscreen_steady(df,col,win30,max_rel_drift0.02,max_cv0.03): 滑窗稳态判据 判据A: 相对漂移 (窗内均值_后半 - 窗内均值_前半)/窗内均值 max_rel_drift 判据B: 离散度 窗内标准差/窗内均值 (变异系数 CV) max_cv 为什么用两个判据而不是一个 只有判据B 会把缓慢单向漂移误判为稳态慢漂移的窗内标准差很小 只有判据A 会把围绕均值抖动误判为稳态。两者是正交的失效模式。 为什么 max_cv 默认取 0.03 而不是 0.01 本示意信号的噪声标准差 0.005 / 均值 0.30 ≈ 1.7%若阈值取 0.01 所有窗口都会因为噪声本身被判为非稳态——本机实测 571 个窗口通过 0 个。 阈值必须按噪声水平设定本例取约 2 倍噪声 CV而不是凭感觉取小值。 out[]vdf[col].to_numpy()foriinrange(0,len(v)-win1):wv[i:iwin]halfwin//2m_allw.mean()ifm_all0:continuerel_driftabs(w[half:].mean()-w[:half].mean())/abs(m_all)cvw.std(ddof1)/abs(m_all)# 记录窗口起点 i便于后续按整窗是否落在过渡段内做精确统计out.append((i,df[t_s].iloc[iwin-1],rel_drift,cv,rel_driftmax_rel_driftandcvmax_cv))respd.DataFrame(out,columns[i,t_end_s,rel_drift,cv,steady])returnres dfmake_demo_signal()resscreen_steady(df,lean_loading,win30,max_rel_drift0.02,max_cv0.03)print(f总窗口数 {len(res)}判定为稳态的窗口数 {int(res[steady].sum())}f占比 {res[steady].mean():.1%})# 关键校验只统计整窗都落在人为漂移段内的窗口样本下标 i∈[250,300]# 避免把与漂移段擦边的窗口算进来、让误判率虚高insideres[(res[i]250)(res[i]29330)]print(f整窗位于漂移段内的窗口 {len(inside)}误判为稳态的比例 {inside[steady].mean():.1%})res.to_csv(steady_windows.csv,indexFalse,encodingutf-8-sig)# 预期输出本机实测win30 / max_rel_drift0.02 / max_cv0.03# 总窗口 571判为稳态 47583.2%# 整窗位于漂移段内 52 个窗口误判为稳态的比例 0.0%# 参考把 max_rel_drift 收紧到 0.01 - 总稳态降到 76.9%、误判仍为 0.0%# 放宽到 0.05 - 总稳态升到 88.4%但漂移段误判率跳到 40.4%逐段剖析win30对应 300 s 的窗口采样间隔 10 s。这个长度不是随便取的——它必须远大于测量噪声的相关时间、又远小于工况切换的特征时间。工程上的取法是先看数据自相关函数取自相关衰减到噪声水平的时间再乘 3~5 倍。阈值max_rel_drift0.02表示「窗口前后半段均值差不超过 2%」对贫液负载这类关键量是可接受的稳态带宽。反直觉默认值max_cv是本函数里最容易设错的参数。噪声 CV 约 1.7%若按「越严越好」的思路取 0.01结果是一个稳态窗口都筛不出来本机实测 571 个窗口通过 0 个——阈值必须建立在噪声水平之上而不是越低越好。反之把max_rel_drift放宽到 0.05稳态窗口占比从 83.2% 升到 88.4%但漂移段误判率从 0% 跳到 40.4%筛出来的稳态里混进了过渡态而这类污染在残差图上是看不出来的它表现为参数偏移不是残差变大见 1.3 节。代码 3加权标定 留一 / 留组交叉验证环境Python 3.9依赖 numpy、pandas。模型声明下面的srd_model是一个示意线性模型示意参数用来演示标定与验证流程它不具预测能力不得用于任何工程决策。真实的 MEA 模型应使用速率基塔 电解质热力学第 5、8、13 篇或 CCSI MEA Steady State Model 一类附加模型。# 14_3_calibrate.py —— 加权最小二乘标定 留一/留组交叉验证# 环境Python 3.9 / numpy / pandasimportnumpyasnpimportpandasaspddefsrd_model(theta,cap_pct):示意线性模型SRD t0 t1*(1 - 捕集率) 为什么只用两个参数 可用训练点只有 4 个。参数个数逼近样本个数时留一验证会因为 少一个点就换一组解而剧烈波动本机实测换成 3 参数后 LOO 的 MAE 从 0.302 恶化到 0.913。样本少时模型复杂度必须跟着降——这是标定第一纪律。 本模型只是定性示意参数为示意值禁止外推使用。returntheta[0]theta[1]*(1.0-cap_pct/100.0)defweighted_sse(theta,cap,srd,w):rsrd_model(theta,cap)-srdreturnfloat(np.sum(w*r**2))defcalibrate(cap,srd,w):网格粗搜。 为什么用网格而不是解析最小二乘加权 少量样本时需要看目标函数地形 是否平坦对应第 13 篇的参数可辨识性网格能把平坦方向直接暴露出来。bestNonefort0innp.arange(2.0,6.0,0.05):fort1innp.arange(-20.0,20.0,0.1):thnp.array([t0,t1])vweighted_sse(th,cap,srd,w)ifbestisNoneorvbest[0]:best(v,th)returnbest[1]dfpd.read_csv(calibration_observations.csv)# 关键留组点必须从训练集里剔除否则留组验证就是自己测自己fitdf[(df[w]0)df[cap].notna()(~df[src].str.contains(高捕集率))].copy()holdoutdf[(df[w]0)df[cap].notna()(df[src].str.contains(高捕集率))]capfit[cap].to_numpy(float)srdfit[srd].to_numpy(float)wfit[w].to_numpy(float)thetacalibrate(cap,srd,w)print(标定参数示意 ,np.round(theta,4))print(拟合残差GJ/t ,np.round(srd_model(theta,cap)-srd,4))# ---- 留一交叉验证LOO同一批装置/机组内部 ----loo_err[]foriinrange(len(fit)):idxnp.ones(len(fit),bool);idx[i]Falseth_icalibrate(cap[idx],srd[idx],w[idx])loo_err.append(srd_model(th_i,cap[i])-srd[i])loo_errnp.array(loo_err)print(fLOO 误差: MAE{np.abs(loo_err).mean():.4f}RMSE{np.sqrt((loo_err**2).mean()):.4f}f最大绝对误差{np.abs(loo_err).max():.4f}GJ/t)# ---- 留组验证用 TCM 三代基线 Sherman 训练预测未参与训练的 TCM 高捕集率(97%)工况 ----# 为什么这叫留组而不叫留一留一的训练集里包含同一装置的其他工况# 装置级系统偏差被共享了留组把整行从训练集拿掉测的才是外推。pred_hosrd_model(theta,float(holdout[cap].iloc[0]))dev_hopred_ho-float(holdout[srd].iloc[0])print(f留组外推: 预测{pred_ho:.3f}实测{float(holdout[srd].iloc[0]):.3f}偏差{dev_ho:.3f}GJ/t)# 预期输出本机实测训练集 4 点# 标定参数示意 [3.75, 0.7]# 拟合残差GJ/t [-0.28, -0.034, 0.218, 0.135]# LOO 误差: MAE0.3019 RMSE0.3290 最大绝对误差0.4100 GJ/t# 留组外推: 预测3.771 实测3.700 偏差0.071 GJ/t结果怎么解读这才是本节的重点本机实测给出两组误差——LOO 的 MAE 0.30 GJ/t最大 0.41留组外推偏差 0.071 GJ/t。注意留组偏差反而比 LOO 的 MAE 小。这不代表模型外推能力强恰恰说明样本量只有 4 个时两类误差都不可靠留一会因为「少一个点就换一组参数」而放大误差留组则只是一次单点比较运气成分无法排除。真正稳健的结论只有一条拟合残差的符号是成组出现的TCM 2014、2015 两代基线为负现行基线与 Sherman 为正说明缺失的是系统性变量消泡剂投加、压缩级间热回收、装置配置而不是随机噪声。一个只吃捕集率的模型连训练集这 4 个点都只能解释到 ±0.28 GJ/t约为 SRD 的 7%。这正是「禁止把 TCM 数值无条件外推到中国机组工况」这条铁律的量化依据——第 10 篇讲 SRD 区间时要标工况条件第 12 篇做工况扫描时要标可行域原因都在这里。三、常见报错与排查报错 1KeyError: cap或could not convert string to float: —根因对照表里用—之类的占位符表示「未核实」读进 pandas 后仍是字符串。解法统一用NaNCSV 里留空并在代码里显式df[cap].notna()过滤不要用 0.0 填充缺失值——那会在目标函数里变成一个「捕集率 0%、SRD 真实值」的强约束点把标定结果整体拉偏。报错 2标定后的 SRD 全部偏高约 0.14 GJ/t根因Sherman FEED 的 3.65 GJ/t 含「压缩级间回收 0.14 GJ/t」与 TCM 的 SRD 定义不一致。解法要么按口径拆开用 3.51 的再沸器值参与标定要么按本文做法降权两条路都行但必须在报告里写明你选了哪条。报错 3稳态筛选后剩余窗口极少10%根因阈值太紧或原始数据本身以变工况试验为主中试装置常见。解法先放宽max_rel_drift到 5% 再逐步收紧同时把窗口长度与采样间隔对齐300 s 窗口配 10 s 采样若确实没有稳态段就应改用动态模型而不是硬标定稳态模型。报错 4LOO 误差很小但现场复现不了根因训练集与验证集共享了同一台装置的系统偏差例如同一套流量计、同一套分析方法。解法改用留组验证按装置/按机组分组并接受「留组误差更大」这个结果这才是真实的预测能力。报错 5把模型值当实测值用了根因CCSI/Aspen 的 3.50 / 3.77 GJ/t 是模型输出若混入实测列表参与拟合会得到「模型预测模型」的循环论证。解法在对照表里加measured布尔列本文代码 1 已加拟合前强制过滤。四、动手练习练习 1口径对齐把代码 1 的对照表扩充一列scope为 Sherman 行标注「含压缩级间回收」。然后分别用「降权0.6」与「口径拆分改用 3.51」两种方式各标定一次比较参数差异。成功判据能定量说出两种处理方式带来的 SRD 预测差异量级应在 0.1 GJ/t 左右并说明哪种更适合自己的应用场景。练习 2稳态筛选的阈值敏感性在代码 2 中把max_rel_drift依次设为 0.01、0.02、0.05max_cv固定 0.03记录「漂移段整窗误判比例」与「稳态窗口占比」。成功判据本机实测基线0.02 时稳态占比 83.2%、漂移段误判 0.0%收紧到 0.01 时稳态占比降到 76.9%误判仍 0.0%放宽到 0.05 时稳态占比升到 88.4%但误判跳到 40.4%。能解释「为什么 0.02 附近存在一个甜区」并给出你最终选定的阈值与理由即算通过。练习 3样本量与模型复杂度的权衡把代码 3 的srd_model换成三参数版本t0 t1*(1-cap) t2*(mea-30)/5重新跑一遍 LOO 与留组外推。成功判据本机实测基线三参数时 LOO 的 MAE 从 0.302 恶化到 0.913最大绝对误差从 0.410 恶化到 1.605 GJ/t能解释「为什么训练点只有 4 个时增加参数反而让验证误差变差」并据此写出本模型适用域的一句话结论。五、小结与下一篇预告标定的本质不是拟合而是口径管理。本篇做完了三件事把 TCM 三代 MEA 基线4.10 / 3.90 / 3.62 GJ/t与 Sherman 3.65、TCM 高捕集率 3.7 GJ/t 对齐到同一张表用滑窗双判据把过渡态数据挡在标定之外用留一 / 留组分别度量「同装置换工况」与「换装置外推」的能力。同时明确CCSI/Aspen 的 3.50 / 3.77 GJ/t 是模型值只能当交叉核对对象。但标定跑不起来的前提是模型能收敛。下一篇第 15 篇转向速率基塔的收敛诊断与初值工程为什么必须先平衡级、后速率基为什么填料高度过小会让「任何贫液负载与 L/G 都无解」以及怎么用残差轨迹区分「单调发散」「振荡」「停滞」三类失败模式。第 13 篇的参数可辨识性、第 5 篇的传递物性缺失问题会在那里汇合。本篇认知问题回显FAQQ1TCM 公开的 MEA 基线 SRD 有几个版本分别是多少ATCM 的 MEA 基线共有三代2014 年 4.10 GJ/t CO₂捕集率 90.0%、2015 年 3.9083.5%、加消泡剂后现行基线 3.6287.4%均为 30 wt% MEA。Q2NCCC 中试数据在 CCSI 模型整定中起什么作用ANCCC 位于 Wilsonville, Alabama其中试数据被 CCSI 用于整定验证 MEA 稳态模型分别约束物性、水力学、界面面积与反应动力学四类子模型。Q3中试数据标定前为什么要做稳态筛选判据是什么A过渡态数据会以参数偏移而非残差变大的方式污染标定判据用滑窗相对漂移与变异系数双条件两者对应正交的失效模式缺一不可。Q4标定好的模型能否直接预测中国机组的 SRDA不能。TCM 数值建立在特定烟气与装置上留组外推偏差通常远大于留一误差禁止把 TCM 数值无条件外推到中国机组工况。Q5怎么判断中试标定是过拟合而不是真有效A同时报留一与留组两类误差留一测同装置换工况留组测换装置外推若留组误差远大于留一误差说明模型只学到了训练域。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑