第一次正式参加数据挖掘类的比赛,投入了三个星期。结果没有进入复赛,但是学到了许多经验。感谢技术圈和github的大佬们提供的baseline,让我少走了很多弯路。
第一次写博客,其一为了防止以后忘记,其二如果 能帮到萌新们也是很开心啦。
思路:全文按照数据预处理、特征工程和模型融合讲解,并附有代码。
数据预处理
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读取测试集和训练集:
分析数据时会发现训练集中有少量样本'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、数据预处理
文本类特征处理
数据有3个文本类型特征item_category_list、item_property_list和predict_category_property,使用split分割。item_property_list特征有100个字段,各字段之间无从属关系,由于后面字段缺失值太多,所以取range(19)
predict_category_property特征有14个字段,有从属关系,缺失值太多取range(5)
并使用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 ''))
时间戳处理
数据中的时间是以时间戳形式存在,进行如下处理提取日期和时间
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.day data['hour'] = data['realtime'].dt.hour
特征工程
长度特征
每条样本的3个文本特征的长度不一样,其中也许包含了一些信息。例如商品的属性列表很详细,可能是比较精细的产品,例如电脑和显卡两种商品,电脑参数包括CPU/显卡/内存等多项信息,显然比显卡复杂。
因此长度特征可以描述商品的种类。
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(';')))
基于商店质量的shop分段特征
shop中有4个连续型特征:shop_score_description、shop_score_delivery、
shop_score_service、shop_review_positive_rate
以shop_score_description为例,一条样本的取值是4.9632654,我们期望得知这个取值在总体样本中得分是处于什么样的一个水平。就需要进行分段,代码中0,1,2代表较差、一般、优秀3个等级。
分段还有一个好处就是可以和其他特征进行组合,后面会提到。
data['shop_score_description0'] = data[' '].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)
基于历史点击率的分段特征
以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 1 elif ((x>=3)&(x<=5))|(x==23): return 2 else: 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日后面的用户的行为的。
所以说,这种带有穿越性的特征十分容易导致过拟合,相当于拿着试卷答案在做试卷。在后面的统计特征中更要注意这一点。
基于点击率的特征
如果我们能够知道某件商品以前的点击率。极端点说,如果有一个特征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)
基于组合特征的点击率特征
该特征统计的是两个特征组合起来的历史点击率和推送次数。
例如:'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
这里有两个小问题
(1)如何组合特征
特征可以分为三大类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输出重要度时可以发现第二种组合更优秀。
def get_all_cross_cnt(data): ''' Descr:输入:数据data,统计函数get_cnt(data,col_name,base_name) 需要统计的特征列表(此处函数内部已定义) 输出:包含两两组合特征的历史点击率、历史推送次数的data ''' item_name_level = [ 'item_id', 'context_page_id', 'item_sales_level', 'item_price_level', 'item_collected_level','item_pv_level','item_brand_id','item_city_id'] user_name = [ 'user_id', 'user_gender_id','user_age_level','user_occupation_id','user_star_level' ] shop_name = [ 'shop_id', 'shop_review_num_level','shop_star_level', # 'shop_review_positive_rate0','shop_score_service0','shop_score_delivery0','shop_score_description0', 'normal_shop' ] all_name = item_name_level+user_name+shop_name+['hour' # ,'hour1','hour2' ] count = 0 for i in itertools.permutations(all_name,2): data = get_cross_cnt2(data,i[0],i[1]) count = count+1 print count return data all_name = item_name_level+user_name+shop_name+['hour' # ,'hour1','hour2' ] count = 0 for i in itertools.permutations(all_name,2): data = get_cross_cnt2(data,i[0],i[1]) count = count+1 print count return data
(2)统计组合特征时还可以统计的一些信息
对于两个特征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]点击次数 / [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
其他一些效果不太好的特征:
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:输入:数据data 1、使用preprocessing.LabelEncoder()使特征在一个小区间内 2、转换int行特征为str 3、两两字符型特征累加 输出:字符串组合特征 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_name user_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_name new_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
2、连续性变量的累加特征
对前面提到的4个连续型特征进行累加,试过两两累加、三三累加。效果都不好
shop_score_description、shop_score_delivery、
shop_score_service、shop_review_positive_rate