Python使用神经网络进行简单文本分类

深度学习无处不在。在本文中,我们将使用Keras进行文本分类。

由Kaizong Ye,Coin Ge撰写

出于演示目的,我们将使用  20个新闻组  数据集。

数据分为20个类别,我们的工作是预测这些类别。如下所示:

×

在自然语言的文本分类中,主要使用两类模型,一类是使用传统的机器学习模型,如朴素贝叶斯,最大熵,支持向量机等,第二类就是使用神经网络模型,包括CNN和RNN。传统的机器模型在分类前首先要做特征工程,例如把文本转换成词袋,并转化为TF-IDF矩阵,然后再做分类。而使用神经网络模型可以使它自己提取特征并进行文本分类,并能获得优于传统机器学习模型的能力。

CNN模型的文本分类

CNN原来是用于对图像分类,后来按照其形式用到了对自然语言处理上,处理原理相同,首先是对句子的每一个词生成一个实值的词向量,然后按照句子合并成一个词向量矩阵,这个词向量矩阵就相当于一个图像的像素,剩下的就如同图像处理一样,使用卷积核进行卷积以及进行池化等。

RNN模型的文本分类

Lai使用了一种RNN模型进行文本分类,这个模型结构比较奇葩,一共分为三层,首先使用的是类似双向RNN的结构当做卷积层,第二层为最大池化层,最后一层是输出层,具体如下。 
使用cl(wi)cl(wi)表示单词wiwi的左边的上下文,使用cr(wi)cr(wi)表示wiwi的右边的上下文,当然cl(wi)cl(wi)和cr(wi)cr(wi)都是实值向量,维度为|c||c|。单词wiwi左边和右边的上下文向量分别有下式计算: 

cl(wi)=f(W(l)cl(wi−1)+W(sl)e(wi−1))(1)(1)cl(wi)=f(W(l)cl(wi−1)+W(sl)e(wi−1))

 

cr(wi)=f(W(l)cr(wi+1)+W(sr)e(wi+1))(2)(2)cr(wi)=f(W(l)cr(wi+1)+W(sr)e(wi+1))


其中,e(wi)e(wi)表示第ii个词的词向量,W(l)W(l)为从一个隐藏层(上下文)到下一个隐藏层的参数矩阵,W^{(sl)}为当前词与左边上下文的参数矩阵,ff诶非线性激活函数,对于cr(wi)cr(wi)类似。第一个单词的左边上下文默认为cl(w1)cl(w1),对于最后一个单词的右边上下文默认为cr(wn)cr(wn)。 


通常,对于深度学习,我们将划分训练和测试数据。

导入所需的软件包


自适应网页宽度的 Youku 视频

视频

CNN(卷积神经网络)模型以及R语言实现

探索见解

去bilibili观看

探索更多视频

Python

import pandas as pd
import numpy as np
import pickle
from keras.preprocessing.text import Tokenizer
from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout
from sklearn.preprocessing import LabelBinarizer
import sklearn.datasets as skds
from pathlib import Path


将数据从文件加载到Python变量

Python


# 为了复现性
 
np.random.seed(1237)
  
label_index = files_train.target
label_names = files_train.target_names
labelled_files = files_train.filenames
 
data_tags = ["filename","category","news"]
data_list = []
 
# 读取文件中的数据并将其添加到列表
 
 
 
data = pd.DataFrame.from_records(data_list, columns=data_tags)

我们的数据无法以CSV格式提供。我们有文本数据文件,文件存放的目录是我们的标签或类别。

我们将使用scikit-learn load_files方法。这种方法可以提供原始数据以及标签和标签索引。

最后我们得到一个数据框,其中包含文件名,类别和实际数据。

拆分数据进行训练和测试

Python

# 让我们以80%的数据作为训练,剩下的20%作为测试。
 
 
train_size = int(len(data) * .8)
 
train_posts = data['news'][:train_size]
train_tags = data['category'][:train_size]
train_files_names = data['filename'][:train_size]
 
test_posts = data['news'][train_size:]
test_tags = data['category'][train_size:]
test_files_names = data['filename'][train_size:]


标记化并准备词汇

 Python

# 20个新闻组
 
 
num_labels = 20
vocab_size = 15000
batch_size = 100
 
# 用Vocab Size定义Tokenizer
 
 
tokenizer = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts(train_posts)
 

在对文本进行分类时,我们首先使用Bag Of Words方法对文本进行预处理。


用于NLP的Python:使用Keras的多标签文本LSTM神经网络分类

阅读文章


预处理输出标签/类

在将文本转换为数字向量后,我们还需要确保标签以神经网络模型接受的数字格式表示。

建立Keras模型并拟合

PowerShell

model = Sequential()

它为输入数据的维度以及构成模型的图层类型提供了简单的配置。

这是拟合度和测试准确性的代码段

100/8145 [..............................] - ETA: 31s - loss: 1.0746e-04 - acc: 1.0000
200/8145 [..............................] - ETA: 31s - loss: 0.0186 - acc: 0.9950    
300/8145 [>.............................] - ETA: 35s - loss: 0.0125 - acc: 0.9967
400/8145 [>.............................] - ETA: 32s - loss: 0.0094 - acc: 0.9975
500/8145 [>.............................] - ETA: 30s - loss: 0.0153 - acc: 0.9960
...
7900/8145 [============================>.] - ETA: 0s - loss: 0.1256 - acc: 0.9854
8000/8145 [============================>.] - ETA: 0s - loss: 0.1261 - acc: 0.9855
8100/8145 [============================>.] - ETA: 0s - loss: 0.1285 - acc: 0.9854
8145/8145 [==============================] - 29s 4ms/step - loss: 0.1293 - acc: 0.9854 - val_loss: 1.0597 - val_acc: 0.8742
 
Test accuracy: 0.8767123321648251

评估模型

Python

for i in range(10):
    prediction = model.predict(np.array([x_test[i]]))
    predicted_label = text_labels[np.argmax(prediction[0])]
    print(test_files_names.iloc[i])
    print('Actual label:' + test_tags.iloc[i])
    print("Predicted label: " + predicted_label)

在Fit方法训练了我们的数据集之后,我们将如上所述评估模型。

混淆矩阵

混淆矩阵是可视化模型准确性的最佳方法之一。

保存模型

通常,深度学习的用例就像在不同的会话中进行数据训练,而使用训练后的模型进行预测一样。

# 创建一个HDF5文件'my_model.h5'
 
 
model.model.save('my_model.h5')
 
# 保存令牌生成器,即词汇表
 
 
with open('tokenizer.pickle', 'wb') as handle:
    pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)

Keras没有任何实用程序方法可将Tokenizer与模型一起保存。我们必须单独序列化它。

加载Keras模型

 Python 

预测环境还需要注意标签。

encoder.classes_ #标签二值化

预测

如前所述,我们已经预留了一些文件进行实际测试。

Python

 
labels = np.array(['alt.atheism', 'comp.graphics', 'comp.os.ms-windows.misc',
'comp.sys.ibm.pc.hardware', 'comp.sys.mac.hardware', 'comp.windows.x',
'misc.forsale', 'rec.autos', 'rec.motorcycles', 'rec.sport.baseball',
'rec.sport.hockey', 'sci.crypt', 'sci.electronics', 'sci.med', 'sci.space',
'soc.religion.christian', 'talk.politics.guns', 'talk.politics.mideast',
'talk.politics.misc', 'talk.religion.misc'])
 ...
for x_t in x_tokenized:
    prediction = model.predict(np.array([x_t]))
    predicted_label = labels[np.argmax(prediction[0])]
    print("File ->", test_files[i], "Predicted label: " + predicted_label)
    i += 1

输出量

File -> C:\DL\20news-bydate\20news-bydate-test\comp.graphics\38758 Predicted label: comp.graphics
File -> C:\DL\20news-bydate\20news-bydate-test\misc.forsale\76115 Predicted label: misc.forsale
File -> C:\DL\20news-bydate\20news-bydate-test\soc.religion.christian\21329 Predicted label: soc.religion.christian

我们知道目录名是文件的真实标签,因此上述预测是准确的。

结论

在本文中,我们使用Keras python库构建了一个简单而强大的神经网络。


可下载资源

关于作者

Kaizong Ye拓端研究室(TRL)的研究员。在此对他对本文所作的贡献表示诚挚感谢,他在上海财经大学完成了统计学专业的硕士学位,专注人工智能领域。擅长Python.Matlab仿真、视觉处理、神经网络、数据分析。

本文借鉴了作者最近为《R语言数据分析挖掘必知必会 》课堂做的准备。

​非常感谢您阅读本文,如需帮助请联系我们!

 
QQ在线咨询
售前咨询热线
15121130882
售后咨询热线
0571-63341498