数学建模竞赛实战:基于随机森林与特征工程的古代玻璃风化识别
1. 项目背景与核心挑战
2022年的高教社杯全国大学生数学建模竞赛,也就是我们常说的“国赛”,其C题在当时引起了不小的讨论。这道题目的背景设定非常贴近现实,聚焦于古代玻璃制品的化学成分分析与风化识别。简单来说,就是给参赛者一堆古代玻璃文物的化学成分检测数据,以及它们是否被风化(即因长期埋藏或环境因素导致化学成分和外观发生变化)的标签,要求大家建立一个模型,能够根据化学成分来准确判断一件玻璃制品是否风化,并进一步分析风化前后的成分变化规律,甚至对缺失的化学成分进行预测。
听起来是不是有点像考古学和材料科学的交叉课题?没错,这正是数学建模的魅力所在——它不局限于纯数学,而是要求你用数学工具去解决一个真实的、跨学科的问题。对于参赛者而言,这道题的挑战是多维度的。首先,数据是典型的“高维小样本”,化学成分指标(如二氧化硅、氧化钠、氧化钾等氧化物的含量)很多,但文物样本数量相对有限,这直接带来了过拟合的风险。其次,数据中不可避免地存在缺失值,有些文物的部分成分数据没有检测出来,如何处理这些缺失值本身就是一道建模前的必答题。最后,也是最核心的,你需要选择一个或一套合适的数学模型,来完成分类(风化与否)、关联分析(成分变化规律)和预测(补全缺失值)这三重任务。
我当时和队友花了大量时间在这道题上,从数据清洗、特征工程到模型选型、调参优化,踩了不少坑,也总结出一些比较实用的思路。今天,我就抛开那些复杂的公式和冗长的论文摘要,以一个过来人的视角,把这道C题的解题核心思路、代码实现的关键步骤,以及那些在官方优秀论文里可能不会细说的“实战经验”,系统地梳理一遍。无论你是正在备赛的同学,还是对数据挖掘和分类问题感兴趣的开发者,相信这些从真实比赛中沉淀下来的方法,都能给你带来直接的启发。
2. 数据理解与预处理:奠定模型大厦的基石
拿到赛题数据后,绝大多数新手会犯的第一个错误就是急急忙忙开始跑模型。在数学建模中,尤其是处理这种带有强烈现实背景的数据,前期在数据理解与预处理上投入的时间,往往能决定你最终模型效果的上限。2022年C题的数据集,我们可以把它想象成一个二维表格:每一行代表一件玻璃文物样本,每一列代表一个特征,主要包括文物编号、类型(高钾或铅钡)、颜色、以及多种化学成分的百分比含量,最后一列是标签——“风化”或“未风化”。
2.1 数据探索与可视化:用眼睛先“看”数据
在写任何一行处理代码之前,我们应该先对数据有一个整体的、感性的认识。我习惯用Python的Pandas和Matplotlib/Seaborn库来做这件事。
首先,是查看数据的基本情况:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 假设数据已加载为DataFrame `df`
print(df.info()) # 查看数据类型、缺失值情况
print(df.describe()) # 查看数值型特征的统计分布(均值、标准差、分位数等)
df.info() 会立刻告诉你哪些列有缺失值(Non-Null Count小于总行数)。在C题数据中,化学成分列出现缺失是常态,这可能是检测手段的限制或数据记录问题。 df.describe() 则能让你快速了解每个化学成分含量的大致范围、中心趋势和离散程度。比如,你会发现二氧化硅(SiO2)的含量普遍很高(符合玻璃主要成分是二氧化硅的常识),而一些微量元素含量则很低且波动大。
接下来,可视化是关键。我们可以绘制以下图形:
- 风化与未风化样本的数量分布条形图 :直观了解两类样本是否均衡。如果严重不均衡(比如未风化样本远多于风化样本),我们在后续建模时就需要考虑采用过采样、欠采样或调整类别权重的策略。
- 不同类型(高钾/铅钡)玻璃的成分均值对比柱状图 :这能帮你从宏观上把握两类玻璃的化学成分差异,为后续可能的分组分析提供依据。
- 化学成分的分布直方图或箱线图 :箱线图尤其有用,它能一眼看出数据的分布范围、中位数、异常值。你可能会发现某些成分的数据中存在一些极大或极小的“离群点”,这些点是需要重点审视的——它们是检测误差,还是某种特殊工艺的体现?
- 相关性热力图 :计算所有数值型特征(化学成分)之间的皮尔逊相关系数,并用热力图展示。这能帮助你发现高度相关的特征对。例如,氧化钠(Na2O)和氧化钾(K2O)可能存在一定的负相关,因为它们在古代玻璃中有时是相互替代的助熔剂。高相关性特征在后续建模时可能会引发多重共线性问题,可以考虑只保留其中一个,或使用主成分分析(PCA)进行降维。
# 示例:绘制风化状态分布图
plt.figure(figsize=(8,6))
sns.countplot(x='风化状态', data=df) # 假设‘风化状态’列名为‘Weathering_State’
plt.title('样本风化状态分布')
plt.show()
# 示例:绘制箱线图查看二氧化硅含量分布
plt.figure(figsize=(10,6))
sns.boxplot(x='风化状态', y='SiO2', data=df)
plt.title('不同风化状态下SiO2含量分布')
plt.show()
# 示例:绘制相关性热力图
plt.figure(figsize=(12,10))
numeric_df = df.select_dtypes(include=[np.number]) # 选择数值型列
corr_matrix = numeric_df.corr()
sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='coolwarm', center=0)
plt.title('化学成分相关性热力图')
plt.show()
注意 :数据可视化不是走过场。在这个过程中,你可能会发现一些数据录入错误(比如某个成分含量为9999,这显然不合理),或者对问题的背景有更深的领悟。例如,通过箱线图你可能会发现,风化样本的某些碱性氧化物(如Na2O、K2O)含量整体低于未风化样本,这非常符合风化过程会析出碱金属离子的化学常识。这个观察本身就可以成为你后续模型特征构建或结果分析的一个有力支撑点。
2.2 缺失值处理:没有“银弹”,只有合适的选择
面对缺失值,常见的处理方法有删除、均值/中位数/众数填充、插值法、以及使用模型预测。对于国赛C题,我们需要根据缺失的机制和比例来决策。
- 整行删除 :如果某个样本缺失的特征非常多(比如超过一半),或者该样本的标签(风化状态)缺失,那么直接删除该样本可能是最干净的选择。但国赛数据珍贵,样本量本就不大,此法需慎用。
- 统计值填充 :对于数值型特征(化学成分),常用均值或中位数填充。这里有一个 重要技巧 :不要直接用全体样本的均值去填充。更好的做法是, 依据玻璃类型(高钾/铅钡)和/或风化状态进行分组填充 。例如,一个高钾玻璃的氧化钾(K2O)数据缺失了,那么就用所有“高钾玻璃”样本的K2O含量的中位数(中位数对异常值更鲁棒)来填充它。这比使用全体样本均值更合理,因为高钾玻璃和铅钡玻璃的成分体系本就不同。
- 模型预测填充 :这是一种更高级但也更复杂的方法。例如,你可以将其他完整的化学成分作为特征,建立一个回归模型(如随机森林回归、KNN回归)来预测某个缺失列的值。这种方法理论上更精确,但计算成本高,且需要防止“数据泄露”——用未来数据预测过去。在实际比赛中,如果时间紧张,分组统计值填充是性价比最高的选择。
# 示例:按玻璃类型分组,用中位数填充缺失值
def fill_missing_by_group(df, group_col, fill_col):
"""按group_col分组,用每组的中位数填充fill_col的缺失值"""
df[fill_col] = df.groupby(group_col)[fill_col].transform(
lambda x: x.fillna(x.median())
)
return df
# 假设需要填充‘K2O’列,按‘Glass_Type’(玻璃类型)分组
df = fill_missing_by_group(df, 'Glass_Type', 'K2O')
2.3 特征工程:从原始数据中“创造”价值
原始化学成分数据是直接可用的特征,但好的特征工程能极大提升模型性能。对于C题,我们可以尝试构建以下特征:
- 比率特征 :玻璃的化学稳定性与其成分间的比例密切相关。例如, 碱土金属氧化物与碱性氧化物之比 ((CaO+MgO)/(Na2O+K2O))常被用来衡量玻璃的耐风化能力,比值越高通常越稳定。构建这类基于专业知识的特征,能让模型更容易捕捉到风化背后的化学原理。
- 总和与归一化 :检查所有化学成分百分比之和是否接近100%。如果不接近,可能意味着存在未检测的成分或误差。可以考虑将各成分含量归一化到100%,但这可能会改变原始数据的分布,需根据模型需求决定。
- 类别特征编码 :“玻璃类型”(高钾/铅钡)和“颜色”是重要的类别特征。对于二分类的“玻璃类型”,使用0/1标签编码即可。对于“颜色”,如果种类不多且无序,可以使用独热编码(One-Hot Encoding)。
- 交互特征 :尝试创建一些成分之间的交互项(如乘积),有时能捕捉到非线性的协同效应,但这也可能急剧增加特征维度,需要配合特征选择使用。
特征工程后,别忘了进行 特征缩放 。很多模型(如支持向量机SVM、K近邻KNN、神经网络)对特征的尺度很敏感。将特征标准化(StandardScaler,使均值为0,方差为1)或归一化(MinMaxScaler,缩放到[0,1]区间)是一个好习惯。树模型(如随机森林、XGBoost)虽然不要求,但有时也能加速训练。
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
# 假设数值特征列表为 `numeric_features`,类别特征列表为 `categorical_features`
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(drop='first', sparse_output=False), categorical_features) # drop='first'避免多重共线性
])
# 在训练集上拟合预处理器,并转换训练集和测试集
X_train_processed = preprocessor.fit_transform(X_train)
X_test_processed = preprocessor.transform(X_test)
3. 核心建模思路:分类、关联与预测的三重奏
国赛C题通常要求完成多个子任务,2022年C题就典型地包含了分类、关联规则挖掘和缺失值预测。我们需要为每个任务选择合适的“武器”。
3.1 任务一:风化状态的分类判别
这是最核心的监督学习任务。目标是根据化学成分等特征,预测文物是否风化。我们面临一个二分类问题。
模型选型与对比 : 没有绝对最好的模型,只有最适合数据和问题的模型。在有限的时间内,我建议采用“简单模型快速基线 + 复杂模型调优冲刺”的策略。
- 逻辑回归 :作为第一基线。它简单、可解释性强,能提供特征系数的初步解读(例如,正系数表示该成分含量越高越可能风化)。但它假设特征与对数几率是线性关系,可能无法捕捉复杂模式。
- 支持向量机 :特别是使用径向基函数(RBF)核的SVM,在处理非线性可分问题上能力很强。但它的计算开销较大,且对参数(如惩罚系数C、核函数参数gamma)和特征缩放非常敏感。
- 随机森林 :这是我在实战中最推荐尝试的模型之一。它本身就是集成模型,抗过拟合能力较强,能处理非线性关系,并且能输出特征重要性评分,这对于后续分析“哪些化学成分对风化影响最大”非常有帮助。它通常能提供一个不错的基准性能。
- XGBoost/LightGBM :这类梯度提升树模型是很多数据科学竞赛的“夺冠利器”。它们性能强大,但需要更多的调参技巧,且更容易过拟合小数据集。
- 神经网络 :对于高维数据,简单的多层感知机(MLP)也可以尝试。但在样本量不大的情况下,需要极其小心地设计网络结构(层数、神经元数不宜过多)并应用正则化(如Dropout),否则会严重过拟合。
实操步骤与代码框架 :
from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, classification_report
# 1. 划分特征X和标签y,划分训练集和测试集(或使用交叉验证)
X = df.drop('Weathering_State', axis=1) # 假设‘Weathering_State’是标签列
y = df['Weathering_State']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y) # stratify确保分层抽样
# 2. 数据预处理(接上一节的preprocessor)
X_train_processed = preprocessor.fit_transform(X_train)
X_test_processed = preprocessor.transform(X_test)
# 3. 训练与评估多个模型(以随机森林为例)
models = {
'Logistic Regression': LogisticRegression(max_iter=1000, random_state=42),
'SVM': SVC(random_state=42, probability=True), # probability=True便于后续输出概率
'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42)
}
for name, model in models.items():
model.fit(X_train_processed, y_train)
y_pred = model.predict(X_test_processed)
print(f"--- {name} ---")
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print(f"F1-Score: {f1_score(y_test, y_pred, pos_label='风化'):.4f}") # 假设‘风化’为正类
print(classification_report(y_test, y_pred))
print("\n")
# 4. 特征重要性分析(针对树模型)
rf_model = models['Random Forest']
importances = rf_model.feature_importances_
# 需要获取处理后的特征名称(对于ColumnTransformer稍复杂,此处略)
# 可以将重要性排序后绘图,找出关键化学成分
关键经验 :在样本量不大的情况下, 不要依赖单次train_test_split的结果来评价模型 ,这有很大的随机性。务必使用 K折交叉验证 来获取更稳健的性能估计。
cross_val_score函数可以方便地实现这一点。最终提交的模型,应该是用全部训练数据重新训练后的模型。
3.2 任务二:风化前后化学成分的关联规律
这个任务更偏向于探索性数据分析(EDA)和统计推断,目的是定性地描述风化导致了哪些成分的规律性变化。
思路与方法 :
- 分组统计对比 :这是最直观的方法。分别计算风化组和未风化组在各个化学成分上的 均值、中位数 ,并计算其差值或变化率((风化组均值-未风化组均值)/未风化组均值)。制作一个对比表格,可以清晰地看到哪些成分在风化后显著上升(如二氧化硅可能因其他成分流失而相对富集)、哪些显著下降(如碱金属氧化物Na2O、K2O易被溶出)。
- 假设检验 :为了判断观察到的差异是否具有统计学显著性,而不仅仅是随机波动,可以对每个化学成分进行 独立样本t检验 (若数据符合正态分布)或 曼-惠特尼U检验 (非参数检验)。计算p值,通常以p<0.05作为显著性的标准。这能为你的结论提供更坚实的数理支撑。
- 可视化呈现 :使用 分组小提琴图 或 带误差棒的柱状图 来展示风化与未风化组某个成分的分布差异,比单纯的数字表格更生动有力。
from scipy import stats
# 假设已按风化状态将数据分为两组:df_weathered, df_unweathered
components = ['SiO2', 'Na2O', 'K2O', 'CaO', 'MgO'] # 成分列表
results = []
for comp in components:
stat, p_value = stats.mannwhitneyu(df_weathered[comp].dropna(), df_unweathered[comp].dropna())
mean_diff = df_weathered[comp].mean() - df_unweathered[comp].mean()
results.append({
'Component': comp,
'Mean_Weathered': df_weathered[comp].mean(),
'Mean_Unweathered': df_unweathered[comp].mean(),
'Mean_Difference': mean_diff,
'p_value': p_value,
'Significant': p_value < 0.05
})
results_df = pd.DataFrame(results)
print(results_df)
3.3 任务三:风化点未知成分的预测
这个任务可以看作是一个 回归问题 或 缺失值插补问题 。给定一个风化文物样本,已知其部分成分,预测其缺失的化学成分含量。
核心思路 :
- 构建预测模型 :将待预测的成分作为目标变量(y),将该样本已知的其他成分、玻璃类型、颜色等作为特征(X)。注意,这里 必须使用未风化的样本数据来训练模型 。因为风化的过程已经改变了成分,用风化数据训练出的模型去预测风化前的成分,逻辑上是错误的。我们的目标是预测它风化前的原始成分。
- 模型选择 :由于特征之间可能存在复杂的非线性关系, 随机森林回归 或 梯度提升回归树 是不错的选择。它们能处理非线性,且对异常值相对稳健。也可以尝试 多元线性回归 作为基线,或 K近邻回归 (用最相似的几个未风化样本的成分均值来预测)。
- 分而治之 :如果不同玻璃类型(高钾/铅钡)的成分体系差异巨大,更好的策略是 分别对高钾玻璃和铅钡玻璃建立两个预测模型 。这样模型学到的规律更纯粹,预测精度可能更高。
- 评估 :由于测试样本的真实值未知(赛题要求),我们无法直接评估。但在模型开发阶段,可以从未风化数据中 人工隐藏部分已知数据作为验证集 ,来评估模型的预测误差(如均方误差MSE、平均绝对误差MAE)。
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error
# 假设 `df_unweathered` 是未风化样本数据,我们要预测‘K2O’含量
# 特征X包含其他化学成分和类别特征
X_train_reg = df_unweathered.drop(['K2O', 'Weathering_State'], axis=1) # 假设‘Weathering_State’是标签列
y_train_reg = df_unweathered['K2O']
# 预处理(需要处理X中的类别特征和数值特征)
# ... 预处理代码 ...
# 划分训练集和验证集,用于评估
X_tr, X_val, y_tr, y_val = train_test_split(X_train_processed, y_train_reg, test_size=0.2, random_state=42)
rf_reg = RandomForestRegressor(n_estimators=200, random_state=42)
rf_reg.fit(X_tr, y_tr)
y_pred_val = rf_reg.predict(X_val)
print(f"Validation MAE: {mean_absolute_error(y_val, y_pred_val):.4f}")
print(f"Validation MSE: {mean_squared_error(y_val, y_pred_val):.4f}")
# 训练最终模型用于预测
final_model = RandomForestRegressor(n_estimators=200, random_state=42)
final_model.fit(X_train_processed, y_train_reg)
# 当需要对一个风化样本预测其原始K2O时,使用该模型
4. 模型优化、验证与结果分析
建立一个初步模型只是开始,让模型变得可靠、结果具有说服力,才是数学建模论文获得高分的关键。
4.1 超参数调优:从“能用”到“好用”
以随机森林为例, n_estimators (树的数量)、 max_depth (树的最大深度)、 min_samples_split (内部节点再划分所需最小样本数)等参数都会影响模型性能。盲目使用默认参数通常不是最优解。
网格搜索 是一种系统的调参方法,但计算成本高。在比赛时间有限的情况下,我推荐使用 随机搜索 ,它在更大的参数空间内采样,能以更少的尝试找到不错的参数组合。结合交叉验证来评估参数性能。
from sklearn.model_selection import RandomizedSearchCV
# 定义参数分布
param_dist = {
'n_estimators': [100, 200, 300, 500],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
rf = RandomForestClassifier(random_state=42)
random_search = RandomizedSearchCV(rf, param_distributions=param_dist,
n_iter=50, cv=5, scoring='f1', # 使用F1分数作为评估标准
verbose=1, random_state=42, n_jobs=-1)
random_search.fit(X_train_processed, y_train)
print(f"Best parameters: {random_search.best_params_}")
print(f"Best cross-validation score: {random_search.best_score_:.4f}")
# 用最佳参数重新训练最终模型
best_rf_model = random_search.best_estimator_
4.2 模型验证与稳定性评估
交叉验证 是你的最佳伙伴。它不仅能提供更稳健的性能估计,还能帮助你检测模型是否稳定。如果不同折之间的性能差异很大,说明模型可能对数据的具体划分很敏感,或者数据本身存在一些问题。
学习曲线 是另一个强大的诊断工具。绘制训练集和验证集规模变化时的性能曲线,可以帮助你判断模型是处于 欠拟合 (两者性能都低)还是 过拟合 (训练集性能高,验证集性能低)状态。对于过拟合,可以尝试增加训练数据(在比赛中可能很难)、简化模型(减少树深度、增加正则化)、或进行特征选择。
4.3 结果分析与论文呈现
模型跑出结果后,如何分析和呈现同样重要。
-
分类结果分析 :
- 混淆矩阵 :不仅看准确率,更要看 精确率 和 召回率 。在文物风化判别中,可能更关注“将风化文物误判为未风化”(漏报)和“将未风化文物误判为风化”(误报)各自的风险和代价。如果两类错误代价不同,可以调整分类阈值(默认是0.5)来优化。
- 特征重要性 :从随机森林或XGBoost模型中提取的特征重要性排名,是回答“哪些化学成分对判别风化最重要”的最直接证据。可以将重要性排序绘制成条形图,直观展示。
-
关联规律总结 :
- 将任务二中得到的统计对比表和假设检验结果进行整合。用文字清晰地描述:“风化导致碱性氧化物(Na2O, K2O)含量显著降低(p<0.01),而二氧化硅(SiO2)含量相对富集,变化率为X%。” 同时,可以结合化学知识进行解释,提升论文深度。
-
预测结果的不确定性 :
- 对于任务三的预测,不要只给出一个点估计值。可以尝试利用随机森林的 多棵树预测结果 ,计算其 均值和标准差 ,作为预测值及其不确定性范围。例如:“预测该风化文物原始K2O含量为Y%,其95%置信区间为[Y-1.96 std, Y+1.96 std]。” 这体现了建模的严谨性。
5. 代码实现的模块化与可复现性
在紧张的比赛时间内,写出杂乱无章的代码是灾难。良好的代码结构不仅能让你和队友高效协作,也能让论文评委(如果要求提交代码)看到你们的专业素养。
我建议的代码组织结构 :
2022_国赛C题_代码/
├── data/
│ ├── raw/ # 存放原始赛题数据
│ └── processed/ # 存放清洗处理后的数据
├── src/
│ ├── 01_data_exploration.ipynb # 数据探索与可视化
│ ├── 02_data_preprocessing.py # 数据清洗、缺失值处理、特征工程函数
│ ├── 03_model_training.py # 定义模型训练、评估、调参的流程
│ ├── 04_task1_classification.py # 任务一分类模型主流程
│ ├── 05_task2_association.py # 任务二关联分析
│ ├── 06_task3_prediction.py # 任务三回归预测
│ └── utils.py # 存放公共函数(如评价指标计算、绘图样式)
├── config.yaml # 配置文件,存放文件路径、模型参数等
├── requirements.txt # 项目依赖包列表
└── README.md # 项目说明,包括如何运行代码
关键实践 :
- 使用Jupyter Notebook进行探索 :交互式环境非常适合数据探索和快速原型验证。
- 将成熟流程封装为Python脚本 :确定好的预处理、训练流程应写成
.py文件,便于复用和批处理。 - 固定随机种子 :在代码开头设置
np.random.seed(42)和random.seed(42),确保每次运行结果一致,这对调试和复现至关重要。 - 注释与文档 :关键步骤、复杂的逻辑、自定义函数的目的和参数,都需要清晰的注释。这对自己几天后回顾、对队友理解代码都极其重要。
6. 常见“坑点”与实战心得
回顾整个解题过程,有几个地方特别容易出错或被忽略,这里集中分享一下:
-
数据泄露 :这是最致命的错误之一。例如,在任务三预测风化前成分时, 绝对不能 在预处理(如标准化)时把风化样本和未风化样本混在一起计算均值和方差。必须只用未风化样本的数据来拟合标准化器,然后再用这个标准化器去转换风化样本的数据。任何从“未来”或“测试”数据中获取信息用于处理“过去”或“训练”数据的操作,都是数据泄露,会导致模型评估结果虚高,实际应用时性能骤降。
-
盲目追求复杂模型 :在样本量不大的情况下,复杂的深度学习模型或极度复杂的集成模型很容易过拟合。 随机森林通常是小样本、高维数据下的“安全牌” ,它不容易过拟合,且能给出特征重要性,解释性相对较好。先用一个简单的模型(逻辑回归)和随机森林建立性能基线,再考虑是否要上更复杂的模型。
-
忽略业务背景 :数学建模不是纯数学游戏。例如,在构建特征时,想到“碱土金属与碱金属比例”这个指标,就是结合了玻璃化学知识。在分析结果时,如果能用化学原理解释为什么某些成分在风化后变化,论文会增色不少。评委喜欢看到你不仅会跑模型,还能理解问题本身。
-
评估指标单一 :对于分类问题,不要只盯着准确率。如果数据不平衡(比如未风化样本远多于风化样本),准确率可能会很高,但模型可能根本没学会识别少数的风化样本。 F1分数、精确率、召回率、AUC-ROC曲线 都是更全面的评估工具。要根据任务关注点选择合适的指标。
-
时间管理 :国赛三天时间,第一天必须完成数据理解和大部分预处理工作,并确定核心模型方向。第二天集中攻坚模型实现、调优和任务二、三的分析。第三天用于整合结果、撰写论文和检查。代码要尽早跑通一个完整的流程,哪怕效果一般,这能给你巨大的信心和时间余量去迭代优化。
最后,我想说,数学建模竞赛的魅力在于它模拟了一个完整的解决实际问题的科研流程。从理解问题、处理数据、建立模型、分析结果到撰写报告,每一个环节都考验着综合能力。2022年C题是一个非常好的案例,它涵盖了数据科学中的典型任务。通过这样的实战训练,你收获的绝不仅仅是一个奖项,更是一套应对复杂数据问题的思维方法和工具技能。希望这篇结合了思路与代码实现的复盘,能为你未来的竞赛或项目提供一份扎实的参考。在具体编码时,多查文档,多动手试错,遇到报错别慌,那通常是你理解更深一步的契机。
更多推荐
所有评论(0)