ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

2022数学建模C题玻璃风化全流程解析:从数据预处理到灰色关联度

2022数学建模C题玻璃风化全流程解析:从数据预处理到灰色关联度 简介这份资源是2022年全国大学生数学建模竞赛C题的完整解题资料面向备战数模竞赛的高校学生及指导教师聚焦古代玻璃文物的成分分析与鉴别这一典型赛题。压缩包内共1个PDF文件约3.55MB内容涵盖赛题文档与配套代码系统呈现了从数据预处理、数据探索到建模求解的全过程。资料围绕风化效应展开涉及主成分分析降维、因子分析构建风化到未风化成分的转换矩阵、敏感性分析验证模型鲁棒性以及灰色关联度分析比较不同类别玻璃的化学成分关联差异并给出高钾玻璃与铅钡玻璃的亚类划分方法。读者可借此掌握完整的赛题求解思路、建模步骤与结果解释理解分类预测与模型评估的实际应用。目前已有926人学习下载适合需要系统复盘该赛题、提升建模与数据分析能力的学习者参考。1. 2022全国大学生数学建模C题一份能跑通全流程的玻璃风化建模资源如果你正在准备数学建模竞赛尤其是想找一套完整的、能从头跑到尾的真题代码和文档那这份2022年全国大学生数学建模竞赛C题的资源包值得你花时间拆一遍。题目本身是古代玻璃制品的成分分析与鉴别背景不复杂玻璃埋在地下几千年表面会风化化学成分比例会变你要根据风化后的检测数据反推它没风化时长什么样还要把高钾玻璃和铅钡玻璃分开再往下做亚类划分和成分关联分析。听起来像考古实际上是一道标准的“数据预处理降维分类关联度”综合题。资源包里包含完整论文文档和配套代码覆盖了主成分分析、因子分析、灰色关联度、最短距离法聚类这几个核心方法。适合两类人一是第一次打国赛、需要看完整解题链路的新手二是做过几道题但总在“数据怎么洗、阈值怎么定、敏感性怎么证”上卡住的熟手。下面我按实际复现的顺序把这份资源拆开讲清楚。2. 数据预处理与风化系数从表单1到表单2的关联逻辑2.1 表单1的探索结论直接决定后续建模方向表单1记录的是玻璃文物的基本信息纹饰类型、颜色、玻璃类型、表面是否风化。资源里的论文先做了一轮频次统计和卡方检验得出几个关键结论。纹饰B的样品全部是高钾玻璃、全部风化、颜色全是蓝绿色纹饰A的高钾玻璃全部无风化铅钡玻璃风化与无风化比例约11:5纹饰C的高钾玻璃全部无风化铅钡玻璃风化与无风化比例约17:7。这几个数字不是随便看看的它们直接支撑了两个假设同等饰纹条件下铅钡玻璃比高钾玻璃更容易风化饰纹B代表的环境风化效应更强。后续所有建模都建立在这两个判断上。卡方检验的结果也值得注意。纹饰与类型的卡方值16.394P值0.000颜色与类型的卡方值26.017P值0.001表面风化与类型的卡方值3.861P值0.049。效应量化方面颜色的Phi系数0.707纹饰0.561表面风化只有0.272。这说明颜色和纹饰与玻璃类型的关联很强而表面风化与类型的关联相对弱一些。这个结论会影响你后面做分类时选哪些特征。2.2 表单2的预处理步骤与风化系数定义表单2是化学成分数据每个样品有二氧化硅、氧化钠、氧化钾、氧化钙、氧化镁、氧化铝、氧化铁、氧化铜、氧化铅、氧化钡、五氧化二磷、氧化锶等十几个成分的百分比。原始数据不能直接拿来建模资源里的做法是先在Excel里做几步关联 在表单2右侧新增P列计算B到O列的成分合计 SUM(B2:O2) 从A列样品编号中提取编号放入Q列 LEFT(A2, FIND( , A2)-1) 通过编号将表单1的玻璃类型、是否风化、颜色、饰纹关联到R、S、T、U列 VLOOKUP(Q2, 表单1!A:E, 2, FALSE) VLOOKUP(Q2, 表单1!A:E, 3, FALSE) VLOOKUP(Q2, 表单1!A:E, 4, FALSE) VLOOKUP(Q2, 表单1!A:E, 5, FALSE)这几步的逻辑是表单2只有化学成分没有类型和风化标签必须通过样品编号把表单1的信息挂过来否则后面没法按类型分组建模。P列的合计用来检查数据是否有缺失或异常正常样品的成分合计应该在95%到105%之间。风化系数的定义是这份资源里比较有巧思的地方。论文针对铅钡玻璃和高钾玻璃分别定义了不同的公式# 铅钡玻璃风化系数 def weathering_coeff_PbBa(sio2, pbo, bao): return (pbo bao) / sio2 # 高钾玻璃风化系数 def weathering_coeff_K(sio2, k2o, cao, mgo, al2o3, fe2o3, cuo): return sio2 / (k2o cao mgo al2o3 fe2o3 cuo)铅钡玻璃风化后氧化铅和氧化钡含量升高、二氧化硅降低所以用(PbOBaO)/SiO2做比值值越大风化越严重。高钾玻璃反过来风化后二氧化硅升高、助熔剂成分降低所以用SiO2除以其他成分之和。这个定义不是拍脑袋来的是根据参考文献里两种玻璃风化机理相反这一事实推导的。2.3 风化阈值的确定与标签修正算出风化系数后按玻璃类型和饰纹分成三组分别排序观察。铅钡玻璃-A纹的风化系数在0.879和1.3之间有一个明显跳跃所以阈值定在1.0铅钡玻璃-C纹在0.8和1.2之间跳跃阈值也定在1.0高钾玻璃在7.23和12.41之间跳跃阈值定在10.0。这个“找跳跃点定阈值”的做法比拍脑袋定0.5或者1要靠谱得多。注意原始数据里有三个样品编号20、48、30部位1的“是否风化”标签与风化系数判断不一致资源里以风化系数为准做了手工调整。这一步在实际操作中很容易被忽略但不调整的话后面分类会出现标签噪声。3. 问题一建模主成分降维因子分析反推未风化成分3.1 为什么选因子分析而不是直接回归问题一的核心任务是根据风化后的成分数据预测未风化时的成分。这本质上是一个“逆变换”问题。资源里选的是因子分析模型思路是把成分向量X分解为公共因子和特殊因子的线性组合然后通过负载矩阵A的逆矩阵从风化后的观测值反推公共因子再还原未风化成分。为什么不用多元线性回归因为回归需要有成对的“风化前-风化后”训练数据但题目只给了风化后的检测值没有对应的未风化真值。因子分析的好处是它不需要配对标签只需要成分之间的协方差结构就能估计负载矩阵。当然这个假设比较强——它默认风化过程是线性的、连续的论文里也明确写了这条假设。3.2 主成分分析确定保留几个因子在做因子分析之前先用主成分分析降维。以铅钡玻璃-C纹为例论文选取了8个主成分累计贡献率超过97%。这个数字怎么来的看特征值排序后的累计贡献率曲线一般取到85%以上就够了但这里取到97%是为了保证反推精度。import numpy as np from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler # 假设 data 是 n x m 的成分矩阵每行一个样品 scaler StandardScaler() data_std scaler.fit_transform(data) pca PCA() pca.fit(data_std) # 打印累计贡献率 cumvar np.cumsum(pca.explained_variance_ratio_) for i, v in enumerate(cumvar): print(f前{i1}个主成分累计贡献率: {v:.4f}) # 选取累计贡献率超过97%的主成分个数 n_components np.searchsorted(cumvar, 0.97) 1 print(f保留主成分个数: {n_components})参数说明StandardScaler做标准化是必须的因为各成分的量纲虽然都是百分比但数值范围差异大二氧化硅可以到90%以上氧化锶可能只有0.1%不标准化的话主成分会被大量纲变量主导。n_components取searchsorted找到的第一个超过97%的位置比手动指定更稳妥。3.3 负载矩阵求逆与未风化成分预测拿到主成分后计算负载矩阵A。A的每一列是一个主成分对应的特征向量乘以特征值的平方根。然后对A求逆得到从风化成分到公共因子的转换系数矩阵。# 获取负载矩阵 A eigenvalues pca.explained_variance_[:n_components] eigenvectors pca.components_[:n_components].T A eigenvectors * np.sqrt(eigenvalues) # 对 A 求逆注意 A 不是方阵用伪逆 A_inv np.linalg.pinv(A) # 从风化成分反推公共因子 # x_weathered 是标准化后的风化成分向量 factors A_inv x_weathered # 还原未风化成分逆标准化 x_unweathered_std A factors x_unweathered scaler.inverse_transform(x_unweathered_std.reshape(1, -1))逻辑说明A是m×k矩阵m个成分k个主成分pinv求的是伪逆得到k×m的转换矩阵。factors是k维公共因子向量再乘回A得到m维的未风化成分估计。最后用inverse_transform还原到原始量纲。资源里给出了铅钡玻璃-C纹的完整转换系数矩阵和预测结果表可以直接对照验证。提示因子分析反推的精度高度依赖主成分个数和线性假设。如果风化过程非线性严重预测值会偏差很大。资源里没有做交叉验证这是可以改进的地方。4. 问题二与问题三主成分降维最短距离法聚类的分类链路4.1 四类数据的主成分分析与区间构建问题二要求对高钾玻璃和铅钡玻璃分别做亚类划分。资源里的做法是先把表单2的数据分成四类铅钡无风化、铅钡风化、高钾无风化、高钾风化。然后对每一类分别做主成分分析选出贡献率高的几个化学成分去掉最大值和最小值后用剩余数据的最大值和最小值构成一个区间。铅钡无风化类型选了6个成分SiO2、Na2O、K2O、CaO、MgO、Al2O3累计贡献率88.89%区间分别是[50.61, 69.71]、[0.8, 5.74]、[0.15, 0.32]、[0.38, 2.82]、[0.71, 1.49]、[1.44, 13.65]。高钾无风化选了5个成分累计贡献率也是88.89%。铅钡风化选了5个成分累计贡献率87.36%。高钾风化只选了3个成分SiO2、Na2O、K2O累计贡献率就到95.41%。def build_interval(data, feature_cols, cumvar_threshold0.85): 对指定特征列做主成分分析返回筛选后的特征区间 data: DataFrame feature_cols: 参与分析的列名列表 cumvar_threshold: 累计贡献率阈值 X data[feature_cols].values scaler StandardScaler() X_std scaler.fit_transform(X) pca PCA() pca.fit(X_std) cumvar np.cumsum(pca.explained_variance_ratio_) n np.searchsorted(cumvar, cumvar_threshold) 1 # 用前n个主成分的载荷绝对值之和排序选出重要特征 loadings np.abs(pca.components_[:n]).sum(axis0) important_idx np.argsort(loadings)[::-1] intervals {} for idx in important_idx: col feature_cols[idx] vals data[col].values vals_sorted np.sort(vals) # 去掉一个最大值和一个最小值 trimmed vals_sorted[1:-1] intervals[col] (trimmed.min(), trimmed.max()) return intervals, n参数说明cumvar_threshold取0.85是常规做法资源里实际取到了0.87到0.95之间说明作者希望保留更多信息。去掉最大值和最小值是为了避免极端值把区间拉得太宽导致分类边界模糊。返回的intervals字典可以直接用于后续分类判断。4.2 最短距离法聚类的亚类划分选出重要特征后资源里选了数据差异最大的二氧化硅做亚类划分。用最短距离法聚成2类得到两个聚点。铅钡无风化的聚点是64.82和52.49高钾无风化是71.22和62.77铅钡风化是33.96和15.63高钾风化是94.66和92.57。然后以两个聚点的平均值作为分界把二氧化硅数据分成两个区间。from scipy.cluster.hierarchy import linkage, fcluster from scipy.spatial.distance import pdist def subcluster_by_sio2(sio2_values, n_clusters2): 对二氧化硅含量做最短距离法聚类返回两个聚点和分界值 X sio2_values.reshape(-1, 1) # 最短距离法对应 methodsingle Z linkage(X, methodsingle) labels fcluster(Z, n_clusters, criterionmaxclust) centers [] for lab in range(1, n_clusters1): centers.append(sio2_values[labels lab].mean()) centers.sort() boundary (centers[0] centers[1]) / 2 return centers, boundary逻辑说明linkage的method参数选single就是最短距离法它定义类间距离为两类中最邻近样本的距离。fcluster按最大类别数切分。centers是两个类的均值boundary取均值的中点作为分界。这个分界值就是亚类划分的阈值。4.3 敏感性分析的3%扰动验证问题三要求对分类结果做敏感性分析。资源里的做法是给表单3的数据添加3%的随机扰动再代入问题二求得的区间做分类看结果是否改变。def sensitivity_test(data, intervals, perturbation0.03, n_trials100): 对数据进行随机扰动检验分类结果的稳定性 original_labels classify(data, intervals) change_count 0 for _ in range(n_trials): perturbed data.copy() for col in data.columns: noise np.random.uniform(-perturbation, perturbation, sizelen(data)) perturbed[col] data[col] * (1 noise) new_labels classify(perturbed, intervals) if not np.array_equal(original_labels, new_labels): change_count 1 sensitivity change_count / n_trials return sensitivity参数说明perturbation0.03对应3%的扰动幅度n_trials100是重复次数。sensitivity越接近0说明模型越鲁棒。资源里问题三的结论是扰动后分类结果一致敏感性不强但问题二中亚类划分的敏感性较强有三类数据误差超过20%。这个差异值得注意——分类和亚类划分的稳定性不是一回事。5. 避坑与排查这份资源里最容易翻车的五个地方5.1 风化系数阈值在不同饰纹间不能直接套用现象直接把铅钡玻璃-A纹的阈值1.0用到C纹上发现部分样品分类结果与标签矛盾。原因不同饰纹代表不同埋藏环境风化程度分布不同A纹和C纹的风化系数跳跃点虽然都在1.0附近但具体分布有差异。解决按饰纹分组后分别观察跳跃点A纹和C纹可以共用1.0但高钾玻璃必须单独定阈值10.0不能混用。5.2 主成分分析前忘记标准化导致降维失效现象不做标准化直接跑PCA第一主成分贡献率超过99%但后续分类效果很差。原因二氧化硅含量在60%到95%之间氧化锶可能只有0.1%不标准化的话PCA会被大量纲变量完全主导降维等于没降。解决用StandardScaler做Z-score标准化让每个成分的均值为0、方差为1再跑PCA。5.3 因子分析求逆时用错矩阵维度现象对负载矩阵A直接调用np.linalg.inv报错提示矩阵不是方阵。原因A是m×k矩阵m个成分k个主成分m不等于k不能求常规逆。解决用np.linalg.pinv求伪逆或者先做A.T A再求逆。资源里用的是伪逆结果一致。5.4 敏感性分析的扰动方式影响结论现象对数据加3%绝对扰动和对数据乘(13%)相对扰动得到的敏感性结论不同。原因不同成分的数值范围差异大绝对扰动对小数值成分影响更大。解决统一用相对扰动即乘以(1均匀噪声)噪声范围[-0.03, 0.03]。资源里用的是相对扰动。5.5 灰色关联度分析的分辨系数取值现象分辨系数ρ取不同值时关联度排序发生变化。原因ρ越小分辨力越大但太小会导致关联度对数据波动过于敏感。解决按论文里的做法取ρ0.5这是灰色关联度分析的标准取值。如果要做对比实验可以在0.3到0.7之间取几个值看排序是否稳定。6. 问题四的灰色关联度分析与全流程验证技巧问题四要求分析不同类别玻璃中化学成分之间的关联关系。资源里用的是灰色关联度分析具体做法是把每个类别的样品数据作为参考数列各化学成分作为比较数列计算关联系数和关联度然后排序。灰色关联度的核心公式是关联系数% 灰色关联度分析核心代码 function [grey_degree] grey_relation(X, Y, rho) % X: 参考数列 (n x 1) % Y: 比较数列矩阵 (n x m) % rho: 分辨系数通常取 0.5 [n, m] size(Y); % 初值化处理 X_norm X / X(1); Y_norm Y ./ Y(1, :); % 计算绝对差序列 delta abs(X_norm - Y_norm); % 计算关联系数 delta_min min(delta(:)); delta_max max(delta(:)); xi (delta_min rho * delta_max) ./ (delta rho * delta_max); % 计算关联度 grey_degree mean(xi, 1); end逻辑说明初值化处理是为了消除量纲影响每个数列除以自己的第一个元素。delta是参考数列和比较数列的绝对差。关联系数xi的公式里rho取0.5是标准做法。最后对每个比较数列的关联系数求平均得到关联度。关联度越大说明该化学成分与参考数列的关联越强。资源里的结论是铅钡玻璃的关联度排序为二氧化硅氧化钙氧化钾氧化铝氧化镁氧化钠高钾玻璃为二氧化硅氧化钠氧化钾氧化钙氧化镁。两类玻璃的关联度排序差异明显说明它们的成分关联结构不同。但四个类别之间比较时差异其实不大都是二氧化硅关联性最强。这里有一个我自己的教训。第一次做这道题的时候我直接把所有类别的数据混在一起跑灰色关联度结果排序出来跟论文对不上。后来才发现灰色关联度分析必须按类别分别做因为不同类别的参考数列不同混在一起算没有意义。从那以后我每次做关联度分析都强制走一遍“先分组、再分别计算、最后对比”的流程再也没翻过车。验证灰色关联度结果是否合理可以做一个简单检查把关联度排序与主成分分析的载荷排序对比。如果某个成分在主成分分析中载荷很高在灰色关联度中排序也应该靠前。资源里二氧化硅在两个分析中都是第一说明结果自洽。如果出现矛盾优先检查数据标准化和分辨系数取值。提示灰色关联度分析对数据量不敏感小样本也能跑但样本太少时关联度排序的稳定性会下降。资源里高钾风化类型只有7个样品关联度排序的置信度相对低一些做结论时要谨慎。希望帮到你。本文还有配套的精品资源点击获取
返回列表