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

本届腾讯算法大赛赛况激烈,大神云集。高手们在同台过招之余,也会借此机会进行技术交流和赛题探讨。今天我们就邀请到竞赛高分选手chizhu来分享参赛心得,希望这份独家“经验指南”会带给赛程中的你一些新思考。
大家好,我是林智敏。长期混迹竞赛圈,chizhu是我的赛圈id,我也曾获得Kaggle Master头衔。本次比赛单模成绩为1.4516,暂时排名第七。以下就是我今天要跟大家分享的解题思路。
1.解题思路
本届腾讯广告算法大赛的题目是用户画像,根据用户点击广告的序列预测用户的年龄和性别。这个题目对于我而言再熟悉不过了,因为之前的易观赛和华为赛也是预测年龄和性别。我们团队有幸在这两个比赛都取得第一名的好成绩。针对此类型的赛题,我们团队磨合出了一种思路,即先把id看成一个词,然后把id拼接起来连成一个句子,于是我们的任务就变成了一个脱敏场景下的文本分类问题。在此附上上述比赛解决方案,供选手们参考:


易观:
https://github.com/chizhu/yiguan_sex_age_predict_1st_solution


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


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


2.模型建立&后处理
模型结构
目前我的模型结构是:5输入+transformer(一层)+LSTM
why not bert here ?我们知道bert在NLP届的霸主地位不可动摇,但因本次赛题的特殊性,最强的creative_id的词表共有300w+个,从头预训练一个bert的成本是非常高的。而且经过我的尝试,效果也不尽如人意。我也尝试了直接初始化一个4头注意力,128维的6层bert,最高只能到1.30。
模型详情
emb层词表实在过多,这里直接冻结不做更新。然后直接输入transformer(一层),这里需要用到click_time序列来做加权mask (把clisk_time当成attention_mask输入)。
transformer各个子模块都是有现成的,可以直接调用(这里要为huggingface团队打call):

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


后面再接一层LSTM,并做最大池化(只需要最大池化)。我也对均值池化进行了测试,结果显示attention加权求和都不上分。
最后简单的分出两条分支,直接双任务训练即可。
定义双loss求和:

```python
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使用,排列组合,搭积木,搭出一片天。
后处理
对于acc/F1这类与阈值有关的指标其实可以针对类别设置不同权重。从output=argmax(preds)变成output=argmax(preds*weights)。
附上权重搜索的代码:

```PYTHON
####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上的解法,很期待看到大佬们不一样的见解。
最后,祝大家取得满意的成绩。

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

搜索群号:1094257162,加入大赛官方QQ群,和小伙伴一起解锁更多内容。

你可能感兴趣的:(2020腾讯广告算法大赛)