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

第一次正式参加数据挖掘类的比赛,投入了三个星期。结果没有进入复赛,但是学到了许多经验。感谢技术圈和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.day
    data['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为例&

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值