深度推薦模型包DeepCTR

DeepCTR包主要是對目前的一些“基於深度學習的點擊率預測算法”進行了實現,官方文檔參考
本文主要記錄DeepFM算法的相關操作細節。

實驗數據

prefix:用戶輸入(query前綴)
query_prediction:預測的用戶完整需求查詢詞,最多10條;預測的查詢詞可能是前綴本身,數字爲統計概率
title:文章標題
tag:文章類型
label:是否點擊0/1

import pandas as pd
import numpy as np
import lightgbm as lgb
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import f1_score

train_data = pd.read_table('./data/oppo_round1_train_20180929.txt', 
        names= ['prefix','query_prediction','title','tag','label'], header= None, encoding='utf-8').astype(str)
print(train_data.shape)
val_data = pd.read_table('./data/oppo_round1_vali_20180929.txt', 
        names = ['prefix','query_prediction','title','tag','label'], header = None, encoding='utf-8').astype(str)
print(val_data.shape)

# O:(1999999, 5)
# O:(50000, 5)
vctr = train_data['label'].value_counts()   #可以看到標籤異常值和樣本不均衡
vcvl = val_data['label'].value_counts() 
vctr[0]/vctr[1], vcvl[0]/vcvl[1]

# O:(1.6875350690893836, 1.690341673392521)
train_data = train_data[train_data['label'] != '音樂' ]

train_data = pd.concat([train_data,val_data])   #把train和val集合拼接在一起
train_data['label'] = train_data['label'].apply(lambda x: int(x))
items = ['prefix', 'title', 'tag']   #query前綴、文章標題、文章類型

for item in items:   #分別按各item列分組 按label取值0/1 統計搜索次數、點擊次數、點擊率
    temp = train_data.groupby(item, as_index = False)['label'].agg({item+'_click':'sum', item+'_count':'count'})
    temp[item+'_ctr'] = temp[item+'_click']/(temp[item+'_count'])
    train_data = pd.merge(train_data, temp, on=item, how='left')
for i in range(len(items)):
    for j in range(i+1, len(items)):
        item_g = [items[i], items[j]]   #三選二,作爲分組指標
        temp = train_data.groupby(item_g, as_index=False)['label'].agg({'_'.join(item_g)+'_click': 'sum','_'.join(item_g)+'count':'count'})
        temp['_'.join(item_g)+'_ctr'] = temp['_'.join(item_g)+'_click']/(temp['_'.join(item_g)+'count']+3)
        train_data = pd.merge(train_data, temp, on=item_g, how='left')
from sklearn import preprocessing
import time

# 轉換tag
encoder = preprocessing.LabelEncoder()
train_data['tag'] = encoder.fit_transform(train_data['tag'])
encoder = preprocessing.LabelEncoder()
train_data['prefix'] = encoder.fit_transform(train_data['prefix'])
encoder = preprocessing.LabelEncoder()
train_data['title'] = encoder.fit_transform(train_data['title'])
train_data_ = train_data.drop(['query_prediction'], axis = 1)

dense_features = ['prefix_click', 'prefix_count', 'prefix_ctr', 
                   'title_click', 'title_count', 'title_ctr',
                   'tag_click', 'tag_count', 'tag_ctr', 
                   'prefix_title_click', 'prefix_titlecount', 'prefix_title_ctr', 
                   'prefix_tag_click', 'prefix_tagcount', 'prefix_tag_ctr', 
                   'title_tag_click', 'title_tagcount', 'title_tag_ctr']   #類別型特徵
sparse_features = ['prefix', 'title', 'tag']   #數值型特徵
train_data_[sparse_features] = train_data_[sparse_features].fillna('-1', )
train_data_[dense_features] = train_data_[dense_features].fillna(0, )

target = ['label']
from sklearn.metrics import log_loss, roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, MinMaxScaler

for feat in sparse_features:
    lbe = LabelEncoder()
    train_data_[feat] = lbe.fit_transform(train_data_[feat])   #將類別轉化成id編碼
    
mms = MinMaxScaler(feature_range=(0, 1))
train_data_[dense_features] = mms.fit_transform(train_data_[dense_features])
train_data_.head()

在這裏插入圖片描述

from deepctr.models import DeepFM
from deepctr.inputs import  SparseFeat, DenseFeat, get_feature_names

fixlen_feature_columns = [SparseFeat(feat, vocabulary_size=train_data_[feat].nunique(),embedding_dim=4)
                       for i,feat in enumerate(sparse_features)] + [DenseFeat(feat, 1,)
                      for feat in dense_features]

dnn_feature_columns = fixlen_feature_columns   #類別型特徵DNN
linear_feature_columns = fixlen_feature_columns   #連續型特徵線性FM

feature_names = get_feature_names(linear_feature_columns + dnn_feature_columns)
train, test = train_test_split(train_data_, test_size=0.2)
train_model_input = {name:train[name] for name in feature_names}   #每項index:該列取值
test_model_input = {name:test[name] for name in feature_names}
model = DeepFM(linear_feature_columns, dnn_feature_columns, task='binary')
model.compile("adam", "binary_crossentropy", metrics=['binary_crossentropy'], )

history = model.fit(train_model_input, train[target].values,
                    batch_size=256, epochs=10, verbose=2, validation_split=0.2, )

在這裏插入圖片描述

from sklearn.metrics import f1_score

pred_ans = model.predict(test_model_input, batch_size=256)
f1_score(test[target].values, np.where(pred_ans>0.5, 1, 0))

# O:0.7944898855019384
特徵

類別特徵embedding:(1)FM二階項(2)DNN網絡
連續值特徵:FM一階項

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章