优秀数模解题思路分享-2022年数模国赛C题玻璃题的完整思路代码分享

文摘   2024-08-27 09:00   中国澳门  

2022年全国大学生数学建模竞赛评阅要点(附C题解析)

因为想借用一下这个公众号的赛题和评阅说明,那好,我们来分享一下这个赛题的解答。(解答不一定是最优解答,解答仅供参考)

下面先分析一下这个问题

问题1 首先利用卡方检验分析玻璃文物表面风化与玻璃类型、纹饰和颜色的关系;然后对 玻璃类型和有无风化进行分类描述统计,求得各类别化学成分数据的平均值、最大值、 最小值、峰度系数、偏度系数等数值,得到有无风化与化学成分含量的统计规律。再通过求得风化点成分数据与风化前后的均值差的关系进行预测 
在进行问题一的解答的时候,我们需要明确一点,这个题目一定要做数据预处理啊!这次的团队是参考了当年的解答说明的,还是做了成分数据预处理。

接下来使用的是卡方检验模型,方检验是离散对离散的常见模型。卡方检验的核心思想是计算样本的实际观 测值与理论推断值之间的偏离程度,通过卡方值的大小来判断实际与理论之间的吻合度。
在数据预处理这边做了描述性统计的处理,效果不错(该步骤可以spsspro进行)

问题2 用决策树探究分类规律的问题,首先用SPSS计算出特征重要性找到首要分类依据, 找到两类玻璃分类的关键成分以及划分依据;然后用K-means聚类的方法依据特征元素 将14组成分数据聚类:高钾3组,铅钡2组;最后验证模型的合理性,通过变动某一 成分辨析其敏感性。

在解答第二问的时候,本文是想找决策树模型,利用模型的特征重要性去找强特征进行分类。事实证明是这样的。

机器学习方法系列5——决策树(上)

机器学习方法系列6——决策树(下)

这个层次聚类可以用spsspro做出来,效果很好。

问题3 在探索未知类型玻璃分类的挑战中,问题三的核心策略聚焦于多种机器学习模型, 包括但不限于随机森林与XGBoost,这些模型以其卓越的分类能力和高效的计算能力在 业界广受好评。通过严格的对比测试,我们不仅衡量了各模型在准确率上的表现,还综 合考虑了模型的可解释性、训练时间等因素,最终择优而选,为玻璃分类任务提供了强 有力的技术支持和可靠的结论。

在本文中,论文选择了svm支持向量机,随机森林,xgboost,lightgbm

 问题4 鉴于玻璃表面化学成分数据的连续性及复杂性,问题四的分析采用了一套系统化、 多层次的策略。通过Pearson 相关性分析,绘制了相关性矩阵,直观展现各化学成分之 间相关性关系。紧接着,我们运用因子分析,从众多化学变量中提炼出少数几个主要因 子,,通过旋转后的成分矩阵,我们进一步细化了化学变量的分组,确保同组内的变量 具有高度相关性,特别是在高钾玻璃与铅钡玻璃中识别出了那些关联性显著的化学成分。为更精准地捕捉变量间的直接相互作用,我们深入进行了偏相关性分析。此步骤将其他 因素的潜在影响视为常数,聚焦于单独考察两个变量之间的纯粹关系,有效排除了混杂 因素的干扰,揭示了化学成分间复杂的相互作用机制。

最后一问是因子分析和偏相关分析。

到此论文基本脉络展示结束。

我们看看源代码吧,数据是官方给的,直接去官网下载。

import pandas as pdimport warnings warnings.filterwarnings('ignore')import osos.pathdata=pd.read_excel('附件.xlsx',sheet_name='表单1')data.head()data.columnsdata.describe()data.isnull().sum()data.dropna().to_excel('1.1.xlsx',index=None)temp=pd.DataFrame()temp['纹饰']=data['纹饰'].astype('category').cat.codes+1temp['类型']=data['类型'].astype('category').cat.codes+1temp['颜色']=data['颜色'].astype('category').cat.codes+1temp['表面风化']=data['表面风化'].astype('category').cat.codes+1 # 问题1.2:基于这些玻璃文物的类型,分析文物样品表面有无风化化学成分含量的统计规律;# 使用 apply 和 lambda 函数,同时处理非 NaN 和 NaN 值  # 注意:这里我选择了 0 作为 NaN 值的默认替代。你可以根据需求选择其他值。# 如果 '文物采样点' 列中的字符串长度可能小于 2,你可能还需要添加额外的检查来避免 IndexError。# 例如:data2=pd.read_excel('附件.xlsx',sheet_name='表单2')data2['文物编号'] = data2['文物采样点'].apply(lambda x: int(str(x)[:2])                                if pd.notna(x) and len(str(x)) >= 2 else 0)data['颜色'].fillna(data['颜色'].mode()[0],inplace=True)data2.isnull().sum()data2.fillna(0,inplace=True)data2.isnull().sum()data_merge=pd.merge(data,data2,on=['文物编号'])data_mergedata_merge.to_excel('1.2.xlsx',index=None)data_merge.columns# 分类汇总 # 变量:分组变量:{类型,表面风化};汇总变量:{二氧化硅(SiO2),#氧化钠(Na2O),氧化钾(K2O),氧化钙(CaO),氧化镁(MgO),氧化铝(Al2O3)#,氧化铁(Fe2O3),氧化铜(CuO),氧化铅(PbO),氧化钡(BaO),五氧化二磷(P2O5)#,氧化锶(SrO),氧化锡(SnO2),二氧化硫(SO2)}收起 # 参数:汇总类型:{均值,中位数,标准差,最大值,最小值}data_merge['sum']=0for i in ['二氧化硅(SiO2)', '氧化钠(Na2O)',       '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)',       '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)',       '氧化锡(SnO2)', '二氧化硫(SO2)']:    data_merge['sum']+=data_merge[i]data_merge[(data_merge['sum']<85)|(data_merge['sum']>105)]data_merge=data_merge[(data_merge['sum']>85)&(data_merge['sum']<105)]data_merge.reset_index(inplace=True,drop=True)


from sklearn.linear_model import LinearRegression  from sklearn.metrics import r2_score  from sklearn.preprocessing import OneHotEncoder    # 假设 data_merge 已经是一个包含所有数据的 DataFrame  # 转换分类特征为独热编码  categorical_features = ['纹饰', '类型', '颜色', '表面风化']  X = pd.get_dummies(data_merge[categorical_features])   # 提取数值特征(这里假设除了分类特征外,其他都是数值特征)  # 但由于您已经指定了目标变量,这里我们不需要额外提取   # 遍历目标变量  for target in ['二氧化硅(SiO2)', '氧化钠(Na2O)',                 '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)',                 '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)',                 '氧化锡(SnO2)', '二氧化硫(SO2)']:      y = data_merge[target]            # 创建线性回归模型      model = LinearRegression()      model.fit(X, y)            # 计算R²分数      r2 = r2_score(y, model.predict(X))            # 打印结果      print(f"\n{target} 的线性回归结果:")      print(f"R² 分数: {r2}")      print(f"模型系数: {model.coef_}")      print(f"模型截距: {model.intercept_}")temp1=Xtemp1['氧化钠(Na2O)']=data_merge['氧化钠(Na2O)']temp1.to_excel('1.2 岭回归.xlsx',index=None)# 岭回归:# 变量X:{纹饰_A,纹饰_B,纹饰_C,类型_铅钡,类型_高钾,颜色_浅绿,颜色_浅蓝,颜色_深绿,颜色_深蓝,颜色_紫,颜色_绿,颜色_蓝绿,颜色_黑,表面风化_无风化,表面风化_风化};因变量Y:{氧化钠(Na2O)}X1=data_merge[data_merge['表面风化']=='风化'][['文物编号', '纹饰', '类型', '颜色', '表面风化']]X1.reset_index(inplace=True,drop=True)X2=X.loc[data_merge[data_merge['表面风化']=='风化'].index][X.columns[:-1]]y=27.054+1.926*X2['纹饰_A']+40.805*X2['纹饰_B']+(-15.677)*X2['纹饰_C']+6.598*X2['类型_铅钡']+20.456*X2['类型_高钾']+16.807*X2['颜色_浅绿']+5.352*X2['颜色_浅蓝']+15.346*X2['颜色_深绿']+(-12.637)*X2['颜色_深蓝']+(-4.097)*X2['颜色_紫']+8.352*X2['颜色_绿']+1.279*X2['颜色_蓝绿']+(-3.348)*X2['颜色_黑']X1['二氧化硅(SiO2)']=y.to_list()y=0.818+0.566*X2['纹饰_A']-0.563*X2['纹饰_B']-0.368*X2['纹饰_C']-0.137*X2['类型_铅钡']+0.137*X2['类型_高钾']-0.254*X2['颜色_浅绿']+0.575*X2['颜色_浅蓝']+0.566*X2['颜色_深绿']-1.115*X2['颜色_深蓝']-0.305*X2['颜色_紫']+2.197*X2['颜色_绿']-0.408*X2['颜色_蓝绿']-1.185*X2['颜色_黑']X1['氧化钠(Na2O)']=y.to_list()y=0.858+2.694*X2['纹饰_A']+(-4.903)*X2['纹饰_B']+3.067*X2['纹饰_C']+(-4.237)*X2['类型_铅钡']+5.095*X2['类型_高钾']+0.088*X2['颜色_浅绿']+0.352*X2['颜色_浅蓝']+0.419*X2['颜色_深绿']+0.722*X2['颜色_深蓝']+(-0.039)*X2['颜色_紫']+(-0.151)*X2['颜色_绿']+(-0.9)*X2['颜色_蓝绿']+0.366*X2['颜色_黑']X1['氧化钾(K2O)']=y.to_list()y=0.761+1.332*X2['纹饰_A']+(-2.854)*X2['纹饰_B']+2.283*X2['纹饰_C']+(-1.237)*X2['类型_铅钡']+1.998*X2['类型_高钾']+(-0.11)*X2['颜色_浅绿']+0.109*X2['颜色_浅蓝']+(-0.898)*X2['颜色_深绿']+1.029*X2['颜色_深蓝']+(-0.468)*X2['颜色_紫']+(-0.623)*X2['颜色_绿']+0.15*X2['颜色_蓝绿']+1.571*X2['颜色_黑']X1['氧化钙(CaO)']=y.to_list()y=0.217+0.654*X2['纹饰_A']+(-0.63)*X2['纹饰_B']+0.194*X2['纹饰_C']+(-0.18)*X2['类型_铅钡']+0.398*X2['类型_高钾']+0.617*X2['颜色_浅绿']+0.145*X2['颜色_浅蓝']+(-0.205)*X2['颜色_深绿']+0.154*X2['颜色_深蓝']+(-0.238)*X2['颜色_紫']+(-0.201)*X2['颜色_绿']+(-0.036)*X2['颜色_蓝绿']+(-0.019)*X2['颜色_黑']X1['氧化镁(MgO)']=y.to_list()
y=1.389+3.821*X2['纹饰_A']+(-2.181)*X2['纹饰_B']+(-0.251)*X2['纹饰_C']+(-0.709)*X2['类型_铅钡']+2.098*X2['类型_高钾']+1.387*X2['颜色_浅绿']+1.225*X2['颜色_浅蓝']+1.362*X2['颜色_深绿']+(-1.98)*X2['颜色_深蓝']+0.251*X2['颜色_紫']+0.724*X2['颜色_绿']+(-0.466)*X2['颜色_蓝绿']+(-1.114)*X2['颜色_黑']X1['氧化铝(Al2O3)']=y.to_list()y=0.266+0.625*X2['纹饰_A']+(-0.777)*X2['纹饰_B']+0.418*X2['纹饰_C']+(-0.163)*X2['类型_铅钡']+0.43*X2['类型_高钾']+0.261*X2['颜色_浅绿']+(-0.039)*X2['颜色_浅蓝']+(-0.482)*X2['颜色_深绿']+0.346*X2['颜色_深蓝']+0.183*X2['颜色_紫']+(-0.869)*X2['颜色_绿']+0.428*X2['颜色_蓝绿']+0.439*X2['颜色_黑']X1['氧化铁(Fe2O3)']=y.to_list()y=0.572+0.539*X2['纹饰_A']+(-0.67)*X2['纹饰_B']+0.704*X2['纹饰_C']+(-0.008)*X2['类型_铅钡']+0.58*X2['类型_高钾']+(-1.378)*X2['颜色_浅绿']+0.093*X2['颜色_浅蓝']+(-0.541)*X2['颜色_深绿']+(-1.515)*X2['颜色_深蓝']+4.526*X2['颜色_紫']+(-0.625)*X2['颜色_绿']+0.724*X2['颜色_蓝绿']+(-0.713)*X2['颜色_黑']X1['氧化铜(CuO)']=y.to_list()y=5.161+(-1.254)*X2['纹饰_A']+(-8.675)*X2['纹饰_B']+15.089*X2['纹饰_C']+15.59*X2['类型_铅钡']+(-10.429)*X2['类型_高钾']+(-7.648)*X2['颜色_浅绿']+(-1.085)*X2['颜色_浅蓝']+(-2.256)*X2['颜色_深绿']+18.635*X2['颜色_深蓝']+(-12.837)*X2['颜色_紫']+0.886*X2['颜色_绿']+4.977*X2['颜色_蓝绿']+4.489*X2['颜色_黑']X1['氧化铅(PbO)']=y.to_list()y=2.192+1.825*X2['纹饰_A']+(-1.251)*X2['纹饰_B']+1.618*X2['纹饰_C']+5.599*X2['类型_铅钡']+(-3.407)*X2['类型_高钾']+(-3.556)*X2['颜色_浅绿']+(-3.152)*X2['颜色_浅蓝']+(-1.904)*X2['颜色_深绿']+(-0.302)*X2['颜色_深蓝']+15.852*X2['颜色_紫']+(-2.028)*X2['颜色_绿']+0.843*X2['颜色_蓝绿']+(-3.561)*X2['颜色_黑']X1['氧化钡(BaO)']=y.to_list()y=0.547+0.223*X2['纹饰_A']+(-2.059)*X2['纹饰_B']+2.383*X2['纹饰_C']+0.213*X2['类型_铅钡']+0.334*X2['类型_高钾']+(-0.364)*X2['颜色_浅绿']+0.555*X2['颜色_浅蓝']+(-3.049)*X2['颜色_深绿']+0.733*X2['颜色_深蓝']+(-0.106)*X2['颜色_紫']+(-1.959)*X2['颜色_绿']+0.076*X2['颜色_蓝绿']+4.662*X2['颜色_黑']X1['五氧化二磷(P2O5)']=y.to_list()y=0.063+(-0.006)*X2['纹饰_A']+0.003*X2['纹饰_B']+0.067*X2['纹饰_C']+0.157*X2['类型_铅钡']+(-0.094)*X2['类型_高钾']+(-0.159)*X2['颜色_浅绿']+0.064*X2['颜色_浅蓝']+(-0.031)*X2['颜色_深绿']+0.147*X2['颜色_深蓝']+0.208*X2['颜色_紫']+(-0.31)*X2['颜色_绿']+(-0.014)*X2['颜色_蓝绿']+0.158*X2['颜色_黑']X1['氧化锶(SrO)']=y.to_list()y=0.082+0.166*X2['纹饰_A']+(-0.122)*X2['纹饰_B']+0.039*X2['纹饰_C']+(-0.124)*X2['类型_铅钡']+0.206*X2['类型_高钾']+(-0.001)*X2['颜色_浅绿']+(-0.121)*X2['颜色_浅蓝']+(-0.102)*X2['颜色_深绿']+0.904*X2['颜色_深蓝']+(-0.076)*X2['颜色_紫']+0.074*X2['颜色_绿']+(-0.319)*X2['颜色_蓝绿']+(-0.278)*X2['颜色_黑']X1['氧化锡(SnO2)']=y.to_list()y=0.341+0.704*X2['纹饰_A']+(-0.775)*X2['纹饰_B']+0.412*X2['纹饰_C']+(-0.368)*X2['类型_铅钡']+0.709*X2['类型_高钾']+(-0.326)*X2['颜色_浅绿']+(-1.137)*X2['颜色_浅蓝']+(-0.283)*X2['颜色_深绿']+(-0.522)*X2['颜色_深蓝']+5.138*X2['颜色_紫']+0.13*X2['颜色_绿']+(-1.129)*X2['颜色_蓝绿']+(-1.531)*X2['颜色_黑']X1['二氧化硫(SO2)']=y.to_list()X1['sum']=0for i in ['二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)']: X1['sum']+=X1[i]for i in ['二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)']: X1[i]=X1[i].clip(lower=0)del X1['sum']print(X1)X1.to_excel('未风化文物风化前的化学成分含量.xlsx',index=None)# 问题 2 依据附件数据分析高钾玻璃、铅钡玻璃的分类规律;#对于每个类别选择合适的化学成分对其进行亚类划分,#给出具体的划分方法及划分结果,并对分类结果的合理性和敏感性 # 进行分析。# 分解问题:# 问题(1):分析高钾玻璃、铅钡玻璃的分类规律;# 构建一个可解释的机器学习分类模型,例如决策树、逻辑回归,以类型(高钾玻璃、铅钡玻璃)为Y,#尽可能构建足够多的特征X,形成可解释的分类规律。# 问题(2):对于每个类别选择合适的化学成分对其进行亚类划分,给出具体的划分方法及划分结果;# 分别对类别进行聚类模型# 问题(3):对分类结果的合理性和敏感性进行分析。# 对分类结果的合理性应该是放在问题(2)里面的,直接用一些量化划分聚类效果的评价指标进行评估,#对前面使用的模型参数进行调整,分析模型的敏感性data_merge.columnsdata_merge[['类型','二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)']].to_csv('2.csv',index=None)# 2.1:决策树分类# # 变量:# 变量X:{二氧化硅(SiO2),氧化钠(Na2O),氧化钾(K2O),氧化钙(CaO),#氧化镁(MgO),氧化铝(Al2O3),氧化铁(Fe2O3),氧化铜(CuO),氧化铅(PbO),#氧化钡(BaO),五氧化二磷(P2O5),氧化锶(SrO),氧化锡(SnO2),二氧化硫(SO2)};变量Y:{类型}KKK=data_merge[['类型','二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)']]KKK.head()import sysKKK[KKK['类型']=='高钾']import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score # 假设 KKK 是一个已存在的 DataFrame # 这里我们使用一些随机数据来模拟 from sklearn.datasets import make_blobs Xk, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0) # 确保 Xk 中只包含数值型列(在这个例子中,Xk 已经是数值型的) # 肘部图函数 def plot_elbow_curve(X, max_k=10): sse = {} silhouette_avg = {} for k in range(2, max_k+1): kmeans = KMeans(n_clusters=k, random_state=42).fit(X) sse[k] = kmeans.inertia_ # SSE,即簇内平方和 silhouette_avg[k] = silhouette_score(X, kmeans.labels_) # 轮廓系数 # 绘制 SSE 肘部图 plt.figure(figsize=(10, 6)) plt.plot(list(sse.keys()), list(sse.values()), marker='o') plt.xlabel('Number of clusters') plt.ylabel('SSE') plt.title('Elbow Method') plt.show() plot_elbow_curve(Xk, max_k=10)print(type(Xk))print(Xk)Xk = pd.DataFrame(Xk)print(Xk)k_means = KMeans(n_clusters=3, random_state=4)k_means.fit(Xk[Xk.columns[1:]])y_predict = k_means.predict(Xk[Xk.columns[1:]])Xk['分类']=y_predictXk.to_excel('2.2.高钾.xlsx',index=None)Xk=KKK[KKK['类型']=='铅钡']Xk.reset_index(inplace=True,drop=True)def calculate_inertia(X, k_range): inertias = [] for k in k_range: kmeans = KMeans(n_clusters=k, random_state=4) kmeans.fit(X) inertias.append(kmeans.inertia_) return inertias print(Xk)# 选择的 k 范围 k_range = range(2, 11) # 计算每个 k 的惯性得分 inertias = calculate_inertia(Xk.iloc[:, 1:], k_range) # 假设我们只使用第二列到最后一列 # 绘制肘部法则图 plt.figure(figsize=(10, 6)) plt.plot(k_range, inertias, marker='o') plt.xlabel('Number of clusters') plt.ylabel('Inertia') plt.title('Elbow Method') plt.grid(True) plt.show()# 决策树分类# 变量:变量X:{二氧化硅(SiO2),氧化钠(Na2O),氧化钾(K2O),氧化钙(CaO),氧化镁(MgO),氧化铝(Al2O3),氧化铁(Fe2O3),氧化铜(CuO),氧化铅(PbO),氧化钡(BaO),五氧化二磷(P2O5),氧化锶(SrO),氧化锡(SnO2),二氧化硫(SO2)};变量Y:{分类}k_means = KMeans(n_clusters=5, random_state=4)k_means.fit(Xk[Xk.columns[1:]])y_predict = k_means.predict(Xk[Xk.columns[1:]])Xk['分类']=y_predictXk.to_excel('2.2.铅钡.xlsx',index=None)# 决策树分类 # 变量:# 变量X:{二氧化硅(SiO2),氧化钠(Na2O),氧化钾(K2O),#氧化钙(CaO),氧化镁(MgO),氧化铝(Al2O3),氧化铁(Fe2O3),#氧化铜(CuO),氧化铅(PbO),氧化钡(BaO),五氧化二磷(P2O5),#氧化锶(SrO),氧化锡(SnO2),二氧化硫(SO2)};变量Y:{分类}
# 问题 3 对附件表单 3 中未知类别玻璃文物的化学成分进行分析,#鉴别其所属类型,并对分类结果的敏感性进行分析。# 问题(1):对附件表单 3 中未知类别玻璃文物的化学成分进行分析,鉴别其所属类型;# 基于问题2,预测表单3未知类别玻璃文物的类型# 问题(2):对分类结果的敏感性进行分析。data3=pd.read_excel('附件.xlsx',sheet_name='表单3')data3.head()data3.fillna(0,inplace=True)data3=pd.concat([data3,pd.get_dummies(data3['表面风化'])],axis=1)data3.head()data_merge=data_merge[['类型','表面风化','二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)']]data_merge=pd.concat([data_merge,pd.get_dummies(data_merge['表面风化'])],axis=1)data_merge.head()import xgboost as xgbimport lightgbm as lgbfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import classification_report,f1_scorefrom sklearn.model_selection import train_test_splitdata_merge.columnsdata_merge.to_excel('3.1data_merge.xlsx',index=None) from sklearn.preprocessing import LabelEncoder X = data_merge[['二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)',\ '二氧化硫(SO2)', '无风化', '风化']] y = data_merge['类型'] # 使用 LabelEncoder 转换目标变量 label_encoder = LabelEncoder() y_encoded = label_encoder.fit_transform(y) # 拆分训练集和测试集 x_train, x_test, y_train, y_test = train_test_split(X, y_encoded, \ test_size=0.3, random_state=12) # 逻辑回归 model = LogisticRegression() model.fit(x_train, y_train) print('逻辑回归') print(classification_report(model.predict(x_test), y_test,\ target_names=label_encoder.classes_)) # RandomForest分类 model = RandomForestClassifier(n_estimators=100,\ random_state=12) # 设置树的数量和随机状态 model.fit(x_train, y_train) print('RandomForest分类') print(classification_report(model.predict(x_test),\ y_test, target_names=label_encoder.classes_)) # lgbm分类 model = lgb.LGBMClassifier(n_estimators=100,\ learning_rate=0.1, random_state=12) # 设置参数 model.fit(x_train, y_train) print('lgbm分类') print(classification_report(model.predict(x_test),\ y_test, target_names=label_encoder.classes_)) # XGboost分类 model = xgb.XGBClassifier(n_estimators=100,\ learning_rate=0.1,\ use_label_encoder=False, \ eval_metric='mlogloss', random_state=12) model.fit(x_train, y_train) print('XGboost分类') print(classification_report(model.predict(x_test),\ y_test, target_names=label_encoder.classes_))model = RandomForestClassifier()model.fit(X, y)model.predict(data3[['二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)',\ '无风化','风化']])#取消科学计数法pd.set_option("display.float_format", \ lambda x: "%.2f" % x)np.set_printoptions(suppress=True)# 支持中文plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = Falsedata_X=[]data_y=[]for i in range(1,1000,20): model = RandomForestClassifier(n_estimators=i, max_depth=None) model.fit(X, y) data_X.append(i) data_y.append(f1_score(y,model.predict(X), pos_label="高钾")) print(i)plt.plot(data_X, data_y, label='F1 分数随 n_estimators 的变化') plt.xlabel('n_estimators') plt.ylabel('f1') plt.title('n_estimators的敏感度分析') plt.legend()plt.savefig('n_estimators的敏感度分析.jpg')plt.show()data_X = [] data_y = [] for i in range(1, 50, 2): model = RandomForestClassifier(n_estimators=50, max_depth=i)# 修正了逗号缺失的问题 model.fit(X, y) predictions = model.predict(X) data_X.append(i) data_y.append(f1_score(y, predictions, pos_label="高钾")) print(i) plt.plot(data_X, data_y, label='F1 分数随 n_estimators 的变化') plt.xlabel('max_depth') plt.ylabel('f1') plt.title('max_depth 的敏感度分析') # 如果未来要添加多条线,可以取消注释并设置适当的 label plt.legend() plt.savefig('max_depth 的敏感度分析.jpg') plt.show()# 问题 4 针对不同类别的玻璃文物样品,分析其化学成分之间的关联关系,#并比较不同类别之间的化学成分关联关系的差异性。# 问题(1):针对不同类别的玻璃文物样品,分析其化学成分之间的关联关系# 与问题1的问题(2)类似,只是减少了一个条件——有无风化# 问题(2):比较不同类别之间的化学成分关联关系的差异性。# 与问题1的问题(2)类似data_merge.columnsdata_merge[['类型', '二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)']].\ to_excel('4.xlsx',index=None)# 独立样本MannWhitney U检验# 变量:变量X:{类型};变量Y:{二氧化硅(SiO2),氧化钠(Na2O),#氧化钾(K2O),氧化钙(CaO),氧化镁(MgO),氧化铝(Al2O3),#氧化铁(Fe2O3),氧化铜(CuO),氧化铅(PbO),氧化钡(BaO),五氧化二磷(P2O5),#氧化锶(SrO),氧化锡(SnO2),二氧化硫(SO2)}import seaborn as sns high_potassium = data_merge[data_merge['类型'] == '高钾']\ [['二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)',\ '氧化钙(CaO)',\ '氧化镁(MgO)', '氧化铝(Al2O3)',\ '氧化铁(Fe2O3)', '氧化铜(CuO)', \ '氧化铅(PbO)', '氧化钡(BaO)', \ '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)']] high_potassium.to_excel('4.1高钾.xlsx',index=None)# 确保没有NaN值 high_potassium = high_potassium.dropna() # 计算相关性矩阵 correlation_matrix1 = high_potassium.corr() # 绘制热图 plt.figure(figsize=(10, 8)) # 设置图形的大小 sns.heatmap(correlation_matrix1, annot=True, cmap='coolwarm', fmt=".2f") plt.title('高钾类型数据的相关性热图') plt.show() plt.savefig('4.1高钾_相关性热图.png') # 保存为PNG图片文件lead_barium = data_merge[data_merge['类型'] == '铅钡']\ [['类型', '二氧化硅(SiO2)', '氧化钠(Na2O)', '氧化钾(K2O)', '氧化钙(CaO)', '氧化镁(MgO)', '氧化铝(Al2O3)', '氧化铁(Fe2O3)', '氧化铜(CuO)', '氧化铅(PbO)', '氧化钡(BaO)', '五氧化二磷(P2O5)', '氧化锶(SrO)', '氧化锡(SnO2)', '二氧化硫(SO2)']]lead_barium.to_excel('4.2铅钡.xlsx',index=None)# 确保没有NaN值 lead_barium = lead_barium.dropna() # 移除非数值列(在这里是'类型'列) numeric_columns = lead_barium.select_dtypes(include=['number']).columns lead_barium = lead_barium[numeric_columns] # 计算相关性矩阵 correlation_matrix2 = lead_barium.corr() # 绘制热图 plt.figure(figsize=(10, 8)) # 设置图形的大小 sns.heatmap(correlation_matrix2, annot=True, cmap='coolwarm', fmt=".2f") plt.title('铅钡类型数据的相关性热图') # 保存热图为PNG图片文件 plt.savefig('4.2铅钡_相关性热图.png') plt.show()


致谢:2022级数学(优师)专业傅国华,2023级数学(优师)专业谭周舟,杨宇琴
本次分享就到这里下次见(本题绝大部分是可以基于spsspro解答的,可以多去尝试一下)

师苑数模
发布数模协会培训推文,讲解数模算法。赛题讲解及比赛通知。学校竞赛结果及学校竞赛成绩发布等文章。
 最新文章