前言
最近在看一些比賽的分享,看看別人是如何做的,就關注到了推薦預測的一篇文章,想學習一些,看看他們是如何實現的,關於構造特徵、預測模型等等。其中比賽是kaggle的一個推薦比賽“Click-Through Rate Prediction”,比賽較早,5年前的比賽,拿來練習還是可以的,
用戶特徵
廣告點擊中,廣告跟用戶之間應該有關聯,但是本比賽中沒有,所以需要構造一個用戶特徵,其中文章中就用:
user_id = device_id + _device_ip + _device_model
data['user_id'] = data['device_id'] + '_' + data['device_ip']+ '_' + data['device_model']
這三個特徵構造成用戶特徵。
廣告特徵
這裏並沒有廣告id的標識,不清楚那些投放渠道是同一個廣告id,文章中將app_id作爲一個廣告特徵,認爲一類APP中的廣告是一樣的,暫不論此方法是否合理有效。繼續來看接下來如何。
用戶與廣告的統計特徵
1、時間特徵處理
將時間特徵提取出四個特徵,分別是日期、星期、小時、距離最開始的日期的時間差。
from datetime import datetime
data['hour']=data['hour'].map(lambda x: datetime.strptime(str(x),"%y%m%d%H"))
data['dayoftheweek']=data['hour'].map(lambda x: x.weekday())
data['day']=data['hour'].map(lambda x: x.day)
data['hour']=data['hour'].map(lambda x: x.hour)
data['time']=(data['day'].values - data['day'].min()) * 24 + data['hour'].values
2、用戶特徵
- 用戶每天在某個app上出現的次數:user_id + ‘-’ + time
- 用戶每個小時,每天出現的次數:user_id + ‘-’ + time + ‘-’ +app_id
- 用戶距離上一次出現的時間差
## 用戶每天/每小時在某個app上出現的次數
for time in ['day','time']:
print('user_id_'+time +'_app')
data['user_id_'+time +'_app'] = data['user_id'] + '_' + data[time].astype(str) + '_' + data['app_id'].astype(str)
dic_ = data['user_id_'+time +'_app'].value_counts().to_dict()
data['user_id_'+time +'_app_count'] = data['user_id_'+time +'_app'].apply(lambda x: dic_[x])
data.drop('user_id_'+time +'_app', axis=1,inplace = True)
## 用戶每個小時,每天出現的次數
for time in ['day','time']:
print('user_id_'+time)
data['user_id_'+time] = data['user_id'] + '_' + data[time].astype(str)
dic_ = data['user_id_'+time].value_counts().to_dict()
data['user_id_'+time +'_count'] = data['user_id_'+time].apply(lambda x: dic_[x])
data.drop('user_id_'+time, axis=1,inplace = True)
data['user_to_lasttime'] = data.groupby('user_id')['time'].diff().values
3、標籤化特徵
對於一些object對象,採取標籤化的處理方式,用數字來表示該特徵。不過用這種方式也有缺點,有一篇博客中提到了數值化特徵的問題:數據清洗遇到的問題思考。
from sklearn.preprocessing import LabelEncoder
for col in data.columns:
if col!='id' and col!='click':
if data[col].dtypes == 'O':
print(col)
data[col+'_labelencode'] = LabelEncoder().fit_transform(data[col].values)
這裏通過類型來判斷,不過一般可以標籤化的特徵也不會太多,這裏最好通過EDA來看下數據分佈情況,不然不能光憑藉類型來決定是否標籤化。
關於模型訓練
這裏沒有特殊處理,因爲“click” 值是0/1值,0表示用戶沒有點擊,1表示用戶點擊了,所以就直接用來表示作爲樣本標籤值訓練模型。