自然语言处理与灾难推文分类

在信息爆炸的时代,如何从海量的社交媒体信息中快速识别出与灾难相关的推文,成为了一个重要的研究课题。这不仅涉及到自然语言处理NLP)的技术,还需要对文本数据进行深入的分析和处理。本文将带了解如何通过NLP技术实现灾难推文的分类,并探讨文本预处理和LSTM模型创建的过程。

数据集分析

所使用的数据集是灾难推文数据集,它包含五列数据,但主要关注的是“text”列,即推文内容,以及“target”列,它指示给定的推文是否与灾难相关。为了获得良好的分类结果,需要对推文数据进行一系列的文本预处理技术。

实现步骤

首先,需要导入项目所需的所有库。这些库包括pandas、numpy、re、nltk等,它们将帮助进行数据处理和模型训练。

import warnings warnings.simplefilter(action='ignore', category=Warning) import pandas as pd import numpy as np import re import nltk from nltk.corpus import stopwords from tqdm import tqdm import seaborn as sns sns.set_style("darkgrid") import matplotlib.pyplot as plt %matplotlib inline

接下来,使用pandas导入灾难推文数据集,并分析数据的几行和列。

data = pd.read_csv("train.csv") data.head()

使用seaborn,绘制灾难和非灾难推文的数量。

sns.countplot(data["target"])

计算归一化值计数,以了解数据集中灾难和非灾难推文的比例。

data["target"].value_counts(normalize=True)

作为数据分析的重要步骤,将计算每条推文的长度,并创建一个基于长度数据绘制直方图的函数。

def length_plot(data, name): length = [len(sentence.split()) for sentence in data] plt.hist(length) plt.title(name)

现在,将分离依赖和独立特征,并计算灾难推文中存在的不重复单词数量。

X = data["text"] # 独立特征 y = data["target"] # 依赖特征 y = np.array(y) # 转换为数组

定义了一个函数来计算不重复单词,并打印出总数量。

def unq_words(sentence): unq_words_list = [] for sent in tqdm(sentence): for word in sent.split(): if word.lower() not in unq_words_list: unq_words_list.append(word.lower()) else: pass return unq_words_list unique_words = unq_words(X) print("Total unique words present :",len(unique_words))

接下来,将处理推文中的特殊符号,如“#”和“@”。定义了两个符号,并分别找出以这些符号开头的单词。

SYMBOL_1 = "#" sym1_words = [word for word in unique_words if word.startswith(SYMBOL_1)] len(sym1_words) # 1965

得出结论,以“@”开头的单词对模型的准确性没有影响,因此决定移除它们。

SYMBOL_2 = "@" sym2_words = [word for word in unique_words if word.startswith(SYMBOL_2)] len(sym2_words) # 2264

在数据集中,存在许多URL,因此编写一个函数来移除它们。

def url_remover(text): url_patterns = re.compile(r'https?://S+|www.S+') return url_patterns.sub(r'', text)

现在,开始实际的预处理,并编写一个函数来实现它。

from nltk.stem import WordNetLemmatizer wl = WordNetLemmatizer() def preprocessing(text): tweets = [] for sentence in tqdm(text): sentence = sentence.lower() # 转换为小写 sentence = url_remover(sentence) # 移除URL sentence = re.sub(r'@w+', '', sentence).strip() # 移除以"@"开头的单词 sentence = re.sub("[^a-zA-Z0-9 ']", "", sentence) # 移除符号 sentence = sentence.split() sentence1 = [wl.lemmatize(word) for word in sentence if word not in set(stopwords.words("english"))] # 词形还原和停用词移除 sentence1 = " ".join(sentence1) tweets.append(sentence1) return tweets tweets = preprocessing(X)

至此,移除了不必要的符号、停用词,并进行了词形还原。在将数据输入模型之前,需要将这些推文转换为数值特征,因此需要执行one-hot编码。

from tensorflow.keras.layers import (Embedding, LSTM, Dense, Dropout, GlobalMaxPool1D, BatchNormalization) from tensorflow.keras.models import Sequential from tensorflow.keras.preprocessing.sequence import pad_sequences from tensorflow.keras.preprocessing.text import one_hot

执行one-hot编码。

VOC_SIZE = 30000 onehot_vector = [one_hot(words, VOC_SIZE) for words in tweets]

找到每条推文的单词长度,并执行零填充以使序列长度相等。

SENTENCE_LENGTH = 15 embedded_docs = pad_sequences(onehot_vectors, padding="post", maxlen=SENTENCE_LENGTH)

接下来是创建模型的重要步骤。第一层是词嵌入层,后面跟着LSTM模型。

def model(): VECTOR_FEATURES = 32 lstm_model = Sequential() lstm_model.add(Embedding(VOC_SIZE, VECTOR_FEATURES, input_length=SENTENCE_LENGTH)) lstm_model.add(LSTM(100, return_sequences = True)) lstm_model.add(GlobalMaxPool1D()) lstm_model.add(BatchNormalization()) lstm_model.add(Dropout(0.5)) lstm_model.add(Dense(10, activation="relu")) lstm_model.add(Dropout(0.25)) lstm_model.add(Dense(1, activation = "sigmoid")) return lstm_model

创建模型并获取模型摘要。

lstm_model = model() lstm_model.compile(optimizer = "adam", loss = "binary_crossentropy", metrics = ["accuracy"]) lstm_model.summary() #摘要

训练模型。

history = lstm_model.fit(embedded_docs, y, epochs=8, batch_size=32) plt.plot(history.history["accuracy"]) plt.xlabel("Epochs") plt.ylabel("Accuracy") plt.title("Accuracy") plt.plot(history.history["loss"]) plt.xlabel("Epochs") plt.ylabel("Loss") plt.title("Loss") pickle.dump(lstm_model, open("model.pkl", "wb")) # 加载模型 lstm_model = pickle.load(open("model.pkl", "rb"))
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485