
简介一份围绕人工智能与分析化学交叉应用的PPT课件面向化学、化工、药学等专业师生及科研人员用于快速建立人工智能赋能分析化学的整体认知。课件从智能与人工智能的基本概念讲起梳理生物智能、人工智能与计算智能之间的关系并围绕认知学派、逻辑学派、行为主义学派和连接主义学派的研究思路展开同时结合专家系统的知识库、推理机等核心组成说明人工智能在谱图解析、分离条件选择、实验方案优化、分子模拟设计等场景中的具体应用。全包仅含1个PPT文件大小3.48MB页面编排清晰便于课堂演示或自学浏览。目前已有150人学习适合作为分析化学、化学信息学等相关课程的教学辅助或入门资料帮助读者理解人工智能在数据分析、模式识别与化学信息处理中的落地方式。1. 从分析化学数据到人工智能决策一个光谱解析的硬仗分析化学仪器一年产出的数据量远超一个熟练实验员能手工处理的范围。比如一台高分辨质谱一个批次就能生成上千个特征片段红外光谱仪每天跑200张谱图也常见。人工智能技术的价值是把传统上依赖经验识谱的工作压缩成一条可训练的流水线数据洗到标准化模型学会区分官能团误差用一个置信区间告诉化学家“该相信多少”。这篇内容面向正在把实验室数据接入机器学习平台的工程师也面向想用AI替代手动谱图解析的分析化学从业者。不堆公式只讲能落地的那部分。2. 分析化学中的AI数据管线预处理、基线校正与特征选择分析化学的数据天生不适合直接扔进神经网络。原因很简单不同仪器、不同批次的谱图噪声和基线漂移各有差异如果跳过预处理模型学的不是化学信息而是仪器状态。我一般把数据管线拆成四步质量检查、平滑、基线与归一化、特征选择。这四步做完后续建模才可能稳定跨批次复现。2.1 光谱数据的标准化与异常值剔除先看原始矩阵行为样本列为波长或质荷比。很多开源数据集里含有空值或明显异常值比如透光率大于100%或者负强度。第一步不是插值而是先用统计方法把物理上不可能的点剔除。常见做法是计算每个样本的均值与标准差再用z-score过滤。import numpy as np import pandas as pd # 假设 X 是 (n_samples, n_features) 的光谱矩阵sample_names 是样本名 df pd.DataFrame(X) df.columns [fwavelength_{i} for i in range(df.shape[1])] df[mean] df.mean(axis1) df[std] df.std(axis1) z_scores np.abs((df[mean] - df[mean].mean()) / df[mean].std()) valid_idx z_scores 3.5 df_clean df.loc[valid_idx, df.columns[:-2]]这段代码计算每个光谱的全局均值再对整个样本集做一次z-score过滤。3.5是经验阈值太大会放过异常样本太小会把正常样本误杀如果你处理的是拉曼光谱建议调到3.0因为拉曼峰强度分布更重尾普通均值阈值容易失真。剔除异常后再接标准化。分析化学里标准化的方式不是一律用MinMax而是根据后续模型选择。若用SVM或PCA用StandardScaler若用树模型根本不需要标准化反而保留原始量纲可以保留峰的物理意义。我通常同时跑两套先看哪一套交叉验证分数更高再决定最终管线。2.2 基线校正与平滑用SciPy拟合基线基线漂移是光谱分析最常见的坑。它来自荧光背景、光散射或仪器基线。代码上的处理核心是用少量参数拟合一条平滑基线再从原始谱图中减掉。常用的方法有airPLS、多项式拟合法和移动平均。这里给出一个用SciPy做多项式基线校正的案例from scipy.linalg import cholesky import numpy as np def polynomial_baseline(y, order3, max_iter100, ratio0.01): x np.linspace(0, 1, len(y)) mask np.ones_like(y, dtypebool) for _ in range(max_iter): coeffs np.polyfit(x[mask], y[mask], order) baseline np.polyval(coeffs, x) residual y - baseline new_mask residual -ratio * np.max(y) if np.all(new_mask mask): break mask new_mask return baseline这个迭代过程中每次只保留高于当前基线的点拟合新基线重复几次后基线逐渐贴近谱图的底部。order3适合色谱基线红外光谱建议order5因为其基线弯曲更复杂。ratio0.01控制阈值如果背景噪声很大可以适当调大但太大会把弱峰一起抹掉。下表是我在真实项目中比较几种基线方法的经验值方法适用数据参数建议缺点/坑airPLS拉曼光谱、强噪声lambda10^5porder1对尖锐峰敏感会削峰多项式迭代红外、紫外order3~5iter100需要合理初始阈值移动平均色谱基线window5~15窗口太大会抹掉相邻峰移动平均窗口如果设置成15对窄峰意味着把峰形拉宽保留时间会发生偏移。因此平滑步骤永远在基线校正之后做顺序反了会出现“假双峰”。这一步做完整个数据管线才敢进入建模。2.3 特征选择不要直接拉平整个谱图很多AI教程喜欢把全谱输入模型这在分析化学中常常失败。原因有两个一是谱特征有高共线性连续波长的数值高度相关二是无关变量会稀释模型的信号。我建议先在降维前用统计学方法做一个粗筛计算每个特征与目标变量的相关度或ANOVA F值再选前K个特征。from sklearn.feature_selection import SelectKBest, f_classif selector SelectKBest(score_funcf_classif, k200) X_selected selector.fit_transform(X_clean, y) selected_idx selector.get_support(indicesTrue)这里的f_classif适用于分类问题如果是回归用f_regression。选200个特征是一个起始经验值具体需要根据谱图分辨率调整。特征选择这一步能让你后续建模时的过拟合风险下降一大截也便于向实验人员解释哪些波长的峰参与了决策。做完特征选择后要把选中的特征索引保存下来后续对未知样本做预测时必须用同一索引切出对应特征否则维度对不上。如果你的数据本身来自LC-MS轮廓峰位对齐后会有数千个特征直接用全谱会让随机森林的OOB得分虚高。用SelectKBest粗筛后再进入PCA或PLS做二次压缩是比较稳妥的路径。常见做法是先化学规则筛除同位素峰再做统计筛选最后用模型自身的feature importance回头验证。3. 用机器学习构建分析化学分类与回归模型以红外光谱和色谱为例当数据预处理管线稳定后下一步就是训练模型。分析化学领域的机器学习项目分类任务常见的有识别未知物是否含特定官能团、判别纯物质与混合物、质谱谱库检索。回归任务则包括浓度预测、保留时间预测、定量分析。你要先明确任务是分类还是回归再选模型。下面我从分类和回归各举一个例子。3.1 红外光谱分类SVM与随机森林的取舍红外光谱数据经过基线校正后特征往往有几百维。对于中小样本集通常几百个样本支持向量机SVM以径向基核函数为默认选择。随机森林则适合你同时想看到特征重要性的场景。下面是一段完整的分类训练流程from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier from sklearn.preprocessing import StandardScaler from sklearn.pipeline import make_pipeline from sklearn.model_selection import cross_val_score, train_test_split # X_selected, y 来自上一章的预处理 X_train, X_test, y_train, y_test train_test_split(X_selected, y, test_size0.2, random_state42) svm_model make_pipeline(StandardScaler(), SVC(kernelrbf, C10, gamma0.01, probabilityTrue)) svm_model.fit(X_train, y_train) rf_model RandomForestClassifier(n_estimators300, max_depth5, min_samples_leaf3, random_state42) rf_model.fit(X_train, y_train) print(SVM CV score:, cross_val_score(svm_model, X_train, y_train, cv5).mean()) print(RF CV score:, cross_val_score(rf_model, X_train, y_train, cv5).mean())注意SVM在管道里先做StandardScaler这是因为径向基核函数依赖距离度量随机森林不需要标准化但为了统一代码这里把它放在同一交叉验证逻辑下。C10和gamma0.01是我在红外数据集上常用的起始点。对于拉曼光谱C在1~100之间gamma则要更小比如0.001因为拉曼峰更尖核函数对尺度更敏感。如果你的样本量不足百建议使用留一法LOO替代普通5折交叉验证。化学数据的数据量通常小5折容易高估模型性能留一法虽然慢但能更真实反映单样本预测的场景。这也是人工智能基础概念里经常会强调的小样本陷阱。3.2 色谱保留时间预测从线性回归到梯度提升在色谱分析中一个常见任务是根据分子描述符预测保留时间。保留时间与分子结构之间存在复杂的非线性关系用随机森林或梯度提升树GBT比线性回归更稳。这里以LightGBM为例import lightgbm as lgb model lgb.LGBMRegressor( n_estimators500, learning_rate0.05, num_leaves31, max_depth-1, min_child_samples5, subsample0.8, colsample_bytree0.6 ) model.fit(X_train, y_train) y_pred model.predict(X_test)num_leaves限制树的复杂度对于分子描述符这种中等维度的特征31是一个常用值。colsample_bytree0.6让每棵树的特征随机采样60%能降低特征共线性造成的影响。min_child_samples5用于防止过拟合小数据集尤其关键太小会导致叶子节点几乎都是单个样本。这里是几种回归算法的对比表格供你选型算法线性回归随机森林回归LightGBM对特征尺度敏感不敏感不敏感过拟合风险低中等中高可解释性高中等低典型R²0.60.80.85如果你的保留时间数据来自不同液相色谱系统记得加入系统ID作为特征否则模型会把系统差异学成样本差异预测值在跨系统时会系统性偏移。比如ACQUITY和Agilent的梯度和流速不同模型需要显式感知这个环境变量。3.3 模型参数与化学意义的对齐这可能是分析化学中的AI项目最特殊的一点模型不只是看准确率还要看它学习的特征是否对应着化学上可解释的峰位。比如SVM的决策边界应该与分子振动频率相关。我的经验是如果模型在某个波长处的权重很大而这个波长正好对应某个官能团的特征峰那么模型的可靠性就更高。反之模型可能只是在用噪声做判断。所以建好模型后一定要把特征重要性系数映射到波长上可视化后与已知谱峰表对比。这个习惯会减少很多“为什么测试集上表现好、换一台仪器就崩”的问题。如果项目时间紧可以把这一步放在模型部署之后但不要省略。生成式人工智能应用工程师相关的课程里也会强调模型输出前必须做特征归因否则实验人员不敢签字。4. 深度学习在质谱与拉曼光谱中的实战从CNN到Transformer当样本量达到几千条机器学习方法容易遇到上限。深度学习可以自动挖掘谱图中局部相邻特征的关系这正是分析化学中“峰形相邻峰”的组合特征。在质谱与拉曼光谱中一维卷积1D-CNN是常见做法近年Transformer也开始被用于跨谱图关联建模。如果你正处在人工智能学习路径的实践阶段这部分可以直接当项目模板用。4.1 一维卷积模型把光谱当作时间序列光谱本质上是等间隔采样的序列信号因此和音频信号类似适合用卷积核捕捉局部峰形。下面是用PyTorch实现的一个轻量级1D-CNNimport torch.nn as nn class SpecCNN(nn.Module): def __init__(self, n_features, n_classes): super().__init__() self.conv1 nn.Sequential( nn.Conv1d(1, 16, kernel_size7, padding3), nn.BatchNorm1d(16), nn.ReLU(), nn.MaxPool1d(2) ) self.conv2 nn.Sequential( nn.Conv1d(16, 32, kernel_size5, padding2), nn.BatchNorm1d(32), nn.ReLU(), nn.MaxPool1d(2) ) self._init_fc_dim(n_features) self.fc nn.Linear(self.fc_dim, n_classes) def _init_fc_dim(self, n_features): import torch x torch.zeros(1, 1, n_features) x self.conv1(x) x self.conv2(x) self.fc_dim x.view(1, -1).size(1) def forward(self, x): x self.conv1(x) x self.conv2(x) x x.view(x.size(0), -1) return self.fc(x)kernel_size7对应光谱中7个连续波长。对于拉曼光谱这大约覆盖几十个波数足以捕捉一个峰的基本形状。BatchNorm1d在化学数据上特别有用能抑制不同批次样本的基线波动。注意如果原始谱图是长序列比如LC-MS轮廓可以先做下采样到2048点否则卷积层会太深参数量过大。训练模型时建议用Adam优化器学习率从1e-4开始batch size设32。如果出现过拟合先降低kernel_size或增加Dropout层不要一上来就加大数据增强。4.2 从CNN到Transformer为什么现在开始用Attention在质谱数据中峰的相对位置和强度对于物质识别至关重要。CNN的感受野始终有限要覆盖跨大范围的峰关系必须堆很多层。Transformer的self-attention理论上可以在第一层就“看到”整个谱图。对长色谱或质谱轮廓这是一个明显优势。一个常见的做法是先把光谱切成patch和ViT类似或者直接对每个质荷比位置做位置编码后输入Transformer encoder。但需要注意质谱数据通常高度稀疏直接对原始序列做attention计算量很大。我会先做一个简单投影把N个特征投影到较小的隐层维度再进入Transformer。import torch.nn as nn import torch class SpecTransformer(nn.Module): def __init__(self, n_features, d_model256, n_heads4, n_encoder_layers2): super().__init__() self.proj nn.Linear(1, d_model) self.pos_enc nn.Parameter(torch.randn(1, n_features, d_model) * 0.02) encoder_layer nn.TransformerEncoderLayer( d_modeld_model, nheadn_heads, dim_feedforward1024, batch_firstTrue ) self.encoder nn.TransformerEncoder(encoder_layer, num_layersn_encoder_layers) self.fc nn.Linear(d_model, 1) # 输出一个目标值 def forward(self, x): # x: (batch, features)将每个特征视为一维token x x.unsqueeze(-1) # (batch, features, 1) x self.proj(x) # (batch, features, d_model) x x self.pos_enc x self.encoder(x) # (batch, features, d_model) return self.fc(x.mean(dim1))这里把每个波长或质荷比视作一个token位置编码是学习的不是固定正弦。n_encoder_layers2通常够用于几千样本的项目太深反而容易过拟合。d_model256对于常见光谱长度500至2000点来说是一个平衡点再大会导致显存占用过高。该模型适合回归如果要分类把self.fc的输出节点改一下或者接上softmax即可。4.3 深度学习在分析化学中容易吃到的亏第一个坑是数据增强不合理。常见的加噪声增强在拉曼光谱上会放大基线残留应该先在原始谱图上做峰位微小的随机平移比如平移1到2个通道模拟仪器波长校准的微小漂移。第二个坑是样本数不足1500个样本以下的深度学习常常不稳定要谨慎使用否则不如第3章中的SVM或随机森林。第三个坑是类别不平衡比如质谱库中某些物质出现很多需要加权采样或使用focal loss。模型数据量要求训练耗时可解释性适用谱图类型1D-CNN2000低中红外/拉曼/色谱Transformer5000高低质谱/高分辨轮廓这张表可以作为你启动深度学习项目前的快速筛选器。数据量不到标准时优先回头用经典化学计量学方法而不是强行上大模型。分析化学项目很看重可复现性一个5000样本的Transformer训练结果如果波动很大反而不如一个稳定的随机森林。5. 分析化学AI模型的可靠性与可解释性验证技巧模型训练完之后不能只看测试集分数。分析化学对错误判断的容忍度很低比如把一个有毒物质判成无毒的后果是灾难性的。所以这一章集中在“如何验证模型不是偶然跑得好”以及“如何让化学家信任模型判断”这两个具体问题上。5.1 置换重要性检验判断模型是否在用噪声置换重要性Permutation Importance的基本思路是随机打乱一个特征的值看模型性能下降多少。如果打乱某个波长导致分数显著下降说明模型确实依赖该特征如果所有特征都下降很小那模型可能已经过拟合了样本序号或批次信息。from sklearn.inspection import permutation_importance result permutation_importance( svm_model, X_test, y_test, n_repeats30, random_state42 ) sorted_idx result.importances_mean.argsort()[::-1] print(sorted_idx[:10])n_repeats30会让重要性估计稳定一些但耗时也高。对于几百个样本的小数据集建议调到20。这一步能直接暴露那些“通过批次信息学到的假规律”。正常做法是打乱样本顺序后重新训练多次对比性能分布但这个成本太大工程上通常用置换重要性做替代。5.2 用SHAP把特征归因到波数而不是只看排名交叉验证和置换重要性只能告诉你“哪个特征重要”却无法告诉你“峰高了还是低了更有助于分类”。分析化学领域需要量化方向性比如某个物质浓度越高模型越倾向于判定为污染。这时候使用SHAP值。import shap explainer shap.Explainer(rf_model, X_train) shap_values explainer(X_test) # shap_values.shape (n_test, n_features, n_classes) for i in range(min(3, len(X_test))): shap.waterfall_plot(shap_values[i], max_display15)如果用的是SVM需要先传svm_model[1]因为管道里第0步是标准化器。shap.Explainer对树模型有原生支持对普通模型会慢一些。在化学项目中我习惯把SHAP值按波长保存成CSV然后叠加到原始谱图上做叠加展示。这个可视化的作用很大实验员看到模型关注的吸收峰刚好是羟基峰才会认可这个模型。输出CSV时记得把波长轴和SHAP值对齐import pandas as pd shap_df pd.DataFrame(shap_values.values.mean(axis0).T, columns[shap_mean]) shap_df[wavelength] wavelengths[selected_idx] shap_df.to_csv(shap_by_wavelength.csv, indexFalse)这里的wavelengths[selected_idx]对应特征选择后的位置。如果后续更换了特征选择参数必须重新生成映射否则波长标注会错位。将这份CSV嵌入到实验数据管理系统中就能让每个预测样本都附带一份可追溯的归因报告。模型偏见在光谱数据上的表现往往是“局部波段的错误高权重”。如果某几个SHAP值明显集中在噪声区就说明预处理阶段有遗漏。此时返回第2章检查平滑窗口和基线校正参数而不是迁就模型继续调参。整个流程最后的标准是特征归因与已知谱峰表高度一致且置换重要性在同一个波段稳定。这里常用的非对称残差拟合基线也会在SHAP可视化中暴露残留值得反复检查。本文还有配套的精品资源点击获取