#文末有福利#
还记得去年燃爆全国的
「新网银行高校金融科技挑战赛」吗?
可以上下滚动的图片
堪比大型撒钱现场的 2019 新网银行高校金融科技挑战赛在初赛阶段就吸引了来自北大、清华、复旦、武大、电子科大、华科、斯坦福、康奈尔大学等 208 所高等学府的 1632 名极客加入挑战。
突出重围闯入决赛的 20 支团队现场瓜分了 47 万现金大奖,所有到场选手都获得了新网银行提供的 20W+/30W+ 的高薪录用 OFFER(OFFER 有效期直至选手毕业)
点击此处回顾 2019 新网银行高校金融科技挑战赛盛况。
今年的比赛已经战火重燃!47 万总奖金、30 万 + 高薪 OFFER!提前进入「就业保险箱」;还有最高 30 万就业助力金、省级权威证书...
想参加但害怕没有经验没有思路?
今年的一位参赛选手,已经为大家提供了一个解题思路,看完赛题之后记得继续往下看,非常具有参考价值( ♥д♥)~
今年的赛题和去年有所不同
分别是
「AI 算法赛道」 和 「移动互联赛道」
不同的赛道角逐,相同的激烈竞赛
下面,我们和大家一起
解析本次的赛题
赛题解析
AI 算法赛道主题:“看见你的呼吸”
观看下方漫画短片,走进由「AI 算法」加持的生活
▼
如果你对算法和技术充满热爱,并有意在未来 IoT 领域创造属于自己的天地,这道赛题就给了你一个小试身手的机会。
本赛题要求参赛者利用手机陀螺仪、加速传感器等等数据,用算法做行为的多分类预测,比如预测手的行为或者预测身体的行动。
为了帮助参赛选手更好地答题,本赛道特别开设了「新手训练营」,点击文章底部阅读原文,进入赛题页面即可报名参加。
赛题解析
移动互联赛道主题:“朱望仔大战大反派”
观看下方漫画短片,做一款你自己的游戏
▼
如果你喜欢游戏!何不自己研发制作游戏!
本赛道提供了简单的弹珠类游戏 DEMO,以“朱望仔大战大反派”为主题,根据新网银行提供的动画设计原稿,结合发散你的思维,启动你的创意,来开发一款游戏吧!
从开发到运营,这道赛题考验的是一个团队的综合实力~
游戏形式可参考主办方提供的游戏 DEMO,你可以从 0 开始开发一款弹珠类游戏,也可以在游戏 DEMO 的基础上做二次开发。
游戏的具体玩法可由选手在大赛主题的基础上自由定义,我们将重点考察:游戏前端体验是否流畅、接口响应效率、服务稳定性以及内容是否完善、是否有创意,玩法体验是否有可玩性,初赛阶段总共获取多少粉丝等。
游戏 DEMO
▼
纯 CNN Baseline(线上0.711)
大家好,我是来自 OTTO Data Lab的 Chauncy。
我个人关注这比赛有接近一个星期了,却只发现了一个基于 LightGBM 的 Baseline。但这题显然更适合用 NN 做呀,前排大佬应该大部分都是用 NN 的吧?难道都藏着给自己上分了不愿意分享?
那我可憋不住了,我就抛砖引玉,提供一个简化版的 CNN 给大家参考,在本文末尾也有几点 Tips。
话不多说,咱们直接进入正题,希望对大家有所帮助。
我这个 baseline 是基于 tensorflow.keras 的,首先来 import 一些我们将要用到的东西:
import numpy as np
import pandas as pd
from tqdm import tqdm
from scipy.signal import resample
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import StratifiedKFold
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
第一部分 · 数据准备
这里我们读入三个 csv 文件,分别是训练集(train)、线上测试集(test)和提交样例(sub)。把训练集读入进来之后就可以把标签(y)先分离出来了:
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
sub = pd.read_csv('submit.csv')
y = train.groupby('fragment_id')['behavior_id'].min()
接下来就要简单处理一下这些数据,我这里就不做 EDA 了,假设大家都已经知道了这批数据是怎样的。原始数据只给了加速度的分量,但我觉得合成后的合量可能有帮助,所以我添加了不带重力的加速度的模长和带重力的加速度的模长:
train['mod'] = (train.acc_x ** 2 + train.acc_y ** 2 + train.acc_z ** 2) ** .5
train['modg'] = (train.acc_xg ** 2 + train.acc_yg ** 2 + train.acc_zg ** 2) ** .5
test['mod'] = (test.acc_x ** 2 + test.acc_y ** 2 + test.acc_z ** 2) ** .5
test['modg'] = (test.acc_xg ** 2 + test.acc_yg ** 2 + test.acc_zg ** 2) ** .5
你也可以对这几个序列再做别的特征,因为这只是个 Baseline 我就不做展示了。事实上,我自己线上的模型也没有再对这些序列做其他的构造。
然后注意到原始数据中每个片段的长度也是不一致的,虽然时长都是 5 秒,但最少有 49 个采样点,最多则有 61 个。而常规的 CNN 在输入层,每个样本的形状应该是一致的。所以我对它们进行了重采样,统一到 60 个采样点:
x = np.zeros((7292, 60, 8, 1))
t = np.zeros((7500, 60, 8, 1))
for i in tqdm(range(7292)):
tmp = train[train.fragment_id == i][:60]
x[i,:,:, 0] = resample(tmp.drop(['fragment_id', 'time_point', 'behavior_id'],
axis=1), 60, np.array(tmp.time_point))[0]
for i in tqdm(range(7500)):
tmp = test[test.fragment_id == i][:60]
t[i,:,:, 0] = resample(tmp.drop(['fragment_id', 'time_point'],
axis=1), 60, np.array(tmp.time_point))[0]
第二部分 · 模型训练
这里我提供一个非常简单的 CNN 网络,真的是只花了 10 分钟随手搭的。你如果直接用这个网络,想摸奖肯定是不可能的(线上 0.711),但它是有上升的潜力的。所以仅供参考:
def Net():
input = Input(shape=(60, 8, 1))
X = Conv2D(filters=64,
kernel_size=(3, 3),
activation='relu',
padding='same')(input)
X = Conv2D(filters=128,
kernel_size=(3, 3),
activation='relu',
padding='same')(X)
X = MaxPooling2D()(X)
X = Conv2D(filters=256,
kernel_size=(3, 3),
activation='relu',
padding='same')(X)
X = Conv2D(filters=512,
kernel_size=(3, 3),
activation='relu',
padding='same')(X)
X = GlobalMaxPooling2D()(X)
X = Dropout(0.3)(X)
X = Dense(19, activation='softmax')(X)
return Model([input], X)
交叉验证作为一种减少偏差和过拟合的方法,在比赛中非常常用。这里我采用 5 折交叉,你可以把 5 改成其它数字。StratifiedKFold 是采用分层抽样的 KFold,保证每一折中不同类别的样本比例相等。在大部分分类任务下,效果都比 KFold 好:
kfold = StratifiedKFold(5, shuffle=True)
接下来就要对每一折进行训练,并在训练过程中把最好的模型权重保存下来。在每一折训练完成后,再加载最好的模型权重在线上测试集上推理。我这里取的是平均值,也就是每一折的权重都是一样的:
proba_t = np.zeros((7500, 19))
for fold, (xx, yy) in enumerate(kfold.split(x, y)):
y_ = to_categorical(y, num_classes=19)
model = Net()
model.compile(loss='categorical_crossentropy',
optimizer=Adam(),
metrics=['acc'])
plateau = ReduceLROnPlateau(monitor="val_acc",
verbose=0,
mode='max',
factor=0.1,
patience=6)
early_stopping = EarlyStopping(monitor='val_acc',
verbose=0,
mode='max',
patience=10)
checkpoint = ModelCheckpoint(f'fold{fold}.h5',
monitor='val_acc',
verbose=0,
mode='max',
save_best_only=True)
model.fit(x[xx], y_[xx],
epochs=100,
batch_size=512,
verbose=1,
shuffle=True,
validation_data=(x[yy], y_[yy]),
callbacks=[plateau, early_stopping, checkpoint])
model.load_weights(f'fold{fold}.h5')
proba_t += model.predict(t, verbose=0, batch_size=1024) / 5.
上面这段代码中,checkpoint就是保存最优模型的回调,如果不在每遇到一个验证集准确率新高的时候就保存一下,可能到下一个epoch就过拟合了。因为Adam默认0.001的学习率,到后期还是太大了,需要用更小的学习率。手动设置又太不方便,而且很考验经验。
plateau就是用来检测在训练过程中如果一段时间内验证集准确率都没有提升,则自动调低学习率,使训练过程能够继续进行。stopping是用来检测当验证集准确率长时间没有再提升后,提前停止训练,尽量减少训练时间。最后只要把结果保存到文件就可以提交了:
sub.behavior_id = np.argmax(proba_t, axis=1)
sub.to_csv('submit.csv', index=False)
提交这个submit.csv就能在线上获得0.711左右的分数。也许你已经注意到我的代码没有设置随机数种子,所以分数在这附近波动这是正常的。如果需要准确复现,你得自己设定随机数种子。
第三部分 · 几点Tips
1. 这题小模型更合适,我自己的模型也不到 60MB,大了过拟合非常严重;
2. 网络结构和参数很重要,此 Baseline 没有任何数据增强,也能拿到 0.711;
3. 要多尝试各种网络结构,不只限于纯 CNN,还可以借鉴许多轨迹分类任务。
快上车!在金融科技领域乘风破浪!
看完赛题和解题思路分享
是不是觉得奖金已经拿到手了?
你离成为金融科技界的弄潮儿
只差报名参加
2020 “创青春·交子杯” 新网银行金融科技挑战赛
与各位极客们一起
瓜分 47 万奖金!
赢取 30 万+高薪OFFER!
还有最高 30 万就业助力金,省级权威证书
等你来拿!
如果想了解更多
7 月 8 日 晚 7:00,进入
「新网银行抖音直播间」或「思否社区直播间」
聆听「新网银行公开课」
带你深度了解赛题背后的意义及前景
关于大赛的任何疑问
你也可以加入本次大赛QQ群讨论咨询~
点击“阅读原文”,报名参赛,迎战吧!