设为首页添加收藏

您好! 欢迎来到广东某某建材科技有限公司

微博
扫码关注官方微博
微信
扫码关注官方微信
电话:400-123-4567

您的位置: 主页 > 杏鑫资讯 > 公司新闻
公司新闻

数学建模竞赛常用算法-数据挖掘、分类预测与优化算法

发布日期:2024-08-26 来源: 网络 阅读量(

一系列数学建模竞赛中,常见的问题设定与模型要求有:

  1. 给定一系列数据,要求进行数据降维(挑选重要数据)、数据预处理、数据特征分析、特征选择等;
  2. 给定一系列数据,要求根据数据训练模型,根据输入x做出预测/分类,输出结果y;
  3. 在给定的范围内搜寻最优解或者最优范围/集合。

以上三种情况,正好是2021年华为杯研究生数学建模竞赛D题考察的全部内容。也是建模竞赛中最常见的问题设定,在本篇文章中会针对性的给出建模建议并分享相关的python代码经验。以下都是我个人的经验,有错误与缺失的地方,欢迎交流指正。

在建模之前,建议根据具体题目对数据进行异常值处理(包括漂移的数据点、缺失值补全)。注意,这一步是非常重要的,很多题目会在数据里埋坑,如果没有考虑到异常数据的影响,往往对于后续的分析与建模有重大影响。对于异常值的检测,常用的方法有基础的统计分析、可视化分析、分布检验;对于检测出的异常值,常用的处理方法有直接删除、根据前后数据进行平滑修正、补充为0等。接下来还可以进行一些常规的数据特征分析,比如均值、方差、最大值最小值、不同列数据的共线性分析等。

很多时候题目会给出维度丰富的数据,但其中往往很多列数据是无效/不重要的,这个时候往往题目会要求筛选出前n个重要的数据维度,用于进一步的建模等。这时候就需要进行特征选择。注意这里是在原始数据的基础上,选择最重要的n列原始数据。最常见的特征选择思路是,先剔除方差为0的列数据、对不同的列之间进行相关性检验,确保不会选择出两个蕴含相同信息的列(此处可以画一些热力图来说明选取的列之间的共线性情况,推荐使用seaborn的heatmap函数):

主要变量之间的相关度分布图

之后,可以把所有挑选过的原始数据,进行归一化数据预处理后,放进经典的机器学习模型中进行训练,根据训练后的模型反向输出每一列数据的重要性指标。这里推荐用sklearn库中的经典模型,方便训练后输出feature_importance数据。此外,有余力的同学可以用神经网络模型,根据网络输入层的weight,来判断每一列数据的重要性。

此外,还有一个与特征选择概念相近但又不能等同的任务:数据降维。数据降维更多时候指的是,对于维度丰富的数据,直接把它压缩成n维数据,这里的n维数据就不再是原始数据了。常用的数据降维算法有PCA等。

分类任务指的是模型根据输入的样本特征x,预测样本对应的类别y(这里的y是一个离散值,比如0,1,2);

回归任务指的是模型根据输入的样本特征x,预测样本对应的分数y(这里的y是一个连续值,比如0.1,0.2)。

分类回归任务,在建模比赛中很多时候用sklearn中的经典模型,比如线性的逻辑回归、非线性的SVM / XGBoost / RandomForest / KNN等就足够了,代码上来看非常简洁。如果对于模型性能有较高要求并且有比较专业的队员,可以自行用pytorch或者TensorFlow搭建一个高性能模型并引入一系列trick/进行调参。下面贴一段相关代码仅供模型选择参考:

###########3.具体方法选择##########
####3.1 决策树回归####
from sklearn import tree
model_DecisionTreeRegressor=tree.DecisionTreeRegressor()
####3.2 线性回归####
from sklearn import linear_model
model_LinearRegression=linear_model.LinearRegression()
####3.3SVM 回归####
from sklearn import svm
model_SVR=svm.SVR()
####3.4KNN 回归####
from sklearn import neighbors
model_KNeighborsRegressor=neighbors.KNeighborsRegressor()
####3.5 随机森林回归####
from sklearn import ensemble
model_RandomForestRegressor=ensemble.RandomForestRegressor(n_estimators=500)#
这里使用 20 个决策树
####3.6Adaboost 回归####
from sklearn import ensemble
model_AdaBoostRegressor=ensemble.AdaBoostRegressor(n_estimators=500)
#这里使用 50 个决策树
####3.7GBRT 回归####
from sklearn import ensemble
model_GradientBoostingRegressor=ensemble.GradientBoostingRegressor(n_estimators=50
0)
#这里使用 100 个决策树
####3.8Bagging 回归####
from sklearn.ensemble import BaggingRegressor
model_BaggingRegressor=BaggingRegressor()
####3.9ExtraTree 极端随机树回归####
from sklearn.tree import ExtraTreeRegressor
model_ExtraTreeRegressor=ExtraTreeRegressor()

数学建模中常见的优化算法有:遗传算法、模拟退火算法、蚁群算法、粒子群算法等。笔者本人比较喜欢用遗传算法,Python中有一个宝藏优化算法库在这里强推一波(创作者本人也在知乎有号 @幼鹰me):

Python优化算法库

使用这个库可以方便快速地实现遗传算法(GA)、粒子群算法(PSO)、蚁群算法(ACA)、模拟退火算法(SA)、免疫优化算法(IA)、人工鱼群算法(AFSA),并且针对经典的TSP问题等有更方便的使用方法,官方文档撰写也很详细。在笔者本人的建模竞赛经历中,经常使用这个库。简单的安装方法就是:

pip install scikit-opt

基于以上传统优化算法,可以根据具体问题设定带约束的优化算法求解。比如2021年华为杯的D题最后一问,优化目标有两个,则在定义优化算法目标函数时,加入一个惩罚项即可:

# 定义遗传算法优化函数
def schaffer(p):
  p = p.reshape(1, -1)
  # ADMET 约束
  admet = int(cla_model1.predict(p)[0]==1) + int(cla_model2.predict(p)[0]==1) + 
  int(cla_model3.predict(p)[0]==0) + \\
  int(cla_model4.predict(p)[0]==1) + int(cla_model5.predict(p)[0]==0)
  # ERA 活性值
  era = reg_model.predict(p)[0]
  # 综合优化目标:ERA + ADMET 约束
  res = -era + int(admet<3)*1e5
  return res
# 遗传算法实现
low_bound = data.min(axis=0)
high_bound = data.max(axis=0)
ga = GA(func=schaffer, n_dim=20, size_pop=50, max_iter=600, prob_mut=0.001, 
lb=low_bound, ub=high_bound, precision=1e-7)
best_x, best_y = ga.run()
Y_history = pd.DataFrame(ga.all_history_Y)
# 绘图。红点代表每一个 iteration 中种群里每一个个体的 y 值。
# 100000 的值都是不满足 admet 至少三个为优的性质。直接忽略。
# 蓝色曲线为 ERA 活性值,越高越好。
fig, ax = plt.subplots(2, 1)
ax[0].plot(Y_history.index, Y_history.values, '.', color='red')
# Y_history.min(axis=1).cummin().plot(kind='line')
abs(Y_history.min(axis=1)).plot(kind='line')
plt.show()

最终绘制的优化图如下,效果是非常好的:

平台注册入口