如何在KERAS中将多个序列设置为特征

cnjp1d6j  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(114)

bounty还有4天到期。回答此问题可获得+100声望奖励。taga正在寻找来自信誉良好来源的答案:如何将POS_TAG作为特征添加到NER模型中?

word2index = list(set(df[“words”].tolist())word2index.append('ENDPAD ')num_words = len(list(set(word2index)))word2index = {word:index + 1 for index,word in enumerate(word2index)} postag2index = list(set(df[“pos_tag”].tolist()))num_postag = len(list(set(postag2index)))postag2index = {word:index for index,word in enumerate(postag2index)}
tag2index = list(set(df[“tag”].tolist()))num_tags = len(list(set(tag2index)))tag2index = {word:index for index,word in enumerate(tag2index)}
我有这3个字典,我知道如何使模型工作良好,如果我只有一个功能/序列(字),但如何添加更多的功能,例如POS_TAG?
我想使用Keras创建命名实体识别模型。这些是我遵循的链接:
https://valueml.com/named-entity-recognition-using-lstm-in-keras/https://djajafer.medium.com/named-entity-recognition-and-classification-with-keras-4db04e22503d
数据看起来像这样:

word label
0          Thousands     O
1                 of     O
2      demonstrators     O
3               have     O
4            marched     O
...              ...   ...
44187          there     O
44188   accidentally     O
44189             or     O
44190   deliberately     O
44191              .     O

他们使用单词到向量,所以他们索引单词和标签,所以X是我的特征(单词的索引序列),y是我的结果(标签的索引序列):

max_len = 30
X = [[word2idx[w[0]] for w in s] for s in list_of_sentances]
X = pad_sequences(maxlen=max_len, sequences=X, padding="post", value=num_words-1)

y = [[label2idx[w[1]] for w in s] for s in list_of_sentances]
y = pad_sequences(maxlen=max_len, sequences=y, padding="post", value=label2idx["O"])
y = [to_categorical(i, num_classes=num_labels) for i in y]

但是如果我有这样的数据集:

这里我有另一个列,那就是POS。我如何将POS列的值添加到我的特征中?所以基本上,我不希望在我的X中只有word值,我还希望在我的X中有POS值。*(或任何其他值)如果我有多个列,例如:

word
POS
is_capital_letter
word_length

...
如何将所有这些列添加到功能中?
这是我的模型:X = np.array(X)y = np.array(y)

x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=1)

print("x_train shape", x_train.shape)
print("x_test shape", x_test.shape)
#x_train shape (750, 75)
#x_test shape (250, 75)

input_word = Input(shape=(max_len,))

model = Embedding(input_dim = vocab_len+1, output_dim = 75, input_length = max_len)(input_word)
model = SpatialDropout1D(0.25)(model)
model = Bidirectional(LSTM(units = 25, return_sequences=True, recurrent_dropout = 0.2))(model)
out = TimeDistributed(Dense(num_labels, activation = "softmax"))(model)

model = Model(input_word, out)
um6iljoc

um6iljoc1#

Keras中的LSTM层期望在[samples,timesteps,features]维度上输入。

  • 样本通常是独立的观察。在你的例子中,我假设这些是句子。
  • 时间步长是连续输入给模型的独立输入变量,应该是一个句子中的单词。
  • 特征是对一个观察的单独测量,也就是一个单词的特征。

在创建X的行中,您对句子和单词进行交互,并转换“单个”特征(word),假设w包含数据集中的一行([wordlabel])。
假设你有多个特征作为数据集中的前n列(目标是最后一列,例如 [word,POS,is_capital_letter,word_length,...,label]),并且你已经以与数据集中相同的顺序在transforms中收集/定义了必要的“transform”字典,那么你可以如下生成输入和目标:

transforms = (word2idx, pos2idx, ...)

X = [[[transforms[i][w[i]]] for i in range(n)] for w in s] for s in list_of_sentances]
Y = [[label2idx[w[n]] for w in s] for s in list_of_sentances]

当然,如果你有数字或其他类型的特征,那么你应该使用其他方法进行转换,而不是 * word 2 idx pos 2 idx *,... dicts,例如MinMaxScaling for word length等。
Padding也适用于新的X和Y,但它使用相同的扩展每个特征,长度为max_len。根据每个特征的替换值,很可能在这里使用精心制作的填充。

相关问题