阅读 137

NLP知识点:文本数据的预处理

1. 为啥要有预处理?

NLP(Natural Language Processing)指的是自然语言处理,就是研究计算机理解人类语言的一项技术。

要研究语言处理,那么首先得有语言文本。之前讲过利用Tokenizer分词器对固定格式的文本进行序列化处理。

在序列化之前,如何把这些文本按照一定的格式处理好,也是一项基础的工作,这一步叫数据的预处理。

2. 文本存储的几种载体

一般直接可读的文本数据会存储在这么几种文件里:

  • 数据库:sqlite、mysql……

  • 表格文件:csv、excel……

  • 纯文本文件:txt、json……

下面我们就挨个来讲一下,如何读写这些文件。

2.1 数据库

数据库存储文本信息,有很多优势:

  • 支持大数据量存储

  • 查询高效

  • 支持复杂的关联关系

拿sqlite数据库举例子,看一下如何进行数据的读取。

下面有一个数据库文件,大小为8KB。

db图标.png

数据库里面有一张名称叫"ci"的表,数据结构和内容如下:

db内容.png

表里面存储了25条数据,是25篇宋词,每条数据包含序号(value)、词牌名(rhythmic)、作者(author)、内容(content)。

假设,我们要使用每首词的内容作为训练集,那么我们该如何组织数据呢?

# 导入sqlite的支持 import sqlite3 # 保存每首词的内容 str_array  = [] # 指定文件位置(同级目录data下的data.db文件)建立连接 conn = sqlite3.connect('./data/data.db') # 执行查询语句,只获取author, content两个字段,获得游标(内含结果) cursor = conn.execute("SELECT author, content from ci;") # 循环结果 for row in cursor:     # 获取结果(0 author, 1 content)中索引为1的数据     ci = row[1]     # 加入内容列表     str_array.append(ci) # 关闭操作 cursor.close() conn.close() # 打印结果 print(str_array) 复制代码

最终打印结果如下:

[ '出砒霜,价钱可。\r\n赢得拨灰兼弄火。\r\n畅杀我。',  '丞相有才裨造化,圣皇宽诏养疏顽。\r\n赢取十年闲。',  '归。\r\n十万人家儿样啼。\r\n公归去,何日是来时。',  '归。\r\n数得宣麻拜相时。\r\n秋前後,公衮更莱衣。',  '百尺长藤垂到地,千株乔木密参天。\r\n只在郡城边。',  '巍峨万丈与天高。\r\n物轻人意重,千里送鹅毛。\r\n\r\n'  …… ] 复制代码

其中\r\n是回车换行。我们看看巍峨万丈与天高。\r\n物轻人意重,千里送鹅毛。\r\n\r\n在文本框的展示,能够帮助你更好地理解。

rn文本框展示.gif

延伸知识:sqlite3的写入

数据的写入很简单,和数据读取类似。也是先建立连接,然后执行sql语句,这里多一个commit提交,最后断开连接。

下面举例说明,连续插入2条数据。

# 导入sqlite的支持 import sqlite3 # %% 数据表数据的写入 conn = sqlite3.connect('./data/data.db') for t in[(9998,"名称1","作者1","正文1"),(9999,"名称2","作者2","正文2")]:     conn.execute("insert into ci values (?,?,?,?)", t)      conn.commit() conn.close() 复制代码

2.2 表格文档

相比于数据库,表格类文档(csv、excel)也是一种很好的文本存储方式。

它双击就能打开,可以直接操作内容,也能利用自带的工具做一些数据处理。

下面有一个csv文件,里面有很多行,每一行是一首宋词,前三列分别是:词牌名、作者、内容。

csv内容.png

假设,我们要使用每首词的内容作为训练集,那么我们该如何组织数据呢?

import csv # 建立存储内容的数组 str_array  = [] # 构建阅读器,指定文件位置(同级目录data下的data.csv文件),指定编码格式 csv_reader = csv.reader(open("./data/data.csv",encoding="gbk")) # 循环每一行 for row in csv_reader:     # 取出索引为2的列(第3列),存入数组     str_array.append(row[2]) # 打印数据     print(str_array) 复制代码

最终打印结果如下:

[ '出砒霜,价钱可。\r\n赢得拨灰兼弄火。\r\n畅杀我。',  '丞相有才裨造化,圣皇宽诏养疏顽。\r\n赢取十年闲。',  '归。\r\n十万人家儿样啼。\r\n公归去,何日是来时。',  '归。\r\n数得宣麻拜相时。\r\n秋前後,公衮更莱衣。',  '百尺长藤垂到地,千株乔木密参天。\r\n只在郡城边。',  '巍峨万丈与天高。\r\n物轻人意重,千里送鹅毛。\r\n\r\n'  …… ] 复制代码

这样,这个数组数据就可以使用了。

延伸知识:csv的写入

数据的写入和数据读取类似。先构建一个写入器 ,写入数据,最后需要关闭打开的文件。

下面举例说明,新建一个csv文件,然后插入1条数据。

import csv # 以写入的方式打开(新建)一个文件,指定编码 f_csv = open('./data/data2.csv','w',encoding='gbk', newline='') # 获取这个文件的写入器 csv_writer = csv.writer(f_csv) # 写入一行数据 csv_writer.writerow(['第一列','第二列','第三列']) # 关闭文件 f_csv.close() 复制代码

代码执行后,会在同级的data目录下新建一个data2.csv文件,然后写入一行3列的数据。

csv写入.png

2.3 文本文档

文本文档(txt)是最轻量级的一种文本存储方式。

它不像数据库或者表格文件那样有关联关系,它只能罗列一段段文本,它也无法承载太多的数据,一般上万行文本就会导致它读取困难。

但是,它也是有优势的。那就是——使用方便。

打开文件往里面输入字符就可以了。

因为没有行列条数的概念,一般文本文档要存储数据集,都是以特殊字符作为区分,例如回车换行符,一行就是一条数据。

下面有一段文本,我们看看如何读取它。

txt内容.png

import os # 保存每行文本内容的数组 str_array  = [] # 指定文件位置(同级目录data下的data.txt文件) f_read = open('./data/data.txt','rb') # 读取一行文件 line = f_read.readline() # 如果此行存在 while line:      # 读出内容     wstr = str(line, encoding = "utf-8-sig")     # 添加到数组     str_array.append(wstr)     # 接着再读下一行     line = f_read.readline() # 关闭文件 f_read.close() # 打印数组 print(str_array) 复制代码

最终打印结果如下:

[ '巍峨万丈与天高。物轻人意重,千里送鹅毛。\r\n',  '远来犹自忆梁陈。江南无好物,聊赠一枝春。\r\n',  '用心勤苦是新诗。吟安一个字,拈断数茎髭。\r\n',  '扪窗摸户入房来。笙歌归院落,灯火下楼台。\r\n',  '酥某露出白皑皑。遥知不是雪,为有暗香来。\r\n',  '称觞喜对二阳临。况当弦月上,一醉祝千春。\r\n' ] 复制代码

延伸知识:txt的写入

数据的写入和数据读取类似。先打开一个文件 ,写入数据,最后需要关闭打开的文件。

下面举例说明,新建一个txt文件,然后写入文本。

import os # 以写入的方式打开(新建)data2.txt的文本 f_write = open('./data/data2.txt','w') f_write.write('写入文本第一行\n第二行') f_write.close() 复制代码

3. 组合拳:清洗数据并存为json文件

假设我们要训练一套关于宋词的数据,数据源就是下面数据库里的这张表的数据。

组合拳 词.png

看似这些数据井井有条,其实并不是那么完美。

组合拳 词的问题.png

此时你有几个诉求:

  1. 去冗余:去掉头尾多余的数据,去掉重复的数据。

  2. 做筛选:只想要《临仙江》这种句式的数据。

  3. 换存储:因为数据量不大,想以json文本格式存储清洗后的数据。

分析:

  1. 去掉文本的头尾空格和换行,可以使用strip()方法。去除重复数据,可通过代码逻辑实现,将遇到的句子保存起来,下一个句子到已保存列表里面查找,能查到说明重复,查不到说明第一次见。

  2. 《临仙江》的格式为:{[7个汉字]。<换行回车>[5个汉字],[5个汉字]。},可以通过正则匹配筛选出,正则表达式为:^[\u4e00-\u9fa5]{7}。\r\n[\u4e00-\u9fa5]{5},[\u4e00-\u9fa5]{5}。$

  3. 从数据库读取数据,筛选到合适的文本,组成json字符串写入文本即可。

代码如下:

import sqlite3 import json import re # 存储内容的数组 str_array = [] # 已经遇到过的内容 keys = {""} # 筛选 {7。5,5。}格式内容的正则表达式 pattern = re.compile(r'^[\u4e00-\u9fa5]{7}。\r\n[\u4e00-\u9fa5]{5},[\u4e00-\u9fa5]{5}。$')  # 连接数据库 conn = sqlite3.connect('./data/data.db') # 执行查询,只获取内容字段,获得游标结果 cursor = conn.execute("SELECT content from ci;") # 循环结果 for row in cursor:     # 获取索引为0的列     ci = row[0]     # 裁剪头尾     ci = ci.strip()     # 匹配格式     m = pattern.match(ci)     # 没有匹配到     if m == None:         print('\n没有匹配到:',ci)     else: # 匹配到         print('\n匹配成功:',ci)         # 是否出现过         if ci in keys:             # 出现过,是重复的,不处理             print('\n已存在->',ci)         else:             # 没有出现过,加入出现列表,加入内容列表             keys.add(ci)             str_array.append(ci) # 关闭游标和链接 cursor.close() conn.close() # 将内容列表转为json j_str = json.dumps(str_array, indent=2, ensure_ascii=False) # 打开(新建)文本 f_write = open('./data/data2.json','w') # 写入文本 f_write.write(j_str) # 关闭文件 f_write.close() 复制代码

生成的data2.json内容如下:

生成的json.png


作者:TF男孩
链接:https://juejin.cn/post/7029165733598724103


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐