2022华为推荐赛事——广告-信息流跨域ctr预估
一、赛事背景
广告推荐主要基于用户对广告的历史曝光、点击等行为进行建模,如果只是使用广告域数据,用户行为数据稀疏,行为类型相对单一。而引入同一媒体的跨域数据,可以获得同一广告用户在其他域的行为数据,深度挖掘用户兴趣,丰富用户行为特征。引入其他媒体的广告用户行为数据,也能丰富用户和广告特征。本赛题希望选手基于广告日志数据,用户基本信息和跨域数据优化广告ctr预估准确率。目标域为广告域,源域为信息流推荐域,通过获取用户在信息流域中曝光、点击信息流等行为数据,进行用户兴趣建模,帮助广告域ctr的精准预估。
二、解决方案
基于鱼佬提供的2.1版本baseline代码,我做了进一步改进得到了以下的解决方案。
2.1 导入必要的库
import pandas as pd import xgboost as xgb import numpy as np
2.2 数据读取
#用pandas读入数据 #记得改路径 train_data = pd.read_csv('./train_data_ads.csv') train_feed = pd.read_csv('./train_data_feeds.csv') test_data = pd.read_csv('./test_data_ads.csv') test_feed = pd.read_csv('./test_data_feeds.csv')
2.3 特征工程
# 自然数编码(重新进行编码)---->准确说是统计矩阵型数据种类 def label_encode(series): unique = list(series.unique()) return series.map(dict(zip(unique, range(series.nunique())))) for col in ['ad_click_list_v001','ad_click_list_v002','ad_click_list_v003','ad_close_list_v001','ad_close_list_v002','ad_close_list_v003','u_newsCatInterestsST']: train_data.loc[:,col]= label_encode(train_data.loc[:,col]) for col in ['u_newsCatInterests','u_newsCatDislike','u_newsCatInterestsST','u_click_ca2_news']: train_feed.loc[:,col]= label_encode(train_feed.loc[:,col]) for col in ['ad_click_list_v001','ad_click_list_v002','ad_click_list_v003','ad_close_list_v001','ad_close_list_v002','ad_close_list_v003','u_newsCatInterestsST']: test_data.loc[:,col]= label_encode(test_data.loc[:,col]) for col in ['u_newsCatInterests','u_newsCatDislike','u_newsCatInterestsST','u_click_ca2_news']: test_feed.loc[:,col]= label_encode(test_feed.loc[:,col])
2.4 特征处理
比赛过程中突然要求禁止使用穿越特征,所以进行了一定的处理,使得特征穿越不再发生。另外还出现了数据缺失等问题进行处理。
#数据缺失处理(不具有穿越特征) train_feed = train_feed.drop(columns=['label','i_docId','i_s_sourceId','i_entities']) test_feed = test_feed.drop(columns=['i_docId','i_s_sourceId','i_entities']) train_data.rename(columns={'pt_d': 'e_et','user_id':'u_userId'}, inplace=True) test_data.rename(columns={'pt_d': 'e_et','user_id':'u_userId'}, inplace=True) train_data=train_data.dropna(subset='e_et') train_feed=train_feed.dropna(subset='e_et') test_data=test_data.dropna(subset='e_et') test_feed=test_feed.dropna(subset='e_et') train_feed = train_feed.drop_duplicates(keep='last', subset=['u_userId', 'e_et']) test_feed = test_feed.drop_duplicates(keep='last', subset=['u_userId', 'e_et']) train_data['e_et']=train_data['e_et'].astype(int) train_feed['e_et']=train_feed['e_et'].astype(int) test_data['e_et']=test_data['e_et'].astype(int) test_feed['e_et']=test_feed['e_et'].astype(int) train_data = train_data.sort_values(by='e_et').sort_values(by='u_userId').fillna(method='pad') train_feed = train_feed.sort_values(by='e_et').sort_values(by='u_userId').fillna(method='pad') test_data = test_data.sort_values(by='e_et').sort_values(by='u_userId').fillna(method='pad') test_feed = test_feed.sort_values(by='e_et').sort_values(by='u_userId').fillna(method='pad') train_data = train_data.merge(train_feed,on=['u_userId','e_et'] ,how='left',sort=False) test_data = test_data.merge(test_feed,on=['u_userId','e_et'] ,how='left',sort=False) test_data = test_data.drop(columns=['label'])
2.5 转换
# 转换成Dmatrix格式 feature_data_columns = [f for f in train_data.columns if f not in ['log_id','u_userId','e_et','label']] feature_test_columns = [f for f in test_data.columns if f not in ['log_id','u_userId','e_et','label']] target_column = 'label' xgtrain = xgb.DMatrix(train_data[feature_data_columns].values, train_data[target_column].values) xgtest = xgb.DMatrix(test_data[feature_test_columns].values)
2.6 超参数设定及训练
#超参数设定 #警告暂时不用管
#最佳成绩:0.707721
param = {'max_depth':6, 'eta':1.1, 'verbosity':0, 'subsample':1, 'colsample_bytree':0.7, 'objective':'multi:softprob', 'num_class':2} #设定watchlist用于查看模型状态 watchlist = [(xgtrain,'train')] num_round = 20 bst = xgb.train(param, xgtrain, num_round, watchlist)
2.8 预测及输出结果
#输出 pred = bst.predict(xgtest) test_data['pctr'] = pred[:,1] test_data[['log_id', 'pctr']].to_csv('submission.csv',index=None)
三、总结
这次比赛初步尝试了一个人构建神经网络,学习到了许多的经验,也认识到了自己的不足,尤其是在数据特征构建方面需要加强。初步的环境构建也花费了许久的时间,在这里也很感谢老师和队友们的帮助和努力。