【王牌选手分享】一发问鼎!鹅厂大神上分思路,助你玩转初赛!

本届腾讯算法大赛赛况激烈,大神云集。高手们在同台过招之余,也会借此机会进行技术交流和赛题探讨。今天我们就邀请到竞赛高分选手chizhu来分享参赛心得,希望这份独家“经验指南”会带给赛程中的你一些新思考。

大家好,我是林智敏。长期混迹竞赛圈,chizhu是我的赛圈id,我也曾获得Kaggle Master头衔。本次比赛单模成绩为1.4516,暂时排名第七。以下就是我今天要跟大家分享的解题思路。

01

解题思路

本届腾讯广告算法大赛的题目是用户画像,根据用户点击广告的序列预测用户的年龄和性别。这个题目对于我而言再熟悉不过了,因为之前的易观赛和华为赛也是预测年龄和性别。我们团队有幸在这两个比赛都取得第一名的好成绩。针对此类型的赛题,我们团队磨合出了一种思路,即先把id看成一个词,然后把id拼接起来连成一个句子,于是我们的任务就变成了一个脱敏场景下的文本分类问题。在此附上上述比赛解决方案,供选手们参考:

易观:

https://github.com/chizhu/yiguan_sex_age_predict_1st_solution

华为:

https://github.com/luoda888/HUAWEI-DIGIX-AgeGroup

回到正题,既然是文本分类,不可或缺的自然是文本表示——词向量。最常见的自然是word2vec,这里分享下个人的小经验:在数据量大的情况下采用skip-gram效果会好些,本次题目还有个重要参数window,细调可能有意外发现哦。

02

模型建立&后处理

(1)

模型结构

目前我的模型结构是:5输入+transformer(一层)+LSTM。

why not bert here ?我们知道bert在NLP届的霸主地位不可动摇,但因本次赛题的特殊性,最强的creative_id的词表共有300w+个,从头预训练一个bert的成本是非常高的。而且经过我的尝试,效果也不尽如人意。我也尝试了直接初始化一个4头注意力,128维的6层bert,最高只能到1.30。

(2)

模型详情

emb层词表实在过多,这里直接冻结不做更新。然后直接输入transformer(一层),这里需要用到click_time序列来做加权mask (把clisk_time当成attention_mask输入)。

transformer各个子模块都是有现成的,可以直接调用(这里要为huggingface团队打call):


from transformers.modeling_bert import BertConfig, BertEncoder, BertAttention,BertSelfAttention,BertLayer,BertPooler

后面再接一层LSTM,并做最大池化(只需要最大池化)。我也对均值池化进行了测试,结果显示attention加权求和都不上分。

最后简单的分出两条分支,直接双任务训练即可。

定义双loss求和:


def custom_loss(data1, targets1,data2, targets2):

    ''' Define custom loss function '''

    loss1 = nn.CrossEntropyLoss()(data1,targets1)

    loss2 = nn.CrossEntropyLoss()(data2,targets2)

    return loss1*0.5+loss2*0.5

可以调节权重,看偏向哪个子任务。

还可以尝试啥?三大特征抽取器:transformer/LSTM/CNN。

后续可以尝试CNN,组合LSTM使用,排列组合,搭积木,搭出一片天。

(3)

后处理

对于acc/F1这类与阈值有关的指标其实可以针对类别设置不同权重。从output=argmax(preds)变成output=argmax(preds*weights)。

附上权重搜索的代码:


####opt

class_num=10

weights = [1.0]*class_num

def search_weight(valid_y, raw_prob, init_weight=[1.0]*class_num, step=0.001):

    weight = init_weight.copy()

    f_best = accuracy_score(y_true=valid_y, y_pred=raw_prob.argmax(

        axis=1))

    flag_score = 0

    round_num = 1

    while(flag_score != f_best):

        print("round: ", round_num)

        round_num += 1

        flag_score = f_best

        for c in range(class_num):

            for n_w in range(0, 2000,10):

                num = n_w * step

                new_weight = weight.copy()

                new_weight[c] = num

                prob_df = raw_prob.copy()

                prob_df = prob_df * np.array(new_weight)

                f = accuracy_score(y_true=valid_y, y_pred=prob_df.argmax(

                    axis=1))

                if f > f_best:

                    weight = new_weight.copy()

                    f_best = f

                    print(f)

    return weight

今年我做了认真准备,来参加腾讯广告算法大赛,希望能在这个平台突破自我,取得佳绩!参赛后,我在每天工作之余,改改结构参数挂着跑,还是非常舒服的。我目前的思路还是只有NLP上的解法,很期待看到大佬们不一样的见解。

最后,祝大家取得满意的成绩。

每一次的切磋都是一次学习的机会,在互相竞技的过程中,既充满各式各样的挑战,也有新思路的启发。希望各位竞赛人能在腾讯算法大赛的平台上磨练技艺,不断进步,收获满满!

点击如下链接,查看赛况

2020腾讯广告算法大赛

扫码加入大赛官方QQ群

或搜索群号:1094257162

和小伙伴一起解锁更多内容
【王牌选手分享】一发问鼎!鹅厂大神上分思路,助你玩转初赛!_第1张图片

你可能感兴趣的:(【王牌选手分享】一发问鼎!鹅厂大神上分思路,助你玩转初赛!)