2022 年高教社杯全国大学生数学建模竞赛-C 题 古代玻璃制品的成分分析与鉴别详解+Python代码源码
前言
简单介绍一下我自己:博主专注建模四年,参与过大大小小数十来次数学建模,理解各类模型原理以及每种模型的建模流程和各类题目分析方法。参与过十余次数学建模大赛,三次美赛获得过二次M奖一次H奖,国赛二等奖。**提供免费的思路和部分源码,以后的数模比赛只要我还有时间肯定会第一时间写出免费开源思路。**博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路和代码写进此专栏以及详细思路和完全代码且完全免费。希望有需求的小伙伴不要错过笔者精心打造的文章。
建模预览
数学建模的基本步骤大致如下:
- 问题定义:明确你需要解决的问题。这包括对问题的背景进行研究,理解问题的实际意义,以及确定问题的边界条件和假设。
- 建立数学模型:将实际问题转换为数学问题。这通常涉及到定义变量、参数、约束条件以及目标函数(如果是优化问题的话)。
- 求解数学模型:选择合适的数学工具和方法求解模型。这可能包括解析方法、数值方法、仿真等。
- 模型验证与分析:使用实际数据测试模型的有效性,分析模型结果,对模型进行必要的调整和优化。
- 撰写模型报告:详细记录模型的建立过程、求解步骤、结果分析以及模型的局限性等。
题目背景
背景是关于丝绸之路上的古代玻璃贸易和技术传播,特别是关注于早期玻璃物品的化学成分分析,以探索其来源、制造工艺和历史演变。玻璃作为早期中西方文化交流的重要物质证据,其研究揭示了古代贸易网络、文化交流和技术传承的复杂性。以下是题目背景的几个关键点:
- 丝绸之路与玻璃贸易:丝绸之路不仅是古代东西方丝绸贸易的通道,也是包括玻璃在内的多种商品和技术交流的纽带。早期的玻璃在西亚和埃及地区较为常见,通过贸易网络传入中国。
- 玻璃制作技术:古代玻璃的主要原料是石英砂,由于纯石英砂熔点较高,古人在炼制玻璃时会添加助熔剂以降低熔化温度,如草木灰、天然泡碱、硝石和铅矿石等,不同的助熔剂添加会导致玻璃化学成分的差异。
- 玻璃类型:根据添加的助熔剂不同,古代玻璃可以分为多种类型,如铅钡玻璃和高钾玻璃等。铅钡玻璃通常认为是中国自己发明的玻璃品种,而高钾玻璃则在岭南、东南亚和印度等地区较为流行。
- 风化现象:古代玻璃在埋藏环境中易受风化影响,其内部元素会与环境元素进行交换,导致化学成分比例发生变化。这种风化现象会影响到对玻璃文物类别的判断。
通过分析古代玻璃文物的化学成分和风化情况,可以揭示其来源、制造工艺以及古代贸易和文化交流的信息,对于研究古代文明有重要意义。题目要求基于提供的数据,进行详细的数学建模和分析,以解决关于玻璃文物分类、风化影响评估和化学成分关联分析的问题。
问题 1
对这些玻璃文物的表面风化与其玻璃类型、纹饰和颜色的关系进行分析;结合玻璃的类型,分析文物样品表面有无风化化学成分含量的统计规律,并根据风化点检测数据,预测其风化前的化学成分含量。
建模解答
针对问题一,我们的目标是分析古代玻璃文物的表面风化与其玻璃类型、纹饰和颜色之间的关系,并预测风化前的化学成分含量。
步骤 1: 数据预处理
处理缺失值:对化学成分数据中的缺失值进行处理,可以选择填充(例如使用成分的平均值)或者删除含有过多缺失值的样本。
import pandas as pd import numpy as np def read_excel_to_dataframe(file_path): """ 读取 Excel 文件并将其转换为 Pandas DataFrame。 参数: file_path (str): Excel 文件的路径。 返回: DataFrame: 从 Excel 文件中读取的数据。 """ try: df = pd.read_excel(file_path,header=0) return df except Exception as e: print(f"读取文件时发生错误: {e}") return None
我们对数据进行预览查看数据是否有空缺值:
我们发现文物颜色这一特征是存在缺失值的,基于数据来看最好的方式可以通过一些机器学习算法进行填充,能够保证填充的数据具有一定的准确性,这里采用使用随机森林进行缺失值填充:使用没有缺失值的数据来训练一个随机森林模型,其中,预测变量是除了要填充缺失值的列以外的其他列,目标变量是需要填充缺失值的列。
ef full_RF(df): # 假设df是你的DataFrame,首先创建一个副本以避免修改原始DataFrame df_copy = df.copy() # 首先,对非数值列进行编码 encoder = LabelEncoder() for column in df_copy.columns.drop('颜色'): df_copy[column] = encoder.fit_transform(df_copy[column]) # 分离出有缺失值和没有缺失值的数据 df_missing = df_copy[df_copy['颜色'].isnull()] df_no_missing = df_copy.dropna() # 准备训练数据 X_train = df_no_missing.drop('颜色', axis=1) y_train = df_no_missing['颜色'] # 训练随机森林模型 model = RandomForestClassifier(n_estimators=100, random_state=42) model.fit(X_train, y_train) # 对缺失值进行预测 X_missing = df_missing.drop('颜色', axis=1) predicted_colors = model.predict(X_missing) # 填充缺失值 df_copy.loc[df_copy['颜色'].isnull(), '颜色'] = predicted_colors return df_copy
关于表单2我们需要明白我们的是空白处表示未检测到该成分,因此我们不需要填充空缺数据,需要判断每行的总和是否在85%到105%之间,并将结果添加为新的一列“有效性”:
sums = df_filled.drop(columns=['文物采样点']).sum(axis=1) df_filled['总和']=sums # 判断每行的总和是否在85%到105%之间,并将结果添加为新的一列“有效性” df_filled['有效性'] = sums.apply(lambda x: '有效' if 85