前言
简单介绍一下我自己:博主专注建模四年,参与过大大小小数十来次数学建模,理解各类模型原理以及每种模型的建模流程和各类题目分析方法。参与过十余次数学建模大赛,三次美赛获得过二次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 <= x <= 105 else '无效')
df_filled
数据整合:将化学成分数据与文物的基本信息(如类型、纹饰、颜色)整合在一起,为后续分析做准备。
其中我们分别要提取出未风化和风化的数据,需要注意的是,表面风化特征中带有风化这一属性时,文物采样点会存在采样未风化这一情况,所以要过滤调,也就是存在着风化点中测量未风化点的情况,需要分析的更加具体一点,将这种情况剔除干净再来分析,从而得到一张完整的分析表格:
同理清洗无风化数据也是如此:
现在基于这份数据我们可以进行数据可视化来帮助我们分析每个化学元素的波动和是否存在明显特征规律,
def plot_scatter(df):
# 绘制散点图
plt.figure(figsize=(14, 6))
# 遍历每个样本绘制散点图
for column in df.columns[1:]: # 跳过'化学成分'列,从'样本1'开始
plt.scatter(df['化学成分'], df[column], label=column, s=100) # s控制点的大小
# 添加图例、标题和轴标签
plt.legend()
plt.title('化学成分含量')
plt.xlabel('化学成分')
plt.ylabel('含量')
plt.xticks(rotation=45) # 旋转x轴标签,以便更容易阅读
plt.grid(True) # 添加网格线
plt.tight_layout() # 调整布局以适应标签
plt.show()
我们要根据样本的纹理类型和颜色,三者分组分类:
来看具体效果:
很明显可以看到风化和未风化化学成分不同之处,可根据未风化的文物化学成分的平均含量去预测拟合,也可以用KNN这类算法去匹配最接近的进行拟合,那么第一问我们就做完了,我们马上开始第二问建模。
希望大家支持一下!到这里第一问建模就结束了,想要了解更多的欢迎联系博主再向大家推荐一下笔者精心打造的专栏。此专栏的目的就是为了让零基础快速使用各类数学模型以及代码,每一篇文章都包含实战项目以及可运行代码。博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路: