tokenize(Tokenize函数)

笑笑 23 0

<a href="https://www.fskening.cn/tags/1938.html">tokenize</a>(Tokenize函数) if j in w2v:
values+=w2v[j]
k+=1
if k > 0:
x[i,:]=values/k
else: non+=1
y=LabelEncoder().fit_transform(data['category'].values)
msk=np.random.rand(len(data)) < 0.8
X_train,y_train,X_test,y_test=x[msk],y[msk],x[~msk],y[~msk]
#Train the model
lr=LogisticRegression().fit(X_train,y_train)
lr.score(X_test,y_test)

我们的基线 average Word2Vec 模型抵达了 68% 的准确率。这很不错了,那么让我们来看一看能不能做得更好。


average Word2Vec 方法有两个弱点:它是词袋模型(bag-of-words model),与单词次第相关,一切单词都具有相同的权重。为了停止句子表征,我们将在下面的方法中使用 RNN 架构处置这些效果。


自编码器


自编码器是一种无监视深度进修模型,它试图将自己的输入复制到输入。自编码器的技巧在于中间隐藏层的维度要低于输入数据的维度。所以这种神经网络必需以一种聪明、松懈的方式来表征输入,以完成胜利的重建。在很多状况下,使用自编码器停止特征提取被证明是十分有效的。



我们的自编码器是一个冗杂的序列到序列结构,由一个输入层、一个嵌入层、一个 LSTM 层,以及一个 softmax 层组成。整个结构的输入和输入都是标题,我们将使用 LSTM 的输进去表征标题。在取得自编码器的表征之后,我们将使用 logistics 回归来预测类别。为了获得更多的数据,我们会使用文章中一切句子来锻炼自编码器,而不是仅仅使用文章标题。


#parse all sentences
sentenses=[]
for i in data['body'].values:
for j in nltk.sent_tokenize(i):
sentenses.append(j)
#preprocess for keras
num_words=2000
maxlen=20
tokenizer=Tokenizer(num_words=num_words, split=' ')
tokenizer.fit_on_texts(sentenses)
seqs=tokenizer.texts_to_sequences(sentenses)
pad_seqs=[]
for i in seqs:
if len(i)>4:
pad_seqs.append(i)
pad_seqs=pad_sequences(pad_seqs,maxlen)
#The model
embed_dim=150
latent_dim=128
batch_size=64
#### Encoder Model ####
encoder_inputs=Input(shape=(maxlen,), name='Encoder-Input')
emb_layer=Embedding(num_words, embed_dim,input_length=maxlen, name='Body-Word-Embedding', mask_zero=False)
# Word embeding for encoder (ex: Issue Body)
x=emb_layer(encoder_inputs)
state_h=GRU(latent_dim, name='Encoder-Last-GRU')(x)
encoder_model=Model(inputs=encoder_inputs, outputs=state_h, name='Encoder-Model')
seq2seq_encoder_out=encoder_model(encoder_inputs)
#### Decoder Model ####
decoded=RepeatVector(maxlen)(seq2seq_encoder_out)
decoder_gru=GRU(latent_dim, return_sequences=True, name='Decoder-GRU-before')
decoder_gru_output=decoder_gru(decoded)
decoder_dense=Dense(num_words, activation='softmax', name='Final-Output-Dense-before')
decoder_outputs=decoder_dense(decoder_gru_output)
#### Seq2Seq Model ####
#seq2seq_decoder_out=decoder_model([decoder_inputs, seq2seq_encoder_out])
seq2seq_Model=Model(encoder_inputs,decoder_outputs )
seq2seq_Model.compile(optimizer=optimizers.Nadam(lr=0.001), loss='sparse_categorical_crossentropy')
history=seq2seq_Model.fit(pad_seqs, np.expand_dims(pad_seqs, -1),
batch_size=batch_size,
epochs=5,
validation_split=0.12)
#Feature extraction
headlines=tokenizer.texts_to_sequences(data['headline'].values)
headlines=pad_sequences(headlines,maxlen=maxlen)x=encoder_model.predict(headlines)
#classifier
X_train,y_train,X_test,y_test=x[msk],y[msk],x[~msk],y[~msk]
lr=LogisticRegression().fit(X_train,y_train)
lr.score(X_test,y_test)

我们完成了 60% 的准确率,比基线模型要差一些。我们可以经过优化超参数、增加锻炼 epoch 数量大约在更多的数据上锻炼模型,来改良该分数。


言语模型


我们的第二个方法是锻炼言语模型来表征句子。言语模型描画的是某种言语中一段文本具有的概率。例如,「我喜欢吃香蕉」(I like eating bananas)这个句子会比「我喜欢吃卷积」(I like eating convolutions)这个句子具有更高的具有概率。我们经过火割 n 个单词组成的窗口以及预测文本中的下一个单词来训练言语模型。你能够在这里了解到更多基于 RNN 的言语模型的方式:http://karpathy.github.io/2015/05/21/rnn-effectiveness/。经过树立语言模型,我们了解了「旧事英语」(journalistic English)是如何树立的,并且模型应当聚焦于主要的单词及其表征。



我们的架构和自编码器的架构是相似的,但是我们只预测一个单词,而不是一个单词序列。输入将包括由旧事文章中的 20 个单词组成的窗口,标签是第 21 个单词。在训练完语言模型之后,我们将从 LSTM 的输出隐藏外形中失掉标题表征,然后运转 logistics 回归模型来预测类别。


#Building X and Y
num_words=2000
maxlen=20
tokenizer=Tokenizer(num_words=num_words, split=' ')
tokenizer.fit_on_texts(df['body'].values)
seqs=tokenizer.texts_to_sequences(df['body'].values)
seq=[]
for i in seqs:
seq+=i
X=[]
Y=[]
for i in tqdm(range(len(seq)-maxlen-1)):
X.append(seq[i:i+maxlen])
Y.append(seq[i+maxlen+1])
X=pd.DataFrame(X)
Y=pd.DataFrame(Y)
Y[0]=Y[0].astype('category')
Y=pd.get_dummies(Y)
#Buidling the network
embed_dim=150
lstm_out=128
batch_size=128
model=Sequential()
model.add(Embedding(num_words, embed_dim,input_length=maxlen))
model.add(Bidirectional(LSTM(lstm_out)))
model.add(Dense(Y.shape[1],activation='softmax'))
adam=Adam(lr=0.001, beta_1=0.7, beta_2=0.99, epsilon=None, decay=0.0, amsgrad=False)
model.compile(loss='categorical_crossentropy', optimizer=adam)
model.summary()
print('fit')
model.fit(X, Y, batch_size=batch_size,validation_split=0.1, epochs=5, verbose=1)
#Feature extraction
headlines=tokenizer.texts_to_sequences(data['headline'].values)
headlines=pad_sequences(headlines,maxlen=maxlen)
inp=model.input
outputs=[model.layers[1].output]
functor=K.function([inp]+ [K.learning_phase()], outputs )
x=functor([headlines, 1.])[0]
#classifier
X_train,y_train,X_test,y_test=x[msk],y[msk],x[~msk],y[~msk]
lr=LogisticRegression().fit(X_train,y_train)
lr.score(X_test,y_test)

这一次我们失掉了 72% 的精确率,要比基线模型好一些,那我们能否让它变得更好呢?


Skip-Thought 向量模型


在 2015 年关于 skip-thought 的论文《Skip-Thought Vectors》中,作者从语言模型中获得了十分的直觉知识。但是,在 skip-thought 中,我们并没有预测下一个单词,而是预测之前和之后的句子。这给模型关于句子的更多语境,所以,我们能够树立更好的句子表征。您可以阅读这篇博客(https://medium.com/@sanyamagarwal/my-thoughts-on-skip-thoughts-a3e773605efa),了解关于这个模型的更多音讯。



skip-thought 论文中的例子(https://arxiv.org/abs/1506.06726)


我们将结构一个相似于自编码器的序列到序列构造,但是它与自编码器有两个主要的区别。第一,我们有两个 LSTM 输出层:一个用于之前的句子,一个用于下一个句子;第二,我们会在输出 LSTM 中使用教员志愿(teacher forcing)。这意味着我们不只仅给输出 LSTM 提供了之前的隐藏外形,还提供了实际的前一个单词(可在上图和输出最后一行中检查输入)。


#Build x and y
num_words=2000
maxlen=20
tokenizer=Tokenizer(num_words=num_words, split=' ')
tokenizer.fit_on_texts(sentenses)
seqs=tokenizer.texts_to_sequences(sentenses)
pad_seqs=pad_sequences(seqs,maxlen)
x_skip=[]
y_before=[]
y_after=[]
for i in tqdm(range(1,len(seqs)-1)):
if len(seqs[i])>4:
x_skip.append(pad_seqs[i].tolist())
y_before.append(pad_seqs[i-1].tolist())
y_after.append(pad_seqs[i+1].tolist())
x_before=np.matrix([[0]+i[:-1] for i in y_before])
x_after=np.matrix([[0]+i[:-1] for i in y_after])
x_skip=np.matrix(x_skip)
y_before=np.matrix(y_before)
y_after=np.matrix(y_after)
#Building the model
embed_dim=150
latent_dim=128
batch_size=64
#### Encoder Model ####
encoder_inputs=Input(shape=(maxlen,), name='Encoder-Input')
emb_layer=Embedding(num_words, embed_dim,input_length=maxlen, name='Body-Word-Embedding', mask_zero=False)
x=emb_layer(encoder_inputs)
_, state_h=GRU(latent_dim, return_state=True, name='Encoder-Last-GRU')(x)
encoder_model=Model(inputs=encoder_inputs, outputs=state_h, name='Encoder-Model')
seq2seq_encoder_out=encoder_model(encoder_inputs)
#### Decoder Model ####
decoder_inputs_before=Input(shape=(None,), name='Decoder-Input-before') # for teacher forcing
dec_emb_before=emb_layer(decoder_inputs_before)
decoder_gru_before=GRU(latent_dim, return_state=True, return_sequences=True, name='Decoder-GRU-before')
decoder_gru_output_before, _=decoder_gru_before(dec_emb_before, initial_state=seq2seq_encoder_out)
decoder_dense_before=Dense(num_words, activation='softmax', name='Final-Output-Dense-before')
decoder_outputs_before=decoder_dense_before(decoder_gru_output_before)
decoder_inputs_after=Input(shape=(None,), name='Decoder-Input-after') # for teacher forcing
dec_emb_after=emb_layer(decoder_inputs_after)
decoder_gru_after=GRU(latent_dim, return_state=True, return_sequences=True, name='Decoder-GRU-after')
decoder_gru_output_after, _=decoder_gru_after(dec_emb_after, initial_state=seq2seq_encoder_out)
decoder_dense_after=Dense(num_words, activation='softmax', name='Final-Output-Dense-after')
decoder_outputs_after=decoder_dense_after(decoder_gru_output_after)
#### Seq2Seq Model ####
seq2seq_Model=Model([encoder_inputs, decoder_inputs_before,decoder_inputs_after], [decoder_outputs_before,decoder_outputs_after])
seq2seq_Model.compile(optimizer=optimizers.Nadam(lr=0.001), loss='sparse_categorical_crossentropy')
seq2seq_Model.summary()
history=seq2seq_Model.fit([x_skip,x_before, x_after], [np.expand_dims(y_before, -1),np.expand_dims(y_after, -1)],
batch_size=batch_size,
epochs=10,
validation_split=0.12)
#Feature extraction
headlines=tokenizer.texts_to_sequences(data['headline'].values)
headlines=pad_sequences(headlines,maxlen=maxlen)x=encoder_model.predict(headlines)
#classifier
X_train,y_train,X_test,y_test=x[msk],y[msk],x[~msk],y[~msk]
lr=LogisticRegression().fit(X_train,y_train)
lr.score(X_test,y_test)

这一次我们抵达了 74% 的精确率。这是目前失掉的最佳精确率。


总结


本文中,我们引见了三个使用 RNN 创立句子向量表征的无监视方法,并且在处置一个监督义务的进程中展现了它们的效率。自编码器的结果比我们的基线模型要差一些(这能够是由于所用的数据集相对较小的因由)。skip-thought 向量模型语言模型都使用语境来预测句子表征,并得到了最佳结果。


能够提升我们所展示的方法功用的可用方法有:调理超参数、训练更多 epoch 次数、使用预训练嵌入矩阵、改动神经网络架构等等。实践上,这些初级的调理义务大约能够在肯定水平上改动后果。但是,我以为每一个预处理方法的基本直觉知识都能使用上述分享示例完成。

              

标签: tokenize

抱歉,评论功能暂时关闭!

微信号已复制,请打开微信添加咨询详情!