赞
踩
一直都想参加一次阿里天池比赛,看到有公众号提了这次比赛的baseline,果断报名。0基础,开始了第一次数据科学比赛的尝试~
这次比赛遇到了各种各样的问题,几度想放弃,但是不忍心排200多名。来都来了,冲完B榜吧,也算是表明自己第一次参加天池大赛的态度,不能让母校的名字排在最后。
https://tianchi.aliyun.com/competition/entrance/531871/introduction
发生在热带太平洋上的厄尔尼诺-南方涛动(ENSO)现象是地球上最强、最显著的年际气候信号。通过大气或海洋遥相关过程,经常会引发洪涝、干旱、高温、雪灾等极端事件,对全球的天气、气候以及粮食产量具有重要的影响。准确预测ENSO,是提高东亚和全球气候预测水平和防灾减灾的关键。
本次赛题是一个时间序列预测问题。基于历史气候观测和模式模拟数据,利用T时刻过去12个月(包含T时刻)的时空序列(气象因子),构建预测ENSO的深度学习模型,预测未来1-24个月的Nino3.4指数,如下图所示:
这题是一个典型的时间序列预测问题,看起来没那么难,但是认真一想还是有很多难点的,比如数据质量,内存限制,模型,都是可以改进的,下面是我的baseline。
拿到数据,我都是一股脑往模型里扔,然后开始炼丹,炼着炼着,分数从-6变为-10、-13、-15、-22…最后都到NaN了,平时老师也总是说,不要一上来就上模型,先把数据分析清楚了,于是打算再花几个小时进行数据分析。
CMIP是模拟数据,网友UCDuan说:
CMIP是气候模型的数据
你可以理解为不同情况下(不同的初始场和不同的气候模型)“地球”的真实情况,只是符合大致的‘物理规律’,但不是地球真实的历史情况。所以用CMIP就是想挖掘这个‘物理规律’。
这里我打算拿CMIP数据训练,SODA数据验证。
以sst数据为例
可以看出数据是经过处理的,每隔12个月,连续三组数据值是一样的
再加上下个特征,发现他们也是相似的
另外有些特征数据缺失,需要进行平均填充
方法如下:
tr_features2 = np.concatenate([sst_CMIP_shaped,t300_CMIP_shaped,va_CMIP_shaped,ua_CMIP_shaped],axis=-1)
tr_features2[np.isnan(tr_features2)] = np.mean(tr_features2)#对NaN值进行均值填充
baseline来自这篇文章:https://mp.weixin.qq.com/s/63LPCHNo4zOA_UGDAc2xUQ
这篇文章完成了数据组织、处理、MLP模型构建、本地测试、上传代码,但是有很多问题,我进行了初步修正:
代码链接:https://github.com/guhang987/-AI-Earth-
代码解释:
conda环境:
首先进行数据格式转换,提取数据前24个月,以及标签后12个月的数据。
soda_label = pd.read_csv('./ENSO/data/df_SODA_label.csv')['label']
sst_SODA = pd.read_csv('./ENSO/data/df_sst_SODA.csv')
t300_SODA = pd.read_csv('./ENSO/data/df_t300_SODA.csv')
ua_SODA = pd.read_csv('./ENSO/data/df_ua_SODA.csv')
va_SODA = pd.read_csv('./ENSO/data/df_va_SODA.csv')
sst_SODA = np.array(sst_SODA).reshape(100,36,24,72,1)[:,:12,:,:,:]
t300_SODA = np.array(t300_SODA).reshape(100,36,24,72,1)[:,:12,:,:,:]
va_SODA = np.array(va_SODA).reshape(100,36,24,72,1)[:,:12,:,:,:]
ua_SODA = np.array(ua_SODA).reshape(100,36,24,72,1)[:,:12,:,:,:]
然后利用concat方法拼接这4个维度:
tr_features = np.concatenate([sst_SODA,t300_SODA,va_SODA,ua_SODA],axis=-1)
tr_features.shape
### 训练标签,取后24个
tr_labels = np.array(soda_label).reshape(-1,36)[:,12:]
tr_labels.shape
得到(100, 12, 24, 72, 4)
的数据以及(100, 24)
的标签。按8:2分割训练集与验证集。
下一步构建CNN模型:
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) (None, 12, 24, 72, 4) 0 _________________________________________________________________ conv3d (Conv3D) (None, 9, 9, 32, 64) 671808 _________________________________________________________________ max_pooling3d (MaxPooling3D) (None, 4, 4, 16, 64) 0 _________________________________________________________________ conv3d_1 (Conv3D) (None, 1, 1, 1, 128) 2097280 _________________________________________________________________ flatten (Flatten) (None, 128) 0 _________________________________________________________________ dense (Dense) (None, 64) 8256 _________________________________________________________________ dropout (Dropout) (None, 64) 0 _________________________________________________________________ dense_1 (Dense) (None, 32) 2080 _________________________________________________________________ dropout_1 (Dropout) (None, 32) 0 _________________________________________________________________ dense_2 (Dense) (None, 24) 792 ================================================================= Total params: 2,780,216 Trainable params: 2,780,216 Non-trainable params: 0
相关训练参数:
history = model_cnn.fit(tr_fea,tr_label,
validation_data=(val_fea, val_label),
batch_size=4096, epochs=2000,
callbacks=[plateau, checkpoint, early_stopping],
verbose=1)
之前是拼接SODA和CMIP数据(2000年),后来拼接SODA和CMIP数据(4368年)发现内存爆了,怎么改都不行。于是尝试多次model.fit方法分别输入SODA CMIP数据,中间用del 和gc.collect
来释放内存。
#增量学习 for round_ in range(4): step=1000 leng = step*36 inde = list(range(step*round_*36+1)) if(round_==4): leng = 600*36 gc.collect() sst_CMIP = pd.read_csv('./ENSO/data/df_sst_CMIP.csv',header=None,skiprows=inde,nrows = leng) t300_CMIP = pd.read_csv('./ENSO/data/df_t300_CMIP.csv',header=None,skiprows=inde,nrows = leng) ua_CMIP = pd.read_csv('./ENSO/data/df_ua_CMIP.csv',header=None,skiprows=inde,nrows = leng) va_CMIP = pd.read_csv('./ENSO/data/df_va_CMIP.csv',header=None,skiprows=inde,nrows = leng) cmip_label = pd.read_csv('./ENSO/data/df_CMIP_label.csv',header=None,skiprows=inde,nrows = leng)[1] sst_CMIP.drop(sst_CMIP.columns[0],axis=1,inplace=True) t300_CMIP.drop(t300_CMIP.columns[0],axis=1,inplace=True) va_CMIP.drop(va_CMIP.columns[0],axis=1,inplace=True) ua_CMIP.drop(ua_CMIP.columns[0],axis=1,inplace=True) sst_CMIP_shaped = np.array(sst_CMIP).reshape(-1,36,24,72,1)[:,:12,:,:,:] t300_CMIP_shaped = np.array(t300_CMIP).reshape(-1,36,24,72,1)[:,:12,:,:,:] va_CMIP_shaped = np.array(va_CMIP).reshape(-1,36,24,72,1)[:,:12,:,:,:] ua_CMIP_shaped = np.array(ua_CMIP).reshape(-1,36,24,72,1)[:,:12,:,:,:] del va_CMIP del t300_CMIP del ua_CMIP del sst_CMIP gc.collect() tr_features2 = np.concatenate([sst_CMIP_shaped,t300_CMIP_shaped,va_CMIP_shaped,ua_CMIP_shaped],axis=-1) tr_features2[np.isnan(tr_features2)] = np.mean(tr_features2)#对NaN值进行均值填充 del va_CMIP_shaped del t300_CMIP_shaped del ua_CMIP_shaped del sst_CMIP_shaped gc.collect() tr_labels2 = np.array(cmip_label).reshape(-1,36)[:,12:] model_cnn = build_model() if round_ != 0: #加载上一轮模型 model_cnn.load_weights('./model/model-%d.h5'%(round_-1)) #存储本轮模型 model_weights = "./model/model-%d.h5"%round_ #保存最佳模型 checkpoint = ModelCheckpoint(model_weights, monitor='val_loss', verbose=0, save_best_only=True, mode='min', save_weights_only=True) plateau = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, verbose=1, min_delta=1e-4, mode='min') early_stopping = EarlyStopping(monitor="val_loss", patience=20) model_cnn.fit(tr_features2,tr_labels2, validation_data=(val_f,val_l), batch_size=32, epochs=20000, callbacks=[plateau, checkpoint, early_stopping], verbose=2) prediction = model_cnn.predict(tr_features) #from sklearn.metrics import mean_squared_error sc = score(y_true = tr_labels, y_preds = prediction) print("%d轮完成,分数%f"%(round_,sc)) #3轮完成,分数-17.867135
总的来说,数据处理目前有三种思路:
模型的话,也可以用RNN来做,只不过提供的数据已经组织好了,用CNN就直接可以输入。于是我就拿了一个玩具CNN来做,可惜对CNN没啥理解,参数都是自己调的,不知道哪些超参最好,希望以后能搞明白。
我始终没搞清楚什么是气象中的模拟数据、真实历史数据,以上三种方法都尝试过,可惜各种奇怪的bug和每天几次的提交机会,让我无法验证
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。