如何将数值和嵌入序列模型合并处理RNN中的类别

我想为我的类别特征构建一个带有嵌入的一层LSTM模型。我目前有数值特征和一些类别特征,例如位置,由于计算复杂性,无法进行独热编码,例如使用pd.get_dummies(),这本来是我最初打算做的。

让我们看一个例子:

样本数据

data = {    'user_id': [1,1,1,1,2,2,3],    'time_on_page': [10,20,30,20,15,10,40],    'location': ['London','New York', 'London', 'New York', 'Hong Kong', 'Tokyo', 'Madrid'],    'page_id': [5,4,2,1,6,8,2]}d = pd.DataFrame(data=data)print(d)   user_id  time_on_page   location  page_id0        1            10     London        51        1            20   New York        42        1            30     London        23        1            20   New York        14        2            15  Hong Kong        65        2            10      Tokyo        86        3            40     Madrid        2

让我们来看一个人访问网站的情况。我正在跟踪页面上的时间等数值数据。类别数据包括:位置(超过1000个唯一值)、页面ID(超过1000个唯一值)、作者ID(100多个唯一值)。最简单的解决方案是将所有内容进行独热编码,并将其放入具有可变序列长度的LSTM中,每个时间步对应于不同的页面查看。

上面的DataFrame将生成7个训练样本,具有可变的序列长度。例如,对于user_id=2,我将有2个训练样本:

[ ROW_INDEX_4 ] and [ ROW_INDEX_4, ROW_INDEX_5 ]

X为训练数据,让我们看第一个训练样本X[0]

enter image description here

从上图可以看出,我的类别特征是X[0][:, n:]

在创建序列之前,我使用pd.factorize()将类别变量因子化为[0,1... number_of_cats-1],因此X[0][:, n:]中的数据是与其索引对应的数字。

我是否需要为每个类别特征分别创建一个Embedding?例如,为每个x_*n, x_*n+1, ..., x_*m创建一个嵌入?

如果是的话,我如何将这些内容放入Keras代码中呢?

model = Sequential()model.add(Embedding(?, ?, input_length=variable)) # 我如何将数据输入到这个嵌入中?只有类别输入。model.add(LSTM())model.add(Dense())model.add.Activation('sigmoid')model.compile()model.fit_generator() # 适应变长序列的`X[i]`一个接一个地进行训练。

我的解决方案想法:

看起来像这样:

enter image description here

我可以为每个单一的类别特征(m-n)训练一个Word2Vec模型,以向量化任何给定的值。例如,伦敦将在3个维度上被向量化。假设我使用3维嵌入。然后我会将所有内容放回X矩阵中,现在它将有n + 3(n-m),并使用LSTM模型来训练它?

我只是觉得应该有更简单/更智能的方法。


回答:

如您所述的一个解决方案是,对类别数据进行独热编码(甚至按原样使用,以索引为基础的格式),并将其与数值数据一起输入到LSTM层。当然,您也可以在这里使用两个LSTM层,一个用于处理数值数据,另一个用于处理类别数据(以独热编码格式或索引基础格式),然后合并它们的输出。

另一个解决方案是为每个类别数据设置一个单独的嵌入层。每个嵌入层可以有自己的嵌入维度(如上所述,您可以有多个LSTM层分别处理数值和类别特征):

num_cats = 3 # 类别特征的数量n_steps = 100 # 每个样本中的时间步数n_numerical_feats = 10 # 每个样本中的数值特征数量cat_size = [1000, 500, 100] # 每个类别特征中的类别数量cat_embd_dim = [50, 10, 100] # 每个类别特征的嵌入维度numerical_input = Input(shape=(n_steps, n_numerical_feats), name='numeric_input')cat_inputs = []for i in range(num_cats):    cat_inputs.append(Input(shape=(n_steps,1), name='cat' + str(i+1) + '_input'))cat_embedded = []for i in range(num_cats):    embed = TimeDistributed(Embedding(cat_size[i], cat_embd_dim[i]))(cat_inputs[i])    cat_embedded.append(embed)    cat_merged = concatenate(cat_embedded)cat_merged = Reshape((n_steps, -1))(cat_merged)merged = concatenate([numerical_input, cat_merged])lstm_out = LSTM(64)(merged)model = Model([numerical_input] + cat_inputs, lstm_out)model.summary()

Related Posts

Flatten and back keras

我正在尝试使用自编码器获取简单向量中的值 这是我的代码…

如何按索引访问PyTorch模型参数

如果我的网络有10层,包括偏置项,如何仅通过索引访问第…

Python中多元逻辑回归显示错误

我试图使用逻辑回归进行预测,并使用Python和skl…

在MACOS上安装NLTK

我在我的2015款Mac Pro上尝试安装NLTK,操…

如何在R中将通过RFE选择的变量插入到机器学习模型中?

我想使用递归特征消除方法来选择最重要的特征,然后将这些…

CountVectorizer 错误:ValueError: setting an array element with a sequence

我有一个包含144条学生反馈的数据集,其中有72条正面…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注