Bert NER

初试

利用上周运行成功的模型
稍微的阅读了代码和样例文件
发现源代码提供了predict接口于是构造相同结构的数据输入
直接使用学生手册。每一行作为一个句子进行输入

  1. "D:\Python_plus\data_set\data\student\1.txt"
  2. import json
  3. data=[]
  4. def get_train(filepath):
  5. try:
  6. with open(filepath, "r",encoding='utf-8') as f:
  7. lines = f.readlines()
  8. except FileNotFoundError:
  9. print('无法打开指定的文件!')
  10. except LookupError:
  11. print('指定了未知的编码!')
  12. except UnicodeDecodeError:
  13. print('读取文件时解码错误!')
  14. id=0
  15. for i in lines:
  16. i=i.replace("\n","")
  17. if i == "":
  18. continue
  19. temp={}
  20. temp["id"]=id
  21. temp["text"]=i
  22. id+=1
  23. data.append(temp)
  24. path="D:\\Python_plus\\data_set\\data\\student\\1.txt"
  25. get_train(path)
  26. print(data)
  27. print(data[0])
  28. try:
  29. with open("test.json", "w", encoding='utf-8') as f:
  30. for i in data:
  31. a=json.dumps(i,ensure_ascii=False)
  32. f.write(a)
  33. f.write("\n")
  34. except FileNotFoundError:
  35. print('无法打开指定的文件!')
  36. except LookupError:
  37. print('指定了未知的编码!')
  38. except UnicodeDecodeError:
  39. print('读取文件时解码错误!')

处理后的文本
image.png
结果不理想,可能和文本本身缺乏实体以及文本的类型不一致导致,也可能这么处理过于粗糙
image.png

阅读代码

一直对NER任务有两种解决方案的猜想

  1. 做两次训练,类似于CV的目标检测,先找实体后做分类(CV也是先框出物体,再做分类)
  2. 直接理解为一段序列标注,不是实体的字也有一个标注,然后就是一个序列到另一个序列的转化工作,一个方法就是用字向量加全连接加Softmax

阅读了实现代码之后(没太看懂)
我个人感觉是第一种

  1. def bert_extract_item(start_logits, end_logits):
  2. S = []
  3. start_pred = torch.argmax(start_logits, -1).cpu().numpy()[0][1:-1]
  4. end_pred = torch.argmax(end_logits, -1).cpu().numpy()[0][1:-1]
  5. for i, s_l in enumerate(start_pred):
  6. if s_l == 0:
  7. continue
  8. for j, e_l in enumerate(end_pred[i:]):
  9. if s_l == e_l:
  10. S.append((s_l, i, i + j))
  11. break
  12. return S
  1. R = bert_extract_item(start_logits, end_logits)
  2. if R:
  3. label_entities = [[args.id2label[x[0]],x[1],x[2]] for x in R]
  4. else:
  5. label_entities = []

问题发现

上次实验的结果奇差
于是尝试更换文本实验
随便找了一篇新闻
结果还是很差

  1. 原标题:美国拟恢复资助世卫,但摊派费用要比照中国
  2. 观察者网讯)据福克斯新闻516日报道,一份草拟的信函显示,白宫正准备恢复对世卫组织的部分资助。
  3. 福克斯新闻主持人塔克·卡尔森15日表示,他得到了一份致世卫总干事谭德塞的白宫信函草稿的信息,这份5页的草稿显示,美国政府“同意支付和中国相同的摊派费用”。
  4. 卡尔森还称,一名政府高级官员透露,总统特朗普已经被说服,同意签署这封信函。
  5. 福克斯的报道透露了信函的一部分内容。草稿的开头写道,美国对世卫组织应对疫情的评估“证实了我(特朗普)上个月提出的担忧,并指出一些其他问题。”
  6. 接着信函写道:“尽管世卫组织仍有缺陷,但我相信它仍有巨大的潜力。我希望世卫组织能够发挥这一潜力,尤其是在当下的全球疫情之中……这就是为什么我决定美国将继续和世卫组织合作。”
  7. 福克斯新闻认为,这些文字显然是特朗普的口吻。
  8. 在资金援助方面,美国一直是世卫组织最大的资金来源国,比尔和梅琳达·盖茨基金会则是世卫的第二大供资方。在评定会费的摊派比例上,美国最近几年的分摊比例一直为22%,而中国2020-2021双年度分摊比例为12%,这是按照各国的经济和人口状况计算出的。
  9. 但截止今年3月底,美国还欠着2亿美元的会费没交。福克斯披露的信函中则这么写道,“如果中国增加了资助费用,那我们也会考虑跟着增加。”
  10. 不过从报道透露的内容来看,这份信函还致力于“甩锅”:它先是写道“中国欠了世界一大笔,他们可以从向世卫组织支付合理的资助开始补偿。”接着又称,世卫组织必须隔绝“政治压力”的影响,并再次鼓吹“对病毒的起源和世卫组织的应对措施进行独立评估”。
  11. 这封信函最终以要求“对世卫组织进行常识性改革”、“建立一个普遍的审查机制,公开报告会员国对国际卫生条例的遵守情况”为结尾。
  12. 414日,特朗普曾在白宫记者会上宣布停止资助世卫组织,批评世卫组织“未能及时分享信息”、“抗疫不力”。
  13. 世卫组织总干事谭德塞在48日就曾呼吁,不要将疫情政治化,要团结起来抗击疫情。422日他在回应美国停止资助时表示,他对此感到遗憾,并将寻求与其他合作伙伴一同解决资金问题

image.png

后来阅读代码,发现是源代码里对每一次的读文件运行模型都保存了缓存
也就是不管是train还是test还是predict,全都会在运行的过程中保存一个缓存
(可能是怕文件过大,可以断点继续运行?)
可能因此在预测的时候读入的是第一次的缓存文件(另一个数据文件),然后把对应的标注信息标注在了新文件上,于是直接导致了乱七八糟的标注

随后重新删除缓存,重新运行
结果显著提高
image.png

同时重新运行学生手册
似乎也不那么差(感觉对国家和组织分不太清)大体上划分还行,分类不太满意
还有切出了一堆空的是什么鬼。。。