文章目录

  • 1. 文本处理
  • 2. 文本序列化
  • 3. 数据集拆分
  • 4. 建立RNN模型
  • 5. 训练
  • 6. 测试

参考 基于深度学习的自然语言处理

1. 文本处理

数据预览

# 有两个作者的文章(A, B),定义为0, 1
A = 0 # hamilton
B = 1 # madison
UNKNOWN = -1
# 把同一作者的文章全部合并到一个文件
textA, textB = '', ''import os
for file in os.listdir('./papers/A'):textA += preprocessing('./papers/A/'+file)
for file in os.listdir('./papers/B'):textB += preprocessing('./papers/B/'+file)
  • 把同一作者的文档合并,去除\n, 多余空格,以及作者的名字(防止数据泄露)
def preprocessing(file_path):with open(file_path, 'r') as f:lines = f.readlines()text = ' '.join(lines[1:]).replace('\n',' ').replace('  ', ' ').lower().replace('hamilton','').replace('madison','')text = ' '.join(text.split())return text

print("文本A的长度:{}".format(len(textA)))
print("文本B的长度:{}".format(len(textB)))文本A的长度:216394
文本B的长度:230867

2. 文本序列化

  • 采用字符级别的 tokenizer char_level=True
from keras.preprocessing.text import Tokenizer
char_tokenizer = Tokenizer(char_level=True)char_tokenizer.fit_on_texts(textA + textB) # 训练tokenizerlong_seq_a = char_tokenizer.texts_to_sequences([textA])[0] # 文本转 ids 序列
long_seq_b = char_tokenizer.texts_to_sequences([textB])[0]Xa, ya = make_subsequence(long_seq_a, A) # 切分成多个等长的子串样本
Xb, yb = make_subsequence(long_seq_b, B)



  • ids 序列切分成等长的子串样本
SEQ_LEN = 30 # 切分序列的长度,超参数
import numpy as np
def make_subsequence(long_seq, label, seq_len=SEQ_LEN):numofsubseq = len(long_seq)-seq_len+1 # 滑窗,可以取出来这么多种X = np.zeros((numofsubseq, seq_len)) # 数据y = np.zeros((numofsubseq, 1)) # 标签for i in range(numofsubseq):X[i] = long_seq[i:i+seq_len] # seq_len 大小的滑窗y[i] = labelreturn X, y
print('字符的种类:{}'.format(len(char_tokenizer.word_index))) # 52
# {' ': 1, 'e': 2, 't': 3, 'o': 4, 'i': 5, 'n': 6, 'a': 7, 's': 8, 'r': 9, 'h': 10,
#  'l': 11, 'd': 12, 'c': 13, 'u': 14, 'f': 15, 'm': 16, 'p': 17, 'b': 18, 'y': 19, 'w': 20,
#  ',': 21, 'g': 22, 'v': 23, '.': 24, 'x': 25, 'k': 26, 'j': 27, ';': 28, 'q': 29, 'z': 30,
#  '-': 31, '?': 32, '"': 33, '1': 34, ':': 35, '8': 36, '7': 37, '(': 38, ')': 39, '2': 40,
#  '0': 41, '3': 42, '4': 43, '6': 44, "'": 45, '!': 46, ']': 47, '5': 48, '[': 49, '@': 50,
#  '9': 51, '%': 52}
print('A训练集大小:{}'.format(Xa.shape))
print('B训练集大小:{}'.format(Xb.shape))
A训练集大小:(216365, 30)
B训练集大小:(230838, 30)

3. 数据集拆分

  • A、B数据集混合
# 堆叠AB训练数据在一起
X = np.vstack((Xa, Xb))
y = np.vstack((ya, yb))
  • 训练集,测试集拆分
# 训练集测试集拆分
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

4. 建立RNN模型

from keras.models import Sequential
from keras.layers import SimpleRNN, Dense, EmbeddingEmbedding_dim = 128 # 输出的嵌入的维度
RNN_size = 256 #  RNN 单元个数model = Sequential()
model.add(Embedding(input_dim=len(char_tokenizer.word_index)+1,output_dim=Embedding_dim,input_length=SEQ_LEN))
model.add(SimpleRNN(units=RNN_size, return_sequences=False)) # 只输出最后一步
# return the last output in the output sequence
model.add(Dense(1, activation='sigmoid')) # 二分类model.compile(optimizer='adam', loss='binary_crossentropy',metrics=['accuracy'])
model.summary()

模型结构:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
embedding (Embedding)        (None, 30, 128)           6784
_________________________________________________________________
simple_rnn (SimpleRNN)       (None, 256)               98560
_________________________________________________________________
dense (Dense)                (None, 1)                 257
=================================================================
Total params: 105,601
Trainable params: 105,601
Non-trainable params: 0
_________________________________________________________________

如果return_sequences=True,后两个输出维度如下:(增加了序列长度维度)

simple_rnn_1 (SimpleRNN)     (None, 30, 256)           98560
_________________________________________________________________
dense_1 (Dense)              (None, 30, 1)             257

5. 训练

batch_size = 4096 # 一次梯度下降使用的样本数量
epochs = 20  # 训练轮数
history = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs,validation_data=(X_test, y_test),verbose=1)
Epoch 1/20
88/88 [==============================] - 59s 669ms/step - loss: 0.6877 - accuracy: 0.5436 - val_loss: 0.6856 - val_accuracy: 0.5540
Epoch 2/20
88/88 [==============================] - 56s 634ms/step - loss: 0.6830 - accuracy: 0.5564 - val_loss: 0.6844 - val_accuracy: 0.5550
Epoch 3/20
88/88 [==============================] - 56s 633ms/step - loss: 0.6825 - accuracy: 0.5577 - val_loss: 0.6829 - val_accuracy: 0.5563
Epoch 4/20
88/88 [==============================] - 56s 634ms/step - loss: 0.6816 - accuracy: 0.5585 - val_loss: 0.6788 - val_accuracy: 0.5641
Epoch 5/20
88/88 [==============================] - 56s 637ms/step - loss: 0.6714 - accuracy: 0.5813 - val_loss: 0.6670 - val_accuracy: 0.5877
Epoch 6/20
88/88 [==============================] - 56s 637ms/step - loss: 0.6532 - accuracy: 0.6113 - val_loss: 0.6435 - val_accuracy: 0.6235
Epoch 7/20
88/88 [==============================] - 57s 648ms/step - loss: 0.6287 - accuracy: 0.6424 - val_loss: 0.6159 - val_accuracy: 0.6563
Epoch 8/20
88/88 [==============================] - 55s 620ms/step - loss: 0.5932 - accuracy: 0.6807 - val_loss: 0.5747 - val_accuracy: 0.6971
Epoch 9/20
88/88 [==============================] - 54s 615ms/step - loss: 0.5383 - accuracy: 0.7271 - val_loss: 0.5822 - val_accuracy: 0.7178
Epoch 10/20
88/88 [==============================] - 56s 632ms/step - loss: 0.4803 - accuracy: 0.7687 - val_loss: 0.4536 - val_accuracy: 0.7846
Epoch 11/20
88/88 [==============================] - 61s 690ms/step - loss: 0.3979 - accuracy: 0.8190 - val_loss: 0.3940 - val_accuracy: 0.8195
Epoch 12/20
88/88 [==============================] - 60s 687ms/step - loss: 0.3257 - accuracy: 0.8572 - val_loss: 0.3248 - val_accuracy: 0.8564
Epoch 13/20
88/88 [==============================] - 59s 668ms/step - loss: 0.2637 - accuracy: 0.8897 - val_loss: 0.2980 - val_accuracy: 0.8742
Epoch 14/20
88/88 [==============================] - 56s 638ms/step - loss: 0.2154 - accuracy: 0.9115 - val_loss: 0.2326 - val_accuracy: 0.9023
Epoch 15/20
88/88 [==============================] - 56s 639ms/step - loss: 0.1822 - accuracy: 0.9277 - val_loss: 0.2112 - val_accuracy: 0.9130
Epoch 16/20
88/88 [==============================] - 56s 640ms/step - loss: 0.1504 - accuracy: 0.9412 - val_loss: 0.1803 - val_accuracy: 0.9267
Epoch 17/20
88/88 [==============================] - 58s 660ms/step - loss: 0.1298 - accuracy: 0.9499 - val_loss: 0.1662 - val_accuracy: 0.9331
Epoch 18/20
88/88 [==============================] - 57s 643ms/step - loss: 0.1132 - accuracy: 0.9567 - val_loss: 0.1643 - val_accuracy: 0.9358
Epoch 19/20
88/88 [==============================] - 58s 659ms/step - loss: 0.1018 - accuracy: 0.9613 - val_loss: 0.1409 - val_accuracy: 0.9441
Epoch 20/20
88/88 [==============================] - 57s 642ms/step - loss: 0.0907 - accuracy: 0.9659 - val_loss: 0.1325 - val_accuracy: 0.9475
  • 绘制训练过程
import pandas as pd
import matplotlib.pyplot as plt
pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 1) # set the vertical range to [0-1]
plt.show()

6. 测试

# 测试for file in os.listdir('./papers/Unknown'):# 测试文本处理unk_file = preprocessing('./papers/Unknown/'+file)# 文本转ids序列unk_file_seq = char_tokenizer.texts_to_sequences([unk_file])[0]# 提取固定长度的子串,形成多个样本X_unk, _ = make_subsequence(unk_file_seq, UNKNOWN)# 预测y_pred = model.predict(X_unk)y_pred = y_pred > 0.5votesA = np.sum(y_pred==0)votesB = np.sum(y_pred==1)print("文章 {} 被预测为 {} 写的,投票数 {} : {}".format(file,"A:hamilton" if votesA > votesB else "B:madison",max(votesA, votesB),min(votesA, votesB)))

输出:5个文本的作者,都预测对了

文章 paper_1.txt 被预测为 B:madison 写的,投票数 122118563
文章 paper_2.txt 被预测为 B:madison 写的,投票数 108998747
文章 paper_3.txt 被预测为 A:hamilton 写的,投票数 70416343
文章 paper_4.txt 被预测为 A:hamilton 写的,投票数 50634710
文章 paper_5.txt 被预测为 A:hamilton 写的,投票数 68784876

使用RNN预测文档归属作者相关推荐

  1. 新建word文档默认作者如何修改

    方式一: 安装Office时,提示输入用户名称时输入你想设置的作者姓名,之后每次新建word文档的默认作者就是填写的用户名了. 方式二: 菜单栏-->工具-->选项-->弹出的&qu ...

  2. 如何更改计算机文档作者,如何更改word文档的作者

    2006-12-01 现在我想要把我正在编辑的WORD文档同时保存在不同的文件夹中,有什么方法!??比如说:别人在我的电脑编辑了一份WORD文档,然后他把文档保存在他的U盘上,在他离去后,我却能在电脑 ...

  3. 基于Python的Covid-19全球疫情数据分析预测 文档+项目源码及数据

    资源下载地址:https://download.csdn.net/download/sheziqiong/85638801 资源下载地址:https://download.csdn.net/downl ...

  4. [word办公软件] WPS如何修改Word文档作者?

    转载请说明来源于"厦门SEO" 本文地址:http://www.96096.cc/Article/160977.html word办公软件 有的时候我们阅读其他人的Word文档资料 ...

  5. 如何写出优秀的技术文档?

    大家好,我是小枣君. 鲜枣课堂自从2017年5月开始正式创立,迄今已有3年多的时间.这一期间,我们的内容一直都坚持以技术类科普文章为主,输出了大约400多篇原创.其中绝大部分,都是我写的. 我的想法比 ...

  6. 开发框架文档体系化的思考

    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/VWjB83NBTg6FwPBDg8G0HQ 作者:Shi Zhengxing 本文对自己工作 ...

  7. 多模态文档LayoutLM版面智能理解技术演进-纪传俊

    多模态算法兴起的背景 办公文档是各行各业最基础也是最重要的信息载体,不管是金融.政务.制造业.零售行业等等,各种类型的文档都是业务流转过程中必不可少的数字资料.以银行信贷为例,一笔信贷业务在贷前贷中到 ...

  8. CVPR 2018 | 旷视科技Face++率先提出DocUNet 可复原扭曲的文档图像

    全球计算机视觉顶会 CVPR 2018 (Conference on Computer Vision and Pattern Recognition,即IEEE国际计算机视觉与模式识别会议)将于6月1 ...

  9. 夸克APP端智能:文档关键点检测实践与应用

    作者:顺达 最近夸克端智能小组在做端上的实时文档检测,即输入一张RGB图像,得到文档的四个角的关键点的坐标.整个pipelines属于关键点检测算法,因此最近对相关领域的论文进行阅读和进行了实验尝试. ...

最新文章

  1. rice university phd application result
  2. java z+_Java Z 字形变换
  3. 重学前端学习笔记(二十二)--选择器的机制
  4. 安卓python安装库_如何快速在安卓上搭建python3环境
  5. UITextField 文字垂直居中
  6. android实现 5.0 6.0手机自动接听电话功能
  7. JQ树形菜单加表格混合使用:treeTable组件使用
  8. 利用偏最小二乘法选出最重要的特征波段Matlab
  9. 再说“恢复被删除的文件”(转)
  10. 国产RY8122 18V 2A 500KHz同步降压稳压芯片
  11. 俄罗斯方块游戏的消行实现
  12. 计算机速录方法,速录练习技巧方法介绍
  13. 解决Attribute 'transaction-manager' is not allowed to appear
  14. 无法安装office此计算机安装了32位,在电脑上安装64位Office2013出错提示找到了32位程序如何解决...
  15. kali pinyin拼音输入法
  16. 第二章 基础数据 第2节 工作日历
  17. 通过elasticSearch实现输入框输入字母或者部分词条联想查询
  18. centOS7挂载存储节点
  19. 如何使用阿里云虚拟主机搭建博客(三)设置篇
  20. 教你一个免费合并PDF最简单的方法

热门文章

  1. 计算机文档xsl,XSL-FO 文档
  2. c#课程设计简单题目_《C#项目案例》课程设计题目
  3. java语言 编译原理_【Java学习】深入分析Java的编译原理
  4. linux qt ping,Qt5.2中使用ping命令实现Ip扫描功能
  5. 高可用性的HDFS—Hadoop分布式文件系统深度实践
  6. 1、绪论初识机器学习
  7. 将二维数组名作为函数实参
  8. BotVS开发基础—2.1 账户、行情、K线、深度
  9. '[linux下tomcat 配置
  10. 设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误