第一次正式参加数据挖掘类的比赛,投入了三个星期。结果没有进入复赛,但是学到了许多经验。感谢技术圈和github的大佬们提供的baseline,让我少走了很多弯路。

第一次写博客,其一为了防止以后忘记,其二如果萌新能帮到萌新新们也是很开心啦。

思路:全文按照数据预处理、特征工程和模型融合讲解,并附有代码。

数据预处理

1 导入库和读取数据

1.1导入库:

import pandas as pd
import numpy as np
import lightgbm as lgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import log_loss
from sklearn import preprocessing
import warnings
from sklearn.grid_search import GridSearchCV
warnings.filterwarnings("ignore")
from sklearn.model_selection import StratifiedKFold
import time
from itertools import product
import copy
import itertools
import seaborn as sns

1.2读取测试集和训练集:

train是训练数据,test是需要预测的测试集(这里用的是B榜的test_b)。

分析数据时会发现训练集中有少量样本'instance_id'字段重复,但在比赛B榜的test_b中也有重复样本,所以不进行去重(被注释的那一行是去重操作)。

train = pd.read_csv(r'C:\Users\Lee\Desktop\round\origin_data\round1_ijcai_18_train_20180301.txt', sep="\s+")
test = pd.read_csv(r'C:\Users\Lee\Desktop\round\origin_data\round1_ijcai_18_test_b_20180418.txt', sep="\s+")
data = pd.concat([train, test])
#data = data.drop_duplicates(subset='instance_id')
data = data.reset_index(drop = True)

2 数据预处理

2.1文本类特征处理

数据有3个文本类型特征item_category_list、item_property_list和predict_category_property,使用split分割。

item_category_list特征有3个字段,第一个字段所有数据一样,所以取range(1,3)

item_property_list特征有100个字段,各字段之间无从属关系,由于后面字段缺失值太多,所以取range(19)

predict_category_property特征有14个字段,有从属关系,同样是后面字段缺失值太多取range(5)

缺失值如果过多,样本不足,在对该特征做进一步的统计时,很容易造成误判,例如在52万条样本中该字段只有100条样本,里面有取值为'A'的3条样本全部点击了广告。那么在预测时就很有可能直接判定取值为'A'的广告会被点击。

并使用LabelEncoding进行编码。

    lbl = preprocessing.LabelEncoder()for i in range(1, 3):data['item_category_list' + str(i)] = lbl.fit_transform(data['item_category_list'].map(lambda x: str(str(x).split(';')[i]) if len(str(x).split(';')) > i else ''))  # item_category_list的第0列全部都一样for i in range(19):data['item_property_list' + str(i)] = lbl.fit_transform(data['item_property_list'].map(lambda x: str(str(x).split(';')[i]) if len(str(x).split(';')) > i else '')) for i in range(7):data['predict_category_property' + str(i)] = lbl.fit_transform(data['predict_category_property'].map(lambda x: str(str(x).split(';')[i]) if len(str(x).split(';')) > i else ''))

2.2时间戳处理

数据中的时间是以时间戳(context_timestamp)形式存在,进行如下处理提取日期和时间

    data['realtime'] = data['context_timestamp'].apply(lambda x:time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(x)))data['realtime'] = pd.to_datetime(data['realtime'])data['day'] = data['realtime'].dt.daydata['hour'] = data['realtime'].dt.hour

3特征工程

3.1长度特征

每条样本的3个文本特征的长度不一样,其中也许包含了一些信息。例如商品的属性列表很详细,可能是比较精细的产品,例如电脑和显卡两种商品,电脑参数包括CPU/显卡/内存等多项信息,显然比显卡复杂,那么电脑的属性长度可能为50,而显卡只有10,50和10就可以反映商品的一些信息。

因此长度特征可以描述商品的种类。

    data['len_item_category'] = data['item_category_list'].map(lambda x: len(str(x).split(';')))data['len_item_property'] = data['item_property_list'].map(lambda x: len(str(x).split(';')))data['len_predict_category_property'] = data['predict_category_property'].map(lambda x: len(str(x).split(';')))

3.2基于商店质量的shop分段特征

shop中有4个连续型特征:shop_score_description、shop_score_delivery、

shop_score_service、shop_review_positive_rate

以shop_score_description为例,一条样本的取值是0.9632654,我们期望得知这个取值在总体样本中得分是处于什么样的一个水平。就需要进行分段,代码中0,1,2代表较差、一般、优秀3个等级,这里0.9632654被划分为较差,对应取值为0。

分段还有一个好处就是可以和其他特征进行组合,后面会提到。

    data['shop_score_description0'] = data['shop_score_description'].apply(lambda x: 2 if x > 0.984 else x)data['shop_score_description0'] = data['shop_score_description0'].apply(lambda x: 1 if 0.984 >= x > 0.97 else x)data['shop_score_description0'] = data['shop_score_description0'].apply(lambda x: 0 if  x <= 0.97 else x)data['shop_score_delivery0'] = data['shop_score_delivery'].apply(lambda x: 2 if x > 0.979 else x)data['shop_score_delivery0'] = data['shop_score_delivery0'].apply(lambda x: 1 if 0.979 >= x > 0.966 else x)data['shop_score_delivery0'] = data['shop_score_delivery0'].apply(lambda x: 0 if  x <= 0.966 else x)data['shop_score_service0'] = data['shop_score_service'].apply(lambda x: 2 if x > 0.979 else x)data['shop_score_service0'] = data['shop_score_service0'].apply(lambda x: 1 if 0.979 >= x > 0.967 else x)data['shop_score_service0'] = data['shop_score_service0'].apply(lambda x: 0 if  x <= 0.967 else x)data['shop_review_positive_rate0'] = data['shop_review_positive_rate'].apply(lambda x: 2 if x == 1 else x)data['shop_review_positive_rate0'] = data['shop_review_positive_rate0'].apply(lambda x: 1 if 1 > x > 0.98 else x)data['shop_review_positive_rate0'] = data['shop_review_positive_rate0'].apply(lambda x: 0 if  x <= 0.98 else x)

3.3基于历史点击率的分段特征

以user_age_level为例,我们观察该特征和是否点击is_trade的图:

sns.pointplot(x='user_age_level', y='is_trade', data=data)

可以看到点击率随着用户年龄上升而上升。这说明年龄在1005的用户最容易点击广告,可以脑补一下:1005应该对应的年龄是40-50岁之间,这个阶段的用户有经济实力,工作比较稳定(上班比较悠闲),有较强的点击广告的动机。

user_age_level这个特征区分度很高,很好地反映了年纪越大点击率越高这一信息,就可以不用做分段。

再看店铺评价数量等级shop_review_num_level和is_trade的关系:

就不如用户年龄那样呈明显的线性关系了,这个时候就可以进行分段。

def review_num(x):if (x==1)|(x==22)|(x==25):return 1elif ((x>=3)&(x<=5))|(x==23):return 2else:return 3    
data['shop_review_num_level'] = data['shop_review_num_level'].apply(review_num)

现在我们可以看看分段后的效果

sns.pointplot(x='shop_review_num_level', y='is_trade', data=data)

可以发现这一特征对'is_trade'的区分度提高了。即shop_review_num_level为3的点击概率很大,这一信息相比分段前能够更好地帮助模型做判断。

但是要注意这种特征本质上是带有穿越性的,我统计的是整个数据集中shop_review_num_level的点击率。data包括7月18-25用户是否点击广告的所有样本,而在判断单条7月20日的样本是否点击广告的时候,是无法知道20日后面的用户的行为的。

所以说,这种带有穿越性的特征十分容易导致过拟合,相当于拿着试卷答案在做试卷。在后面的统计特征中更要注意这一点。

3.4基于点击率的特征

如果我们能够知道某件商品以前的点击率。极端点说,如果有一个特征item_brand_id中为'豪牛'的牛奶品牌的广告,以前推送了100条广告,没有一个用户点击,点击率就为0。而另一个为'大草原'的牛奶品牌推送了50条广告,有25名用户点击,点击率为0.5。

那么在后面的预测中可以推断'豪牛'的广告大概率不会被点击,'大草原'的广告有50%的几率会被点击。并且两个品牌的点击率的可信度也是不一致的,'豪牛'样本量大,可信度自然会高。

所以应该统计两个信息:该广告的历史推送条数、该广告的历史点击率

def get_cnt(data,col_name):'''  Descr:输入:带有日期特征的数据集data,特征名称col_name输出:带有两个新特征的data:该特征的历史推送次数:col_name+'_cnt'该特征的历史点击率:col_name+'_cntrate11''''user_cnt = data.groupby(by=[col_name,'day'])['is_trade'].agg({col_name+'_cnt': 'count'})user_cnt = user_cnt.unstack()user_cnt.fillna(0,inplace=True)user_cnt = user_cnt.reindex_axis(sorted(user_cnt.columns), axis=1)user_cnt = user_cnt.cumsum(axis=1)user_cnt = user_cnt.stack()user_cnt = user_cnt.reset_index()user_cnt['day'] = user_cnt['day'].map(lambda x: x+1)user_cnt1 = data.groupby(by=[col_name,'day','is_trade']).agg( 'size')user_cnt1 = user_cnt1.unstack(level=['is_trade','day'])user_cnt1 = user_cnt1[:][1]user_cnt1.fillna(0,inplace=True)day_list = user_cnt1.columns.tolist()user_cnt1 = user_cnt1.reindex_axis(sorted(day_list), axis=1)user_cnt1 = user_cnt1.cumsum(axis=1)user_cnt1 = user_cnt1.stack()user_cnt1 = user_cnt1.reset_index()user_cnt1.columns = [col_name,'day',col_name+'_cntrate11']user_cnt1['day'] = user_cnt1['day'].map(lambda x: x+1)data = pd.merge(data,user_cnt,on=[col_name,'day'],how='left')data = pd.merge(data,user_cnt1,on=[col_name,'day'],how='left')data[col_name+'_cntrate11'] = data[col_name+'_cntrate11']/data[col_name+'_cnt']
#    del data[col_name+'_cnt']return data
def get_all_cnt(data):'''   Descr:输入:数据data,统计函数get_cnt(data,col_name)需要统计的特征列表(此处函数内部已定义)输出:包含每个特征的历史点击率、历史推送次数的data'''item_name = ['item_sales_level', 'item_price_level', 'item_collected_level','item_pv_level','item_brand_id','item_city_id']user_name = ['user_gender_id','user_age_level','user_occupation_id','user_star_level']shop_name = ['shop_review_num_level','shop_star_level',]id_name = ['user_id','item_id','shop_id','context_page_id']all_name = item_name+id_name+user_name+shop_name+['hour']for col_name in all_name:print('------>正在统计单一特征:'+col_name)data = get_cnt(data,col_name)return data

调用:

data = get_all_cnt(data)

3.5基于组合特征的点击率特征

该特征统计的是两个特征组合起来的历史点击率和推送次数。

例如:'item_brand_id'为'大草原'品牌和‘user_age_level’为'1005'时的点击率为0.01,

'item_brand_id'为'大草原'品牌和‘user_age_level’为'1007'时的点击率为0.8

两条样本对比来看,包含了'大草原'品牌可能主打老年奶粉,许多老年人(user_age_level’=1007)的用户会点击这条广告这一信息。

def get_cross_cnt2(data,col_name,base_name):'''  Descr:输入:数据data,需要组合的特征名col_name,base_name,无先后顺序输出:含有该组合特征的历史推送次数col_name+'_'+base_name+'_cnt'历史点击率col_name+'_'+base_name+'_cross_cntrate11'example:col_name = 'item_brand_id'base_name = 'item_id''''cnt = data.groupby(by = [col_name,base_name,'day'])['is_trade'].agg({col_name+'_'+base_name+'_cnt':'count'})cnt = cnt.unstack()cnt.fillna(0,inplace=True)cnt = cnt.reindex_axis(sorted(cnt.columns),axis = 1)cnt = cnt.cumsum(axis = 1)cnt = cnt.stack()cnt = cnt.reset_index()cnt['day'] = cnt['day'].map(lambda x : x+1)cnt1 = data.groupby(by=[col_name,base_name,'day','is_trade']).agg('size')cnt1 = cnt1.unstack(level=['is_trade','day'])cnt1 = cnt1[:][1]cnt1.fillna(0,inplace=True)cnt1 = cnt1.reindex_axis(sorted(cnt1.columns.tolist()),axis = 1)cnt1 = cnt1.cumsum(axis = 1)cnt1 = cnt1.stack()cnt1 = cnt1.reset_index()cnt1.columns = [col_name,base_name,'day',col_name+'_'+base_name+'_cross_cntrate11']cnt1['day'] = cnt1['day'].map(lambda x:x+1)data = pd.merge(data,cnt,on=[col_name,base_name,'day'],how='left')data = pd.merge(data,cnt1,on=[col_name,base_name,'day'],how='left')data[col_name+'_'+base_name+'_cross_cntrate11'] = data[col_name+'_'+base_name+'_cross_cntrate11']/data[col_name+'_'+base_name+'_cnt']
#    del data[col_name+'_'+base_name+'_cnt']return data

这里有两个小问题
第一,组合特征的方式

特征可以分为三大类user,shop,item

那么组合特征有两种方式:

1、按照大类的特征进行组合(大类属性内部不进行组合,不会出现user_age_level_user_gender_level这样的组合特征):

user_xxx_item_xxx

user_xxx_shop_xxx

item_xxx_shop_xxx

2、不按照大类属性,所有特征两两组合:

相比第一种会多出:

item_xxx_item_xxx

user_xxx_user_xxx

shop_xxx_shop_xxx

在使用lgb输出importance时可以发现第二种组合更优秀。

第二,统计组合特征时还可以统计的一些信息

对于两个特征col和base,有如下6个单一统计特征:

[col]推送次数

[base]推送次数

[col_base]推送次数

[col_base]点击次数

[col]点击次数

[base]点击次数

前面统计了单一特征的历史点击率:

[col]点击次数  /  [col]推送次数

[base]点击次数 / [base]推送次数

以及组合特征的历史点击率:

[col_base]点击次数 / [col_base]推送次数

实际上还可以统计的特征有:

[col_base]推送次数 / [col]推送次数

[col_base]推送次数 / [base]推送次数

[col_base]点击次数 / [col]点击次数

[col_base]点击次数 / [base]点击次数

前面两个从商家角度(广告推送者)出发,统计商家的市场占有率、推广程度,

后面两个从用户角度(是否点击)出发,统计用户对产品的喜爱程度。

例如col = 'item_brand_id' , base = 'item_city_id'

[col_base]推送次数 / [col]推送次数,以第一行的0.8为例,

在这里的意义就是:大草原在北京和上海都投放了广告,但是大草原主打北京,在北京投放了80%的广告。

[col_base]推送次数 / [base]推送次数,以第一行的0.66为例,

在北京一共投放了10条广告,其中大草原投放了66%的广告,而竞争对手豪牛投放了33%的广告。

同理,后面两个公式可以统计用户对大草原的点击率和豪牛的点击率

但是在实际应用中效果不好,所以没有统计。

def get_cross_cnt(data,col_name,base_name):'''Descr:输入数据data,输出5个统计信息:[col_base]点击次数 / [col_base]推送次数[col_base]推送次数 / [col]推送次数[col_base]推送次数 / [base]推送次数[col_base]点击次数 / [col]点击次数[col_base]点击次数 / [base]点击次数example:col_name = 'item_brand_id'base_name = 'item_id''''cnt = data.groupby(by = [col_name,base_name,'day'])['is_trade'].agg({col_name+'_'+base_name+'_cnt':'count'})cnt = cnt.unstack()cnt.fillna(0,inplace=True)cnt = cnt.reindex_axis(sorted(cnt.columns),axis = 1)cnt = cnt.cumsum(axis = 1)cnt = cnt.stack()cnt = cnt.reset_index()cnt['day'] = cnt['day'].map(lambda x : x+1)cnt1 = data.groupby(by=[col_name,base_name,'day','is_trade']).agg('size')cnt1 = cnt1.unstack(level=['is_trade','day'])cnt1 = cnt1[:][1]cnt1.fillna(0,inplace=True)cnt1 = cnt1.reindex_axis(sorted(cnt1.columns.tolist()),axis = 1)cnt1 = cnt1.cumsum(axis = 1)cnt1 = cnt1.stack()cnt1 = cnt1.reset_index()cnt1.columns = [col_name,base_name,'day',col_name+'_'+base_name+'_cross_cntrate11']cnt1['day'] = cnt1['day'].map(lambda x:x+1)data = pd.merge(data,cnt,on=[col_name,base_name,'day'],how='left')data = pd.merge(data,cnt1,on=[col_name,base_name,'day'],how='left')#    col_name的单特征量cnt_col = data.groupby(by = [col_name,'day'])['is_trade'].agg({col_name+'_cnt':'count'})cnt_col = cnt_col.unstack()cnt_col.fillna(0,inplace=True)cnt_col = cnt_col.reindex_axis(sorted(cnt_col.columns),axis = 1)cnt_col = cnt_col.cumsum(axis = 1)cnt_col = cnt_col.stack()cnt_col = cnt_col.reset_index()cnt_col['day'] = cnt_col['day'].map(lambda x : x+1)cnt_col1 = data.groupby(by=[col_name,'day','is_trade']).agg( 'size')cnt_col1 = cnt_col1.unstack(level=['is_trade','day'])cnt_col1 = cnt_col1[:][1]cnt_col1.fillna(0,inplace=True)cnt_col1 = cnt_col1.reindex_axis(sorted(cnt_col1.columns.tolist()), axis=1)cnt_col1 = cnt_col1.cumsum(axis=1)cnt_col1 = cnt_col1.stack()cnt_col1 = cnt_col1.reset_index()cnt_col1.columns = [col_name,'day',col_name+'_cntrate11']cnt_col1['day'] = cnt_col1['day'].map(lambda x: x+1)data = pd.merge(data,cnt_col,on=[col_name,'day'],how='left')data = pd.merge(data,cnt_col1,on=[col_name,'day'],how='left')#    base_name的单特征量cnt_base = data.groupby(by = [base_name,'day'])['is_trade'].agg({base_name+'_cnt':'count'})cnt_base = cnt_base.unstack()cnt_base.fillna(0,inplace=True)cnt_base = cnt_base.reindex_axis(sorted(cnt_base.columns),axis = 1)cnt_base = cnt_base.cumsum(axis = 1)cnt_base = cnt_base.stack()cnt_base = cnt_base.reset_index()cnt_base['day'] = cnt_base['day'].map(lambda x : x+1)cnt_base1 = data.groupby(by=[base_name,'day','is_trade']).agg( 'size')cnt_base1 = cnt_base1.unstack(level=['is_trade','day'])cnt_base1 = cnt_base1[:][1]cnt_base1.fillna(0,inplace=True)cnt_base1 = cnt_base1.reindex_axis(sorted(cnt_base1.columns.tolist()), axis=1)cnt_base1 = cnt_base1.cumsum(axis=1)cnt_base1 = cnt_base1.stack()cnt_base1 = cnt_base1.reset_index()cnt_base1.columns = [base_name,'day',base_name+'_cntrate11']cnt_base1['day'] = cnt_base1['day'].map(lambda x: x+1)data = pd.merge(data,cnt_base,on=[base_name,'day'],how='left')data = pd.merge(data,cnt_base1,on=[base_name,'day'],how='left')#    col_name+'_'+base_name+'_cross_cntrate11'data[col_name+'_'+base_name+'_cb'] = data[col_name+'_'+base_name+'_cross_cntrate11']/data[col_name+'_'+base_name+'_cnt']data[col_name+'_'+base_name+'_cb_c'] = data[col_name+'_'+base_name+'_cnt']/data[col_name+'_cnt']data[col_name+'_'+base_name+'_cb_b'] = data[col_name+'_'+base_name+'_cnt']/data[base_name+'_cnt']data[col_name+'_'+base_name+'_cb_c1'] = data[col_name+'_'+base_name+'_cross_cntrate11']/data[col_name+'_cntrate11']data[col_name+'_'+base_name+'_cb_b1'] = data[col_name+'_'+base_name+'_cross_cntrate11']/data[base_name+'_cntrate11']del data[col_name+'_'+base_name+'_cnt']del data[col_name+'_cnt']del data[base_name+'_cnt']del data[col_name+'_'+base_name+'_cross_cntrate11']del data[col_name+'_cntrate11']del data[base_name+'_cntrate11']return data

3.6其他一些效果不太好的特征

3.6.1对离散型特征字符串化,再累加的组合特征

比如user_gender_id='1',user_age_level='2'

那么组合特征'12'就代表着中年('2')女性('1')的含义。

忽然想到,有一个问题是代码只对特征做简单的LabelEncoding处理,假设第一个特征取值为1-2000,第二个特征取值为1-100,那么'2213'实际上可能有多种字符串拼接方式:

'2'+'213'

'22'+'13'

'221'+'3'

都是这一特征,也许这就是效果不好的原因吧,下次比赛的时候再试试。

def zuhe(data):'''Desr:输入:数据data1、使用preprocessing.LabelEncoder()使特征在一个小区间内2、转换int行特征为str3、两两字符型特征累加输出:字符串组合特征example:item_brand_id:'2'item_city_id:'1'zuhe_feature:21'''print('3.zuhe')print('-------------------把缺失值-1替换为0----------------------')
#    for col in ['user_gender_id','user_age_level','user_occupation_id','user_star_level']:
#        data[col] = data[col].apply(lambda x: 0 if x == -1 else x)print('-----------声明item,shop,user,hour四个块中的特征名----------')item_category_list_name = ['item_category_list'+str(i) for i in range(1,3)]item_property_list_name = ['item_property_list'+str(i) for i in range(19)]predict_category_property_name = ['predict_category_property'+str(i) for i in range(5)]item_name = ['item_sales_level', 'item_price_level', 'item_collected_level','item_pv_level','item_city_id','item_brand_id']item_name = item_name+item_category_list_name+item_property_list_name+predict_category_property_nameuser_name = ['user_gender_id','user_age_level','user_occupation_id','user_star_level']shop_name_old = ['shop_review_num_level','shop_review_positive_rate','shop_star_level','shop_score_service','shop_score_delivery','shop_score_description']id_name = ['user_id','item_id','shop_id','item_brand_id','item_city_id','context_page_id']
#    ui_name = user_name+item_name
#    si_name = shop_name + item_name
#    su_name = shop_name + user_namenew_name = []lbl = preprocessing.LabelEncoder()print('-------------------user_name的fit_transform------------------')for ucol in user_name:data[ucol] = lbl.fit_transform(data[ucol]).astype(str)print('-------------------item_name的fit_transform------------------------')for icol in item_name:data[icol] = lbl.fit_transform(data[icol]).astype(str)print('-------------------id_name的fit_transform------------------------')for idcol in id_name:data[idcol] = lbl.fit_transform(data[idcol]).astype(str)print('-------------------对shop进行分段------------------------')shop_name = []for scol in shop_name_old:data['fenduna_'+scol] = pd.cut(data[scol],10,labels=[str(i) for i in range(1,11)])shop_name.append('fenduna_'+scol)print('--------------------hour_astype(str)------------------------')data['hour'] = data['hour'].astype(str)print('-------------------user和item_id特征------------------------')for uicol in itertools.product(user_name,item_name):data[uicol[0]+'_'+uicol[1]] = lbl.fit_transform(data[uicol[0]]+data[uicol[1]])new_name.append(uicol[0]+'_'+uicol[1])'''*******user+shop很废*******'''
#    print('------------------user和shop特征-----------------------')
#    for sucol in itertools.product(shop_name,user_name):
#        data[sucol[0]+'_'+sucol[1]] = lbl.fit_transform(data[sucol[0]]+data[sucol[1]])
#        new_name.append(sucol[0]+'_'+sucol[1])  print('------------------item和shop特征-----------------------')for iscol in itertools.product(shop_name,item_name):data[iscol[0]+'_'+iscol[1]] = lbl.fit_transform(data[iscol[0]]+data[iscol[1]])new_name.append(iscol[0]+'_'+iscol[1]) '''*******id+user/item/shop很废*******'''
#    print('------------------id和user特征-----------------------')
#    for iducol in itertools.product(id_name,user_name):
#        data[iducol[0]+'_'+iducol[1]] = lbl.fit_transform(data[iducol[0]]+data[iducol[1]])
#        new_name.append(iducol[0]+'_'+iducol[1])
#    print('------------------id和item特征-----------------------')
#    for idicol in itertools.product(id_name,item_name):
#        data[idicol[0]+'_'+idicol[1]] = lbl.fit_transform(data[idicol[0]]+data[idicol[1]])
#        new_name.append(idicol[0]+'_'+idicol[1])
#    print('------------------id和shop特征-----------------------')
#    for idscol in itertools.product(id_name,item_name):
#        data[idscol[0]+'_'+idscol[1]] = lbl.fit_transform(data[idscol[0]]+data[idscol[1]])
#        new_name.append(idscol[0]+'_'+idscol[1]) print('--------------------id和hour特征------------------------')for ihcol in id_name:data[ihcol] = lbl.fit_transform(data[ihcol]).astype(str)data[ihcol+'_hour'] = lbl.fit_transform(data[ihcol]+data['hour'])
#        data[ihcol] = lbl.fit_transform(data[ihcol]).astype(int)
#        new_name.append(ihcol+'_hour')print('--------------------user和hour特征------------------------')for uhcol in user_name:
#        data[uhcol] = lbl.fit_transform(data[ihcol]).astype(str)data[uhcol+'_hour'] = lbl.fit_transform(data[uhcol]+data['hour']) print('--------------------item和hour特征------------------------')for ithcol in item_name:
#        data[uhcol] = lbl.fit_transform(data[ihcol]).astype(str)data[ithcol+'_hour'] = lbl.fit_transform(data[ithcol]+data['hour']) print('--------------------shop和hour特征------------------------')for shcol in shop_name:
#        data[uhcol] = lbl.fit_transform(data[ihcol]).astype(str)data[shcol+'_hour'] = lbl.fit_transform(data[shcol]+data['hour'])
#    print('------------------shop和item特征------------------------')
#    for scol in shop_name:
#        data[scol] = data[scol].astype(str)
#    for sicol in itertools.product(shop_name,item_name):
#        data[sicol[0]+'_'+sicol[1]] = lbl.fit_transform(data[sicol[0]]+data[sicol[1]])
#        new_name.append(sicol[0]+'_'+sicol[1])print('------------------把str换回int,---------')print('-------------------user_name的str_int------------------')for ucol in user_name:data[ucol] = data[ucol].astype(int)print('-------------------item_name的str_int------------------------')for icol in item_name:data[icol] = data[icol].astype(int)print('-------------------id_name的str_int------------------------')for idcol in id_name:data[idcol] = data[idcol].astype(int)print('-------------------shop的str_int------------------------')for scol in shop_name:data[scol] = data[scol].astype(int)print('--------------------hour的str_int------------------------')data['hour'] = data['hour'].astype(int)return data

3.6.2连续性变量的累加特征

对前面提到的4个shop类中的连续型特征进行累加,试过两两累加、三三累加。效果都不好。在这些都不好的组合形式里面,三三累加的效果是最好的。(PS:使用itertools里面的函数可以轻松写循环,就不要写两个for循环嵌套了)

shop_score_description、shop_score_delivery、

shop_score_service、shop_review_positive_rate

3.6.3基于前1小时、前一天的统计特征

前面统计的点击率和推送次数,都是历史数据到目前为止的点击率和推送次数。实际上时间具有衰退效应,所以前1小时、前1天的点击率(用户行为)也许是一个强特征。

3.6.4用户行为

既然提到用户行为,有位大佬提到过一个强特,用户上一次点击到这一次推送出现的时间。但是由这个强特可以扩展到其它的一些可以尝试的特征,用户上一次   被推送/点击   广告到这次  被推送/点击   广告的时间/天数。

时间所限,没有做尝试。

天池- IJCAI-18 阿里妈妈搜索广告转化预测新手入门经历(一:数据预处理、特征工程)相关推荐

  1. 2018年阿里妈妈搜索广告转化预测

    了解数据 提供了user,item,context,shop相关的数据 instance_id不作为特征,但是能看出来,实际上有重复instance_id的数据 item_id 全数据要比train多 ...

  2. 2篇CIKM详解阿里妈妈搜索广告CTR模型如何低碳瘦身

    作为<阿里妈妈搜索广告CTR模型的"瘦身"之路>的姊妹篇,本文将结合团队发表的 CIKM 2021 两篇论文,详解我们在模型瘦身之路上的延续性思考与实践.姊妹篇已经总结 ...

  3. 阿里妈妈搜索广告CTR模型的“瘦身”之路

    前言 随着号称"地表最强"的千亿参数规模GPT-3模型在 NLP 领域横扫各大数据榜单,大力出奇迹的暴力美学似乎成为了大数据场景建模的不二法门.搜索.推荐和广告场景的 CTR 模型 ...

  4. 一口气放出三篇SIGIR论文!详解阿里妈妈搜索广告CTR模型演进

    欢迎关注:阿里妈妈技术公众号 本文作者:石士 阿里妈妈技术团队​ 1 引子 点击率预估(a.k.a. CTR模型)在搜索.推荐和广告等互联网应用中扮演了至关重要的角色.随着深度学习技术的快速发展,CT ...

  5. 竞赛|数据竞赛Top解决方案开源整理-科大讯飞AI营销算法、阿里妈妈搜索广告、腾讯广告算法、搜狗的用户画像

    https://mp.weixin.qq.com/s/_4QG0dWhh784lF0n1wymcw

  6. IJCAI-18 阿里妈妈广告转化预测

    IJCAI-18 阿里妈妈搜索广告转化预测总结(0.13966,53/5204) 赛题内容 本次比赛以阿里电商广告为研究对象,提供了淘宝平台的海量真实交易数据,参赛选手通过人工智能技术构建预测模型预估 ...

  7. 【万字干获】阿里妈妈搜索推荐广告预估模型2021思考与实践

    省时查报告-专业.及时.全面的行研报告库 省时查方案-专业.及时.全面的营销策划方案库 知识图谱在美团推荐场景中的应用实践 搜索场景下的智能实体推荐 机器学习在B站推荐系统中的应用实践 小红书推荐系统 ...

  8. 阿里妈妈展示广告预估校准技术演进之路

    来源:DataFunTalk本文约6500字,建议阅读15分钟 本文将介绍校准算法在阿里妈妈展示广告中的应用和演进,将从背景介绍.校准算法演进.工程实践以及总结展望四个方面展开介绍. 分享嘉宾:黄思光 ...

  9. 代码开源!阿里妈妈展示广告Match底层技术架构最新进展

    作者:卓立.日涉.谨持 一.背景 大规模信息检索一直是搜推广领域的核心问题之一,而基于任意复杂模型的检索方案无疑是业界重要的迭代方向之一.近年来,阿里妈妈展示广告Match团队与预测引擎团队专注于从算 ...

最新文章

  1. Java知识积累——String引用的判断问题
  2. 使用 Pandas、Jinja 和 WeasyPrint,轻松创建一个 PDF 报表
  3. 课程 | 中科院教授带你快速入门机器学习
  4. 抖音日活用户破 6 亿,推荐系统到底有何魔力?
  5. 【UAV】陀螺仪数据分析,以维特智能 JY901B 为例
  6. torch.flatten()函数
  7. DCMTK:将XML文档的内容转换为DICOM结构的报告文件
  8. vagrant boxes
  9. Redis数据结构——跳跃表-skiplist
  10. 房地产税迟早要来,而且会带来房价小涨。
  11. 使用VC做一个简单的UI界面对话框
  12. 安信可nbiot模块_安信可无线模组
  13. 如何释放计算机的ip地址,电脑执行释放DNS和更新IP的命令是什么?怎么执行
  14. 从冬令营到字节跳动,我从ICPCer变身Bytedancer
  15. Discuz仿魔客吧模板/素材资源站模板/包含DIY文件
  16. MCtalk对话尚德机构:与教研和大数据结合的AI,才是真功夫
  17. vue 点击按钮筛选功能_vue实现前端列表多条件筛选
  18. 石油大P14040存在
  19. Java Web之Servlet的三大常用作用域对象及其使用方法
  20. 分销小程序系统开发经营模式介绍

热门文章

  1. Oracle提高命中率及优化
  2. 多层卷积后感受野的计算
  3. 苹果手机计算机怎样拉到桌面,苹果手机怎样才能快速投屏到电脑屏幕上
  4. linux php7.4,PHP 7.4登陆Ubuntu 20.04 LTS
  5. git提交如何忽略某些文件
  6. 现在的你迷茫吗?是否还在做毕业后的高薪梦?你相信彩虹海吗?
  7. 浅析 - 阿里巴巴专家教你坚持写作
  8. 交易风云-MAM、PAMM、社区交易&KlipC:如何选择多账户管理系统
  9. 华为云-文字识别OCR-身份证识别
  10. Python基础教程(第3版)读书笔记:第2章 列表和元组