Coggle 30 Days of ML【打卡】广告-信息流跨域ctr预估

Coggle 30 Days of ML【打卡】广告-信息流跨域ctr预估

任务介绍

赛题介绍

广告推荐主要基于用户对广告的历史曝光、点击等行为进行建模,如果只是使用广告域数据,用户行为数据稀疏,行为类型相对单一。而引入同一媒体的跨域数据,可以获得同一广告用户在其他域的行为数据,深度挖掘用户兴趣,丰富用户行为特征。引入其他媒体的广告用户行为数据,也能丰富用户和广告特征。

本赛题希望选手基于广告日志数据,用户基本信息和跨域数据优化广告ctr预估准确率。目标域为广告域,源域为信息流推荐域,通过获取用户在信息流域中曝光、点击信息流等行为数据,进行用户兴趣建模,帮助广告域CTR的精准预估。
在这里插入图片描述

比赛报名方法:https://shimo.im/docs/G9fZLTn1lbccQhkQ/read

比赛地址:https://developer.huawei.com/consumer/cn/activity/starAI2022/algo/competition.html#/preliminary/info/006/rank

数据说明

提供的数据包括目标域用户行为数据,源域用户行为数据, 以下按照这2个维度分别 说明。

  • 目标域用户行为数据
序号字段名称字段含义是 否 可 为空字段类 型取值样例
1label是否点击, 0:否, 1:是int0,1
2user_id用户 idString1,2…
3age年龄String1,2,3…
4gender性别String1,2…
5residence常住地-省份String1,2…
6city常住地-市-编号String1,2…
7city_rank常住地-市-等级String1,2…
8series_dev设备系列String1,2…
9series_group设备系列分组String1,2…
10emui_devemui 版本号String1,2…
11device_name用户使用的手机机型String1,2…
12device_size用户使用手机的尺寸String1,2…
13net_type行为发生的网络状态String1,2…
14task_id广告任务唯一标识String1,2…
15adv_id广告任务对应的素材 idString1,2…
16creat_type_cd素材的创意类型 idString1,2…
17adv_prim_id广告任务对应的广告主 idString1,2…
18inter_type_cd广告任务对应的素材的交 互类型String1,2…
19slot_id广告位 idString1,2…
20site_id媒体 idString1,2…
21spread_app_id投放广告任务对应的应用 idString1,2…
22Tags广告任务对应的应用的标 签String1,2…
23app_second_class广告任务对应的应用的二 级分类String1,2…
24app_scoreapp 得分Int4
25ad_click_list_00 1用户点击广告任务 id 列表[string,][1^2…]
26ad_click_list_00 2用户点击广告对应广告主 id 列表[string,][1^2…]
27ad_click_list_00 3用户点击广告推荐应用列 表[string,][1^2…]
28ad_close_list_00 1用户关闭广告任务列表[string,][1^2…]
29ad_close_list_00 2用户关闭广告对应广告主 列表[string,][1^2…]
30ad_close_list_00 3用户关闭广告推荐应用列 表[string,][1^2…]
31pt_d时间戳String202205221430
32log_id样本 idInt12345678
  • 源域用户行为数据
序号字段名称字段含义是 否 可 为空字段类 型取值样例
1u_userId用户标识String0001
2u_phonePrice用户手机价格String13
3u_browserLifeCycle浏览器用户活跃度String10
4u_browserMode浏览器业务类型String11
5u_feedLifeCycle信息流用户活跃度String12
6u_refreshTimes信息流日均有效刷新次数String16
7u_newsCatInterests信息流图文 点击 分类偏 好[string,][1^2…]
8u_newsCatDislike信息流图文 负反馈 分类 偏好[string,][1^2…]
9u_newsCatInteres tsST用户短时 兴趣 分类偏好[string,][1^2…]
10u_click_ca2_news用户图文 类别 点击序列[string,][1^2…]
11i_docId文章 docidString0001
12i_s_sourceId文章来源的 sourceidString0001
13i_regionEntity文章地域词 idString0001
14i_cat文章类别 idString0001
15i_entities文章实体词 id[string,][1^2…]
16i_dislikeTimes文章负反馈量String60
17i_upTimes文章点赞量String22
18I_dtype文章展现形式String20
19e_ch频道String1,2…
20e_m事件来源设备机型String1,2…
21e_po第几位String9
22e_pl拜访地String1,2…
23e_rn第几刷String1
24e_section信息流场景类型String13
25e_et时间戳String202205221430
26label是否点击, -1:否, 1:是String1
27cilLabel是否点赞,-1:否, 1:是String1
28pro文章浏览进度String1,2…

评估方式

评估方式: 统计广告域的样本 CTR 预估值, 计算 GAUC 和 AUC

评测指标: 本次比赛使用 GAUC 和 AUC 的加权求和作为评估指标, 具体公式如下:
x A U C = α ∗ G A U C + β ∗ A U C x xAUC=α∗GAUC+β∗AUCx xAUC=αGAUC+βAUCx
xAUC 越高,代表结果越优,排名越靠前。其中,AUC为全体样本的 AUC 统计, GAUC 为分组 AUC 的加权求和, 以用户为维度分组,分组权值为分组内曝光量/总曝光)

G A U C = ∑ k = i n A U C i ∗ I m p r e s s i o n i ∑ k = i n I m p r e s s i o n i GAUC=\frac{\sum_{k=i}^nAUC_i*Impression_i}{\sum_{k=i}^nImpression_i} GAUC=k=inImpressionik=inAUCiImpressioni

初赛:α 为 0.7,𝛽为 0.3

提交方式

选手提交结果为一个 submission.csv 文件, 编码采用无 BOM 的 UTF-8 ,格式如下:

log_id,pctr

其中 log_id 为对应测试样本中的 log_id,pctr 对应测试样本经由模型计算出的预 估 ctr 值, pctr 保留 6 位小数。提交文件参考如下示例:

log_id,pctr
1, 0.002345
2, 0.010456

学习打卡

任务名称难度
任务1:比赛报名与尝试低、1
任务2:比赛数据分析中、2
任务3:验证集划分与树模型中、2
任务4:特征工程入门中、2
任务5:特征工程进阶中、2
任务6:深度推荐模型中、2
任务7:深度序列模型中、2
任务8:多折训练与集成高、3

赛题理解和思路

本赛题提供7天数据用于训练,1天数据用于测试,数据包括目标域(广告域)用户行为日志,用户基本信息,广告素材信息,源域(信息流域)用户行为数据,源域(信息流域)物品基本信息等。希望选手基于给出的数据,识别并生成源域能反映用户兴趣,并能应用于目标域的用户行为特征表示,基于用户行为序列信息,进行源域和目标域的联合建模,预测用户在广告域的点击率。所提供的数据经过脱敏处理,保证数据安全。

本次比赛是一个经典点击率预估(CTR)的数据挖掘赛,任务是构建一种模型,根据用户的测试数据来预测这个用户是否点击广告。这是典型的二分类问题,模型的预测输出为 0 或 1 (点击:1,未点击:0)

机器学习中,关于分类任务我们一般会想到逻辑回归、决策树等算法,在本文实践代码中,我们尝试使用逻辑回归来构建我们的模型。我们在解决机器学习问题时,一般会遵循以下流程:图片

任务1:报名比赛

  • 步骤1:报名比赛https://developer.huawei.com/consumer/cn/activity/digixActivity/digixdetail/101655281685926449?ha_source=co&ha_sourceId=89000234
  • 步骤2:下载比赛数据(点击比赛页面的赛题数据)
  • 步骤3:解压比赛数据,并使用pandas进行读取;
  • 步骤4:使用逻辑回归模型完成建模并提交;

Baseline尝试

#安装相关依赖库 如果是windows系统,cmd命令框中输入pip安装,参考上述环境配置
#!pip install sklearn
#!pip install pandas

#---------------------------------------------------
#导入库
import pandas as pd

# 目标域用户行为数据
train_ads = pd.read_csv('./train/train_data_ads.csv',
    usecols=['log_id', 'label', 'user_id', 'age', 'gender', 'residence', 'device_name',
            'device_size', 'net_type', 'task_id', 'adv_id', 'creat_type_cd'])

test_ads = pd.read_csv('./test/test_data_ads.csv',
    usecols=['log_id', 'user_id', 'age', 'gender', 'residence', 'device_name',
    'device_size', 'net_type', 'task_id', 'adv_id', 'creat_type_cd'])

# 数据采样
train_ads = pd.concat([
    train_ads[train_ads['label'] == 0].sample(70000),
    train_ads[train_ads['label'] == 1].sample(10000),
])

#----------------模型训练----------------
# 加载逻辑回归模型,训练
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(
    train_ads.drop(['log_id', 'label', 'user_id'], axis=1),
    train_ads['label']
)

#----------------结果输出----------------
# 模型预测
test_ads['pctr'] = clf.predict_proba(
    test_ads.drop(['log_id', 'user_id'], axis=1),
)[:, 1]

# 写入文件
test_ads[['log_id', 'pctr']].to_csv('submission.csv',index=None)
  • 利用baseline进行提交,得到了大概0.58的结果

baseline

任务2:比赛数据分析

对目标域用户行为进行分析

  • 对于训练集 和 测试集,用户重合的比例是多少?

    我们首先可以分别看看训练集和测试集的用户个数

    train_data_ads = pd.read_csv('./train/train_data_ads.csv')
    test_data_ads = pd.read_csv('./test/test_data_ads.csv')
    train_id_ads = train_data_ads['user_id'].unique()
    test_id_ads = test_data_ads['user_id'].unique()
    len(train_id_ads), len(test_id_ads) # 在训练集和测试集中,去重的id个数
    
    (65297, 28771)
    

    除此之外,我们还查看一下,训练集和测试集相同的用户个数,这个很简单,我们可以通过利用集合的去重,然后再通过集合的与得到我们的结果

    #统计两个数组相同元素个数
    #方法一:前面用户id已经去重了,但是这里不加set会报错
    dup_id_len = len(set(train_id_ads) & set(test_id_ads))
    dup_id_len
    #方法二:
    #duplicate_id = [x for x in train_id_ads if x in test_id_ads]
    #dup_id_len = len(duplicate_id)
    
    27186
    

    我们还可以查看用户重合的比例,从得到的结果来看,测试集重合的比例比较高

    #对于训练集 和 测试集,用户重合的比例是多少?
    ratio_dup_train = dup_id_len / len(train_id_ads)
    ratio_dup_test = dup_id_len / len(test_id_ads)
    ratio_dup_train, ratio_dup_test
    
    (0.41634378302219094, 0.9449098050119913)
    
  • 统计字段中有多少数值字段,多少非数值字段?

    train_data_ads.dtypes
    # test_data_ads.dtypes
    

    从结果我们就可以看出来,其中object就不是数值字段,一共有7个是非数值字段

    log_id                    int64
     label                     int64
     user_id                   int64
     age                       int64
     gender                    int64
     residence                 int64
     city                      int64
     city_rank                 int64
     series_dev                int64
     series_group              int64
     emui_dev                  int64
     device_name               int64
     device_size               int64
     net_type                  int64
     task_id                   int64
     adv_id                    int64
     creat_type_cd             int64
     adv_prim_id               int64
     inter_type_cd             int64
     slot_id                   int64
     site_id                   int64
     spread_app_id             int64
     hispace_app_tags          int64
     app_second_class          int64
     app_score               float64
     ad_click_list_v001       object
     ad_click_list_v002       object
     ad_click_list_v003       object
     ad_close_list_v001       object
     ad_close_list_v002       object
     ad_close_list_v003       object
     pt_d                      int64
     u_newsCatInterestsST     object
     u_refreshTimes            int64
     u_feedLifeCycle           int64
     dtype: object
    
  • 统计哪些用户属性(年龄、性别、手机设备等)与 标签相关性最强?

    数据相关性分析中,经常用到data.corr()函数,data.corr()表示了data中的两个变量之间的相关性,取值范围为[-1,1],取值接近-1,表示反相关,类似反比例函数,取值接近1,表正相关。

    DataFrame.corr(self, method=‘pearson’, min_periods=1) → ‘DataFrame’

    参数:
    method: 可选值为{‘pearson’, ‘kendall’, ‘spearman’}
    pearson :标准相关系数,Pearson相关系数来衡量两个数据集合是否在一条线上面,即针对线性数据的相关系数计算,针对非线性数据便会有误差。
    kendall :Kendall Tau相关系数,用于反映分类变量相关性的指标,即针对无序序列的相关系数,非正太分布的数据
    spearman :非线性的,非正太分布的数据的相关系数
    min_periods: 每对列必须具有有效结果的最小观察数。目前仅适用于皮尔逊和斯皮尔曼相关

    返回: 各类型之间的相关系数DataFrame表格。

    注意: 变量与自身的相关性为1。

    可以看到最大的相关性为 lot_id 字段,其次为series_group,还有就是app_second_class

    corr = train_data_ads.corr(method = 'kendall')['label']
    corr.sort_values()
    
    u_feedLifeCycle    -0.084677
    u_refreshTimes     -0.071523
    creat_type_cd      -0.043874
    adv_prim_id        -0.013145
    age                -0.009950
    city_rank          -0.007258
    gender             -0.005801
    hispace_app_tags   -0.003057
    device_name        -0.002123
    task_id            -0.001353
    residence          -0.001055
    city               -0.000617
    log_id             -0.000555
    user_id            -0.000428
    inter_type_cd       0.000284
    device_size         0.001004
    pt_d                0.001009
    adv_id              0.001220
    emui_dev            0.002263
    series_dev          0.003079
    spread_app_id       0.006494
    net_type            0.007469
    app_score           0.007539
    app_second_class    0.010145
    series_group        0.014230
    slot_id             0.031366
    label               1.000000
    site_id                  NaN
    Name: label, dtype: float64
    

    除此之外,我们还可以画热力图更直观的可视化我们的相关性系数

    import seaborn as sns
    sns.heatmap(train_data_ads.corr(),linewidths=0.1,vmax=1.0, square=True,linecolor='white', annot=True)
    

对源域用户行为进行分析

  • 源域用户行为目标域用户行为 训练集和测试集用户重合的比例分别是多少?

    首先和前面对目标域方法一样,读入文件后查看用户的id

    train_data_feeds = pd.read_csv('./train/train_data_feeds.csv')
    test_data_feeds = pd.read_csv('./test/test_data_feeds.csv')
    train_id_feeds = train_data_feeds['u_userId'].unique()
    test_id_feeds = test_data_feeds['u_userId'].unique()
    len(train_id_feeds), len(test_id_feeds) # 在训练集和测试集中,去重的id个数
    
    (180123, 51162)
    

    其次,我们计算一下,源域用户行为目标域用户行为的训练集的用户重合比例

    dup_id_len_train = len(set(train_id_ads) & set(train_id_feeds))
    dup_id_len_test = len(set(test_id_ads) & set(test_id_feeds))
    ratio_dup_train = dup_id_len_train / len(train_id_feeds)
    ratio_dup_test = dup_id_len_test / len(test_id_feeds)
    ratio_dup_train, ratio_dup_test
    
    (0.36251339362546703, 0.5623509636058012)
    
  • 统计字段中有多少数值字段,多少非数值字段?

    从结果可以看到,我们只有7个非数值字段-,一共有28个字段,21个为数值字段

    train_data_feeds.dtypes
    # test_data_feeds.dtypes
    
    u_userId                 int64
    u_phonePrice             int64
    u_browserLifeCycle       int64
    u_browserMode            int64
    u_feedLifeCycle          int64
    u_refreshTimes           int64
    u_newsCatInterests      object
    u_newsCatDislike        object
    u_newsCatInterestsST    object
    u_click_ca2_news        object
    i_docId                 object
    i_s_sourceId            object
    i_regionEntity           int64
    i_cat                    int64
    i_entities              object
    i_dislikeTimes           int64
    i_upTimes                int64
    i_dtype                  int64
    e_ch                     int64
    e_m                      int64
    e_po                     int64
    e_pl                     int64
    e_rn                     int64
    e_section                int64
    e_et                     int64
    label                    int64
    cillabel                 int64
    pro                      int64
    dtype: object
    

理解数据字段的逻辑,并尝试对数据字段进行分组

这一部分是需要对我们目标域和源域的数据的数据字段进行逻辑上的理解,首先分析的是目标域

  • 首先可以分出城市,这一部分表示了所在的地区的繁荣程度,以及地理位置

    1residence常住地-省份
    2city常住地-市-编号
    3city_rank常住地-市-等级
  • 其次我们可以根据设备的类型和版本,包括手机的机型,以及手机的尺寸,这些都代表着用户使用的设备的参数

    1series_dev设备系列
    2series_group设备系列分组
    3emui_devemui 版本号
    4device_name用户使用的手机机型
    5device_size用户使用手机的尺寸
  • 其次就是广告的设计也可以分为一个组,这些代表着广告创作时使用的创意和素材 以及 面向的对象和创建方式

    1adv_id广告任务对应的素材 id
    2creat_type_cd素材的创意类型 id
    3adv_prim_id广告任务对应的广告主 id
    4inter_type_cd广告任务对应的素材的交 互类型
  • 还有广告的投放,广告投放的媒体和各个应用也是比较重要的一环,面对的应用的面向用户,以及还有投放的app的应用的得分

    最重要的就是slot_id,它与标签的相关性系数最大,所以说明广告位id是非常重要的一环。

    1slot_id广告位 id
    2site_id媒体 id
    3spread_app_id投放广告任务对应的应用 id
    4Tags广告任务对应的应用的标 签
    5app_second_class广告任务对应的应用的二 级分类
    6app_scoreapp 得分

任务3:验证集划分与树模型

学习KFold数据划分逻辑

在sklearn中,有一个KFold函数,用来进行k折交叉验证,这里简单介绍一下cross-validation (CV for short),交叉验证

基本的思路是:k-fold CV,也就是我们下面要用到的函数KFold,是把原始数据分割为K个子集,每次会将其中一个子集作为测试集,其余K-1个子集作为训练集。

下图是官网提供的一个介绍图

../_images/grid_search_cross_validation.png

classsklearn.model_selection.KFold(n_splits=5, **,shuffle=False,*random_state=None)
参数:

**n_splits:**int, default=5 要分割为多少个K子集
shuffle: bool, default=False 是否要洗牌(打乱数据)
random_state: int or RandomState instance, default=None 如果shuffle是True,指定的种子值

import numpy as np
from sklearn.model_selection import KFold

X = np.random.randint(1,100,20).reshape((10,2))

kf = KFold(n_splits=3)

for X_train,X_test in kf.split(X):
    print(X_train,X_test)

我们可以看到,我们把数据分为了5份,每份都分别作为测试器,其余k-1份作为训练集,这里返回的是数据集的划分后的索引

[2 3 4 5 6 7 8 9] [0 1]
[0 1 4 5 6 7 8 9] [2 3]
[0 1 2 3 6 7 8 9] [4 5]
[0 1 2 3 4 5 8 9] [6 7]
[0 1 2 3 4 5 6 7] [8 9]

这里我们就可以通过索引得到我们划分后的训练集和测试集

for X_train_i,X_test_i in kf.split(X):
    print(X[X_train_i],X[X_test_i])
[[49 41]
 [54 35]
 [53 86]
 [65 21]
 [39 72]
 [68 58]
 [19 46]
 [91 55]] [[30 33]
 [32 87]]
[[30 33]
 [32 87]
 [53 86]
 [65 21]
 [39 72]
 [68 58]
 [19 46]
 [91 55]] [[49 41]
 [54 35]]
[[30 33]
 [32 87]
 [49 41]
 [54 35]
 [39 72]
 [68 58]
 [19 46]
 [91 55]] [[53 86]
 [65 21]]
[[30 33]
 [32 87]
 [49 41]
 [54 35]
 [53 86]
 [65 21]
 [19 46]
 [91 55]] [[39 72]
 [68 58]]
[[30 33]
 [32 87]
 [49 41]
 [54 35]
 [53 86]
 [65 21]
 [39 72]
 [68 58]] [[19 46]
 [91 55]]

使用Pandas和sklean完成下属数据划分操作:

  • 训练集验证集用户不重合的情况

    我们可以尝试得到共有多少个user_id,也就是用户

    user_id = train_data_ads['user_id'].unique()
    print('一共有 {} 种 user_id'.format(len(user_id)))
    user_id
    
    一共有 65297 种 user_id
    array([100005, 100006, 100009, ..., 286534, 286715, 286999])
    

    我们如果确定了user_id以后,可以通过以下方法得到结果,取列表中的user_id作为dataframe

    train_data_ads.loc[train_data_ads['user_id'].isin(user_id)]
    # train_data_ads[train_data_ads['user_id'].isin(userid_name)] 
    
    log_idlabeluser_idagegenderresidencecitycity_rankseries_devseries_groupad_click_list_v001ad_click_list_v002ad_click_list_v003ad_close_list_v001ad_close_list_v002ad_close_list_v003pt_du_newsCatInterestsSTu_refreshTimesu_feedLifeCycle
    0373250010000532161472326301573064814278^317062066177610361142193122410712181732022060303263922016015
    1373253110000532161472326301573064814278^317062066177610361142193122410712181732022060303263922016015
    2373252110000532161472326301573064814278^317062066177610361142193122410712181732022060303263922016015
    3373251010000532161472326301573064814278^317062066177610361142193122410712181732022060303263922016015
    4373255010000532161472326301573064814278^317062066177610361142193122410712181732022060303283922016015
    7675512650508028718064333193272214893442622929340572638418581717115620561058190^20824107121817320220609084819920715721986717
    7675513650492028718064333193272214893442622929340572638418581717115620561058190^20824107121817320220609084819920715721986717
    7675514650509028718064333193272214893442622929340572638418581717115620561058190^20824107121817320220609101219920715721986717
    7675515650491128718064333193272214893442622929340572638418581717115620561058190^20824107121817320220609111919920715721986717
    7675516650499028718064333193272214893442622929340572638418581717115620561058190^20824107121817320220609084619920715721986717

    7675517 rows × 35 columns

    接着,我写了一个函数,相当于分开验证集和训练集的用户

    def train_val_split(data, ratio = 0.8):
      np.random.shuffle(data)
      Len = len(data)
      train = data[:int(Len*ratio)]
      val = data[int(Len*ratio):]
      return train, val
    
    # 随机取一部分userid作为训练集,其余全部作为验证集
    # 比例大约是 训练集:验证集 = 8:2
    user_id_train,user_id_val = train_val_split(user_id)
    len(user_id_train),len(user_id_val),user_id_train,user_id_val
    
    (52237,
     13060,
     array([104773, 117348, 183842, ..., 252764, 136365, 212255]),
     array([250682, 240767, 271978, ..., 109581, 186293, 115990]))
    
    train_data_ads_userid = train_data_ads.loc[train_data_ads['user_id'].isin(user_id_train)]
    val_data_ads_userid = train_data_ads.loc[train_data_ads['user_id'].isin(user_id_val)]
    
  • 验证集用户时间戳 晚于 训练集用户时间戳

    这一部分,我们可以对数据集进行操作,可以以用户时间戳进行排序,最后取即可

    train_data_ads.sort_values(by = 'pt_d', ignore_index=True)
    
    log_idlabeluser_idagegenderresidencecitycity_rankseries_devseries_groupad_click_list_v001ad_click_list_v002ad_click_list_v003ad_close_list_v001ad_close_list_v002ad_close_list_v003pt_du_newsCatInterestsSTu_refreshTimesu_feedLifeCycle
    06524020157067721721541183079416331622410712181732022060201231121092122039417
    12593930144249822443153033098814584142233200016382143312361535^1036168^312241071218173202206020127168157579898517
    211653902138638225117216518536286241832614332194162009120612091344129034611130924107121817320220602013126169119762016
    31012010217209723731223131701926564155391979010321172314171690205115971862461621903122410712181732022060201382718627112168817
    4508547011306632114152326332572622725635^34210103620661914^1005312114190^3092410712181732022060201470211
    76755125803850150395522044022361673916542102410712181732022061012090217
    7675513739230027012582463012236257072829034024129993628716951036111215571633190312162372305241071218173202206101209259410711227914
    7675514910308027247564333193272204361702031706294121971411121036206618301005312114162^30924107121817320220610120921921811211236917
    7675515434262019594072203992347361321458722637210412450510411306182310321774199246190114367241071218173202206101209219112112112108917
    7675516405329022326872203285165214931606814584355631333010361234123615221636312191190^20824107121817320220610120919962981025617

    7675517 rows × 35 columns

  • 联合目标域用户行为源域用户行为,并使用时间戳和用户划分验证集

    接着利用目标域数据集的用户的不同,以大概8:2的比例划分了训练集和验证集

    对时间戳来说,这一部分我个人会有些疑惑,既要用户不同,又要时间戳前后,那只有相同的用户,才会有时间戳前后的概念

    所以最后我这一部分先不进行时间戳的划分,而是单单对不同用户划分了训练集和验证集

    # ----------------数据集划分-------------
    # 划分训练集和测试集
    cols = [f for f in train_data_ads.columns if f not in ['label']]
    
    train_data_ads_userid = train_data_ads.loc[train_data_ads['user_id'].isin(user_id_train)]
    val_data_ads_userid = train_data_ads.loc[train_data_ads['user_id'].isin(user_id_val)]
    
    x_train = train_data_ads_userid[cols]
    y_train = train_data_ads_userid['label']
    
    x_val = val_data_ads_userid[cols]
    y_val = val_data_ads_userid['label']
    
    x_test = test_data_ads[cols]
    #--------------------------------------
    

使用树模型、随机森林、LightGBM或CatBoost完成模型多折训练

  • catboost

接着利用了Catboost进行训练,并没有进行多折训练,得到初步的分数是0.716975

params = {'learning_rate': 0.3, 'depth': 5, 'l2_leaf_reg': 10, 'random_seed':2022,
                'od_type': 'Iter', 'od_wait': 100, 'allow_writing_files': False}


clf = CatBoostClassifier(iterations=20000,eval_metric='AUC',task_type='GPU',**params)
model = clf.fit(x_train,y_train, eval_set=(x_val, y_val),metric_period=100,use_best_model=True)
0:	test: 0.7024544	best: 0.7024544 (0)	total: 26.4ms	remaining: 8m 48s
100:	test: 0.7895933	best: 0.7895950 (99)	total: 2.36s	remaining: 7m 44s
200:	test: 0.7926059	best: 0.7926413 (195)	total: 4.67s	remaining: 7m 40s
300:	test: 0.7938464	best: 0.7938464 (300)	total: 7s	remaining: 7m 37s
400:	test: 0.7945357	best: 0.7945357 (400)	total: 9.32s	remaining: 7m 35s
500:	test: 0.7945496	best: 0.7946053 (480)	total: 11.6s	remaining: 7m 33s
600:	test: 0.7945190	best: 0.7946548 (556)	total: 14s	remaining: 7m 30s
700:	test: 0.7945854	best: 0.7946799 (656)	total: 16.3s	remaining: 7m 28s
bestTest = 0.7946799397
bestIteration = 656
Shrink model to first 657 iterations.

  • lightgbm

还尝试了利用LGB的模型进行训练,也得到了不错的结果,这里本来尝试利用GPU,但是环境一直不可以

from lightgbm import LGBMClassifier

clf = clf = LGBMClassifier(feature_fraction = 0.8,
                    learning_rate = 0.1,
                    max_depth= 10,
                    num_leaves = 16,
                    metric='auc',
                    num_iteration = 1000,
                    is_unbalance=True,
                    # boosting='gbdt',
                    # num_boost_round=300,
                    early_stopping_round=30,
                    # device='gpu', 
                    # gpu_platform_id=0, 
                    # gpu_device_id=0,
                    verbose=1,
                    )
model = clf.fit(x_train,y_train, eval_set=(x_val, y_val))

在这里插入图片描述

  • xgboost

还尝试利用了xgboost,得到了不错的结果

from xgboost import XGBClassifier

xgb_params = {'n_estimators':20000,
            'max_depth':5,
            'learning_rate':0.1,
            'eval_metric':'auc',
            'seed':2022,
            'verbose':True,
            'objective':'reg:logistic',
            "gpu_id":0, 
            "tree_method":"gpu_hist",
            }
clf = XGBClassifier(**xgb_params)

model = clf.fit(x_train,y_train, eval_set=[(x_val, y_val)],early_stopping_rounds=50,eval_metric='auc')

在这里插入图片描述

  • catboost + kfold

再接着利用多折训练的方式,设置折数为3个,所以是3折模型训练。

这一部分像前面单独分清楚训练集和验证集,因为KFold会从整个数据集中提取index,一部分作为训练集,一部分作为验证集进行训练

seed = 2022
train_x = train_data_ads[cols]
train_y = train_data_ads['label']

kf = KFold(n_splits=3, shuffle=True, random_state=seed)
cv_scores = []
test = np.zeros(x_test.shape[0])
for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
    print('************************************ {} {}************************************'.format(str(i+1), str(seed)))
    trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
            
    params = {'learning_rate': 0.3, 'depth': 5, 'l2_leaf_reg': 10, 'bootstrap_type':'Bernoulli','random_seed':seed,
                'od_type': 'Iter', 'od_wait': 50, 'allow_writing_files': False}

    model = CatBoostClassifier(iterations=20000, **params, eval_metric='AUC', task_type ='GPU')
    model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
                metric_period=200,
                cat_features=[], 
                use_best_model=True, 
                verbose=1)

    val_pred  = model.predict_proba(val_x)[:,1]
    test_pred = model.predict_proba(x_test)[:,1]
        
    test += test_pred / kf.n_splits
    cv_scores.append(roc_auc_score(val_y, val_pred))
    
    print(cv_scores)
************************************ 1 2022************************************
0:	test: 0.7065597	best: 0.7065597 (0)	total: 22.1ms	remaining: 7m 22s
200:	test: 0.7975476	best: 0.7975476 (200)	total: 4.04s	remaining: 6m 38s
400:	test: 0.8002338	best: 0.8002338 (400)	total: 8.07s	remaining: 6m 34s
600:	test: 0.8010459	best: 0.8010792 (595)	total: 12.1s	remaining: 6m 30s
800:	test: 0.8016420	best: 0.8016428 (798)	total: 16.1s	remaining: 6m 25s
1000:	test: 0.8021788	best: 0.8021788 (1000)	total: 20.1s	remaining: 6m 22s
1200:	test: 0.8025397	best: 0.8025480 (1192)	total: 24.2s	remaining: 6m 18s
1400:	test: 0.8026709	best: 0.8027424 (1357)	total: 28.2s	remaining: 6m 14s
bestTest = 0.8027424216
bestIteration = 1357
Shrink model to first 1358 iterations.
[0.8027424283302532]
************************************ 2 2022************************************
0:	test: 0.7099740	best: 0.7099740 (0)	total: 21.9ms	remaining: 7m 18s
200:	test: 0.7987009	best: 0.7987009 (200)	total: 4.03s	remaining: 6m 37s
400:	test: 0.8011493	best: 0.8011587 (386)	total: 8.05s	remaining: 6m 33s
600:	test: 0.8020754	best: 0.8020836 (599)	total: 12.1s	remaining: 6m 29s
800:	test: 0.8025443	best: 0.8025546 (793)	total: 16.1s	remaining: 6m 25s
1000:	test: 0.8032209	best: 0.8032209 (1000)	total: 20.1s	remaining: 6m 21s
bestTest = 0.803391844
bestIteration = 1112
Shrink model to first 1113 iterations.
[0.8027424283302532, 0.8033918763632052]
************************************ 3 2022************************************
0:	test: 0.7065725	best: 0.7065725 (0)	total: 21.1ms	remaining: 7m 2s
200:	test: 0.7976198	best: 0.7976198 (200)	total: 4.03s	remaining: 6m 36s
400:	test: 0.7997762	best: 0.7997762 (400)	total: 8.03s	remaining: 6m 32s
600:	test: 0.8010272	best: 0.8010328 (592)	total: 12.1s	remaining: 6m 29s
800:	test: 0.8015802	best: 0.8015901 (799)	total: 16.1s	remaining: 6m 25s
bestTest = 0.8017456532
bestIteration = 858
Shrink model to first 859 iterations.
[0.8027424283302532, 0.8033918763632052, 0.8017456522533244]

最后提交查看结果,从结果可以看到,多折训练的结果会比正常训练更好,能达到0.80+的AUC,最后提交得到0.718

因为多折训练在某一方面对我们的数据的过拟合进行了一定的抑制,所以在大数据中往往会表现的不错,后续也可以尝试多加一部分折数

在这里插入图片描述

任务4:特征工程入门

使用Pandas完成下列统计【目标域】:

  • 统计用户历史行为次数
  • 统计用户历史点击的广告分类
  • 统计每类广告被点击的概率

将提取的特征加入树模型重新训练

任务5:特征工程进阶

使用gensim和Pandas完成下列统计【目标域 + 原域】:

  • 使用word2vec训练广告序列和实体序列
  • 聚合得到用户word2vec编码
  • 计算用户与当前广告序列的相似度

将提取的特征加入树模型成绩排名好像训练

任务6:全连接模型

搭建全连接网络模型

将所有的特征进行数值编码

使用early stop进行进行训练

任务7:深度推荐模型

将类别特征进行Embedding嵌入

对模型进行训练与验证

搭建DeepFM模型进行与验证

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风信子的猫Redamancy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值