模型简介
Wide&Deep模型是由谷歌于2016年提出,并在Google Play store的场景中成功落地。模型特点是由wide部分为模型提供记忆能力,由deep部分提供泛化能力
解决的痛点:
传统的DNN(Deep Neural Networks,深度神经网络)能将高维稀疏特征编码为低维稠密的Embedding vector,这种基于Embedding的方式能够有效提高模型的泛化能力。但是,基于Embedding的方式可能因为数据长尾分布,导致长尾的一些特征值无法被充分学习,其对应的Embedding vector是不准确的,这便会造成模型泛化过度(过拟合)。
模型结构
如下图所示,模型由wide和deep两部分构成
(图1)
wide
上文简介部分我们提到,该部分为模型提供记忆能力–通过特征叉乘对原始特征做非线性变换,输入为高维度的稀疏向量。通过大量的特征叉乘产生特征相互作用的“记忆(Memorization)”
数学原理:
其中Cki是一个布尔变量,当第i个特征属于第k个特征组合Φk时,Cki值为1,否则为0,Xi是第i个特征的值,当Cki和Xi值1都为1时,结果才为1
例如特征组合"AND(gender=female, language=en)",如果对应的特征“gender=female” 和“language=en”都符合,则对应的交叉积变换层结果才为1,否则为0。
Deep
该部分主要是一个Embedding+MLP的神经网络模型(如图1)。大规模稀疏特征通过embedding转化为低维密集型特征。然后特征进行拼接输入到MLP中,挖掘藏在特征背后的数据模式。
模型代码(主要基于TensorFlow)
import warnings
warnings.filterwarnings("ignore")
import itertools
import pandas as pd
import numpy as np
from tqdm import tqdm
from collections import namedtuple
import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, LabelEncoder
from utils import SparseFeat, DenseFeat, VarLenSparseFeat
# 简单处理特征,包括填充缺失值,数值处理,类别编码
def data_process(data_df, dense_features, sparse_features):
data_df[dense_features] = data_df[dense_features].fillna(0.0)
for f in dense_features:
data_df[f] = data_df[f].apply(lambda x: np.log(x+1) if x > -1 else -1)
data_df[sparse_features] = data_df[sparse_features].fillna("-1")
for f in sparse_features:
lbe = LabelEncoder()
data_df[f] = lbe.fit_transform(data_df[f])
return data_df[dense_features + sparse_features]
def build_input_layers(feature_columns):
# 构建Input层字典,并以dense和sparse两类字典的形式返回
dense_input_dict, sparse_input_dict = {
}, {
}
for fc in feature_columns:
if isinstance(fc, SparseFeat):
sparse_input_dict[fc.name] = Input(shape=(1, ), name=fc.name)
elif isinstance(fc, DenseFeat):
dense_input_dict[fc.name] = Input(shape=(fc.dimension, ), name=fc.name)
return dense_input_dict, sparse_input_dict
def build_embedding_layers(feature_columns, input_layers_dict