word2vec和常见CNN+RNN网格结构组成的文本分类模型

作者为了应付毕业,所以在补充深度学习相关知识,这是我尝试把word2vec和深度学习相互结合的一次记录。

  • 数据集来源
  • 数据集预处理
  • 生成word2vec模型
  • 搭建网络并且训练

 

数据集来源

本文的数据集源自kaggle比赛中的NLP入门比赛,灾难新闻预报警。

数据集预处理

数据导入:

import numpy as np
import pandas as pd
train_df = pd.read_csv("data/train.csv")
test_df = pd.read_csv("data/test.csv")

数据预处理:

import re
import os, sys
import string
# 停用词
from nltk.corpus import stopwords
# 小写
def text_to_lowercase(text):
    return text.lower()
#去掉标点符号
def text_remove_punctuation(text):
    return text.translate(str.maketrans('', '', string.punctuation))
#去掉url
def text_remove_url(text):
    return re.sub(r"http\S+", "", text)
#去掉@符号
def text_remove_twitter_handle(text):
    return re.sub('@[^\s]+','',text)
#去掉Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
def text_remove_leadtrail_spaces(text):
    return text.strip()
def clean_text(text):
    # order matters
    text1 = text_remove_twitter_handle(text)
    text2 = text_remove_url(text1)
    text3 = text_remove_punctuation(text2)
    text4 = text_to_lowercase(text3)
    text5 = text_remove_leadtrail_spaces(text4)
    return text5
# x = train_df["text"]
# 类似于list遍历性操作
# y = [clean_text(i) for i in x]
# text processing
train_df['text_processed'] =[clean_text(i) for i in train_df["text"]]
# x1 = test_df["text"]
# y1 = [clean_text(i) for i in x1]
# text processing
#清洗数据
test_df['text_processed'] =[clean_text(i) for i in test_df["text"]]
feature=train_df['text_processed']
target=train_df['target']

生成word2vec模型

from gensim.models import Word2Vec
# 训练模型,词向量的长度设置为500# , 迭代次数为8# ,采用skip-gram模型# ,采用负采样# 窗口选择6# 最小词频是7# ,模型保存为pkl格式
w2v_model=Word2Vec(feature, size=500, sg=1,hs=0,window=6, iter=8,min_count=7)
w2v_model.wv.save_word2vec_format("./word2Vec" + ".pkl", binary=True) 

导入工具包

from keras.preprocessing.sequence import pad_sequences
from keras.preprocessing.text import Tokenizer
from keras.utils import np_utils
from keras.layers.merge import concatenate
# 搭建模型
from keras.models import Sequential, Model
# 这个是层的搭建
from keras.layers import Dense, Embedding, Activation, Input
from keras.layers import Convolution1D, Flatten, Dropout, MaxPool1D
from keras.layers import  BatchNormalization
from keras.layers import Convolution1D, Conv1D,MaxPooling1D
from keras.layers import Dense, Embedding, Input, Lambda, Reshape
from keras.layers import Convolution1D, Flatten, Dropout, MaxPool1D, GlobalAveragePooling1D
from keras.layers import LSTM, GRU, TimeDistributed, Bidirectional
rom keras.utils import to_categorical

数据集分割和转数字

# 文本标签分类数量
NUM_CLASS=2
# 输入维度
INPUT_SIZE=64
# # 序列对齐文本数据
# Tokenizer是一个用于向量化文本,或将文本转换为序列
tokenizer = Tokenizer(filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',lower=True,split=" ")
tokenizer.fit_on_texts(feature)
vocab = tokenizer.word_index
x_ids=tokenizer.texts_to_sequences(feature)
pad_s=pad_sequences(x_ids, maxlen=INPUT_SIZE)
from keras.utils import to_categorical
target_u=to_categorical(target,NUM_CLASS)
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(pad_s,target_u,random_state=22,test_size=0.2)

搭建网络并且训练

给Embedding加入word2vec

embeding_matrix=np.zeros((len(vocab)+1,500))
for word,i in vocab.items():
    try:
        embeding_vector=w2v_model[str(word)]
        embeding_matrix[i]=embeding_vector
    except KeyError:
        continue

textCNN模型加入word2vec

from keras.layers import Flatten,Dropout
main_input=Input(shape=(INPUT_SIZE,),dtype='float64')
embedder=Embedding(len(vocab)+1,500,input_length=INPUT_SIZE,weights=[embeding_matrix],trainable=True)
embed=embedder(main_input)
cnn1=Conv1D(256,3,padding='same',strides=1,activation='relu')(embed)
cnn1=MaxPooling1D(pool_size=38)(cnn1)
cnn2=Conv1D(256,4,padding='same',strides=1,activation='relu')(embed)
cnn2=MaxPooling1D(pool_size=37)(cnn2)
cnn3=Conv1D(256,5,padding='same',strides=1,activation='relu')(embed)
cnn3=MaxPooling1D(pool_size=36)(cnn3)
cnn=concatenate([cnn1,cnn2,cnn3],axis=-1)
flat=Flatten()(cnn)
drop=Dropout(0.2)(flat)
main_output=Dense(NUM_CLASS,activation='softmax')(drop)
model=Model(inputs=main_input,outputs=main_output)
model.summary()

模型搭建结果:

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print('Train...')
model.fit(X_train, y_train,
          batch_size=32,
          epochs=10,
          validation_data=[X_test,y_test])

模型训练结果:

其他的模型

加了word2vec的CNN模型

model = Sequential()
model.add(Embedding(len(vocab)+1,500,input_length=INPUT_SIZE,weights=[embeding_matrix],trainable=True)) #使用Embeeding层将每个词编码转换为词向量
model.add(Conv1D(256, 5, padding='same'))
model.add(MaxPooling1D(3, 3, padding='same'))
model.add(Conv1D(128, 5, padding='same'))
model.add(MaxPooling1D(3, 3, padding='same'))
model.add(Conv1D(64, 3, padding='same'))
model.add(Flatten())
model.add(Dropout(0.1))
model.add(BatchNormalization())  # (批)规范化层
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(NUM_CLASS, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print('Train...')
model.fit(X_train, y_train,
          batch_size=32,
          epochs=10,
          validation_data=[X_test,y_test])

加入了word2vec的RNN模型

model = Sequential()
model.add(Embedding(len(vocab)+1,500,input_length=INPUT_SIZE,weights=[embeding_matrix],trainable=True))
model.add(LSTM(256, dropout=0.2, recurrent_dropout=0.1))
model.add(Dense(NUM_CLASS, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print('Train...')
model.fit(X_train, y_train,
          batch_size=32,
          epochs=10,
          validation_data=[X_test,y_test])

加入了word2vec的Bi-GRU

# 模型结构:词嵌入-双向GRU*2-全连接
model = Sequential()
# 64是序列号
model.add(Embedding(len(vocab)+1,500,input_length=INPUT_SIZE,weights=[embeding_matrix],trainable=True))
model.add(Bidirectional(GRU(256, dropout=0.2, recurrent_dropout=0.1, return_sequences=True)))
model.add(Bidirectional(GRU(256, dropout=0.2, recurrent_dropout=0.1)))
model.add(Dense(NUM_CLASS, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print('Train...')
model.fit(X_train, y_train,
          batch_size=32,
          epochs=10,
          validation_data=[X_test,y_test])

加入了word2vec的CNN+RNN 串联

# 模型结构:词嵌入-卷积池化-GRU*2-全连接
model = Sequential()
model.add(Embedding(len(vocab)+1,500,input_length=INPUT_SIZE,weights=[embeding_matrix],trainable=True))
model.add(Convolution1D(256, 3, padding='same', strides = 1))
model.add(Activation('relu'))
model.add(MaxPool1D(pool_size=2))
model.add(GRU(256, dropout=0.2, recurrent_dropout=0.1, return_sequences = True))
model.add(GRU(256, dropout=0.2, recurrent_dropout=0.1))
model.add(Dense(NUM_CLASS, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print('Train...')
model.fit(X_train, y_train,
          batch_size=32,
          epochs=10,
          validation_data=[X_test,y_test])

加入了word2vec的 CNN+RNN 并联

# 模型结构:词嵌入-卷积池化-全连接 ---拼接-全连接
#                -双向GRU-全连接
main_input = Input(shape=(INPUT_SIZE,), dtype='float64')
embed = Embedding(len(vocab)+1,500,input_length=INPUT_SIZE,weights=[embeding_matrix],trainable=True)(main_input)
cnn = Convolution1D(256, 3, padding='same', strides = 1, activation='relu')(embed)
cnn = MaxPool1D(pool_size=4)(cnn)
cnn = Flatten()(cnn)
cnn = Dense(256)(cnn)
rnn = Bidirectional(GRU(256, dropout=0.2, recurrent_dropout=0.1))(embed)
rnn = Dense(256)(rnn)
con = concatenate([cnn,rnn], axis=-1)
main_output = Dense(NUM_CLASS, activation='softmax')(con)
model = Model(inputs = main_input, outputs = main_output)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print('Train...')
model.fit(X_train, y_train,
          batch_size=32,
          epochs=10,
          validation_data=[X_test,y_test])

 

### 如何在 Java 中实现 Word2Vec使用 Word2Vec 的库 #### 已知背景 Word2Vec 是一种用于生成词嵌入的技术,能够将单词表示为低维向量形式,从而捕捉它们之间的语义关系。其主要模型包括连续词袋模型(CBOW)跳字模型(Skip-gram)。在 Java 中可以利用现有的开源库或者自行实现该算法。 --- #### 方法一:使用现成的 Java 版本 Word2Vec 库 目前已有多个成熟的 Java 实现可供选择: 1. **NLPchina/Word2VEC_java** 这是一个基于 Java 的 Word2Vec 开源项目[^1]。可以通过 Maven 引入依赖并快速上手: ```xml <dependency> <groupId>com.github.nlpchina</groupId> <artifactId>word2vec</artifactId> <version>最新版本号</version> </dependency> ``` 2. **Jiangwm/Word2VEC_java** 另一个 GitHub 上的 Java 实现[^5]提供了类似的接口支持。可以根据文档中的示例代码完成训练过程。 3. **Deeplearning4j (DL4J)** DL4J 提供了一个强大的自然语言处理工具包,其中包含了 Word2Vec 的实现[^4]。以下是简单的初始化训练流程: ```java import org.deeplearning4j.text.sentenceiterator.SentenceIterator; import org.deeplearning4j.text.tokenization.tokenizerfactory.TokenizerFactory; import org.deeplearning4j.models.word2vec.Word2Vec; SentenceIterator iter = new BasicLineIterator("path/to/corpus"); TokenizerFactory t = new DefaultTokenizerFactory(); Word2Vec vec = new Word2Vec.Builder() .minWordFrequency(1) .iterations(5) .layerSize(128) .windowSize(5) .iterate(iter) .tokenizerFactory(t) .build(); vec.fit(); // 训练模型 ``` 上述方法均能有效减少开发时间,并提供良好的性能保障。 --- #### 方法二:手动实现 Word2Vec 如果希望深入理解内部机制,则可以选择自己编写核心逻辑。具体步骤如下: 1. 准备数据集——寻找足够的语料作为输入材料。 2. 构建词汇表——统计所有出现过的词语及其频率。 3. 定义神经网络结构——依据 CBOW 或 Skip-gram 设计前馈层。 4. 编写损失函数优化器——采用负采样等方式加速收敛速度[^2]。 5. 测试效果——验证最终得到的向量是否满足预期需求。 下面展示一段简化版的手动实现伪代码片段: ```java public class CustomWord2Vec { private Map<String, int[]> vocabMap; // 单词索引映射 public void train(List<List<String>> sentences) { initializeVocabulary(sentences); NeuralNetwork nn = createNeuralNetwork(NeuralNetworkType.SKIP_GRAM); for(int epoch=0;epoch<numEpochs;epoch++) { for(List<String> sentence : sentences){ processSentence(sentence,nn); } } } private void initializeVocabulary(List<List<String>> sentences){...} private NeuralNetwork createNeuralNetwork(NeuralNetworkType type){...} private void processSentence(List<String> sentence, NeuralNetwork nn){...} } ``` 此方式虽然耗时较长但也更灵活可控[^3]。 --- #### 性能调优建议 无论选用哪种途径,在实际操作过程中都需要注意以下几个方面以提升效率: - 调整超参数设置如窗口大小(window size),隐藏层数目(layer size)[^4]; - 对高频次项应用降采样(down-sampling rate)降低计算负担; - 利用多线程或多核处理器加快运算进度(useNumThreads); ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南楚巫妖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值