项目场景:
在具体学科场景下进行命名体识别是缺少数据集的,如何构建学科领域数据集,从而有效的进行命名实体识别是个关键。
文献数据清理
遇到的问题首先我们确实数据集,从而无法进行命名实体识别,其次关键信息通常都保存在文献中,我们需要通过文献来挖掘数据,最后挖掘来的数据需要打标签才能使用,针对这三个问题,需要三步走来解决。首先需要进行文献数据清理,这边我们是通过爬虫来获取原始学科文献,但学科文献基本上以PDF来显示,在PDF中直接数据抽取是不可能的,对是不可能的。我们先自动去除纯图片形式的PDF,之后要去除文献中的标题作者信息和参考文献,致谢,项目基金,声明等无效或冗余的信息。在这两步骤之前,我们还需要取得学科项目基本的词典,作为关键信息及数据挖掘的基础,例如沉积学学科中的Formation,将他作为关键词,文献中的关键信息可能为 A Formation,B Formation等。
好了我们下面来逐步开始构建文献初步清理和挖掘的流程。
第一步,关键词的导入,这里我们的项目中是需要两部分词典关键词,因此我们便导入两份词典,分别用数组形式保存。
# 时间存储字典
def dict():
# 打开字典并去掉换行符
with open("../duc.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
# 去除换行符
result = ([x.strip() for x in lines if x.strip() != ''])
# 将整理好字典提取成为全局字典
for x in result:
Dict.append(x)
return Dict
# 地点存储词典
def geodict():
# 打开字典并去掉换行符
with open("../geosubstance1.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
# 去除换行符
result = ([x.strip() for x in lines if x.strip() != ''])
# 将整理好字典提取成为全局字典
for x in result:
GeoDict.append(x)
return GeoDict
第二步,导入完词典,需要进行初步筛选,我们首先将PDF文本转换成DOCX文本便可以提取里面内容了,且好处在于,不会受到表格和图片影响。如在PDF中头铁硬来,则需要处理PDF中图片,表格也是以字符流形式存储。由于我做的工作是沉积学文本,里面所发期刊繁杂没有统一的abstract和acknowledgment这类标签,所以需要打个标签,这个工作量比后面一个个打命名实体识别标签要容易太多。这两个先前步骤结束之后就可以数据清理了。我们按照句号分割,把里面特殊的设计到同英文句号的缩写给去除,例如Fig.这些会影响到下一步提取的内容。最终将其分别保存到Txt文本中。
# 读取每段文本
# 进行初步清理并合并成一个文本
def getParagraphsText(doc,Namedocx):
paragraphsText = []
paragraphsText_new = []
for i in range(0,len(doc.paragraphs)):
print("这是:",doc.paragraphs[i].text)
for i in range(0, len(doc.paragraphs)):
paragraphsText.append(doc.paragraphs[i].text)
text = ([x.strip() for x in paragraphsText if x.strip() != ''])
# 初步数据清理从abstract开始删除acknowedge以后字段
第三步,初步筛选的文本进行一个初步提取,为什么叫初步提取,是因为这里仅仅是词典结合,不涉及到词性和其他内容,就好比你去相亲,先做个性别分类,是个男的我就筛选出来,我不管你身高,体重,长相,学历等等。在这里也是,只要有这个关键词,我不管关键词前面的组合词是什么我都把这句话给你提取出来,就如同A Formation,B Formation,这句话我只要有Formation就行,我不管A和B是什么,这不是我这一步需要考虑的,为此这一步也有一个限制要求:之前两个词典分别是物质和时间词典,在一句话中需要同时出现时间和物质,或者上下两句话中分别出现时间和物质,才行。为此我的处理代码如下:
# 筛选文本
# 进行提取筛选
def filter():
osfile = []
dir = r"D:\ZhichenHu\yiyao\CarbonatePlatform_time\txt"
for root, dirs, files in os.walk(dir):
for file in files:
if file.split('.')[1] == 'txt':
osfile.append(file)
for indexFile in range(len(osfile)):
splitTxt = []
splitTxtSpace = []
filterResult = []
ResultDoc = []
整体代码如下:
这里因项目需要,我加了一个提取地点的句子,但这很简单,对整体项目影响并不大。
__author__ = "Huzhichen"
from docx import Document
import re
import os
# 时间存储字典
def dict():
# 打开字典并去掉换行符
with open("../duc.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
# 去除换行符
result = ([x.strip() for x in lines if x.strip() != ''])
# 将整理好字典提取成为全局字典
for x in result:
Dict.append(x)
return Dict
# 地点存储词典
def geodict():
# 打开字典并去掉换行符
with open("../geosubstance1.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
# 去除换行符
result = ([x.strip() for x in lines if x.strip() != ''])
# 将整理好字典提取成为全局字典
for x in result:
GeoDict.append(x)
return GeoDict
# 读取每段文本
# 进行初步清理并合并成一个文本
def getParagraphsText(doc,Namedocx):
paragraphsText = []
paragraphsText_new = []
for i in range(0,len(doc.paragraphs)):
print("这是:",doc.paragraphs[i].text)
for i in range(0, len(doc.paragraphs)):
paragraphsText.append(doc.paragraphs[i].text)
text = ([x.strip() for x in paragraphsText if x.strip() != ''])
# 初步数据清理从abstract开始删除acknowedge以后字段
a = 0
for i in range(len(text)):
if text[i] == "Abstract":
a = i
for i in range(a+1,len(text)):
if text[i] == 'Acknowledgements':
break
else:
#text[i] = re.sub(u"\\(.*?\\)|\\{.*?}|\\[.*?]", '', text[i])
text[i] = re.sub(r"\d+\.(\d+)?", '', text[i])
text[i] = re.sub(r"\d+\.(\d+)? m",'',text[i])
text[i] = re.sub(r"\d+\.(\d+)? km", '', text[i])
text[i] = re.sub(r"Fig. +\d", '', text[i])
text[i] = re.sub(r"Figs. \d and \d", '', text[i])
text[i] = re.sub(r"Figs. +\d", '', text[i])
text[i] = re.sub(r" (\w)?\.", '', text[i])
text[i] = re.sub(r" (\w)?\.(\w)?\.", '', text[i])
paragraphsText_new.append(text[i].replace("ca.","ca").replace("i.e.","").replace("etc.","etc").replace("e.g.,","").replace("e.g.","").replace("al.","al")\
具体代码请私聊。开箱即用