基于LSTM+CRF的中文命名实体识别
基于LSTM+CRF的中文命名实体识别
- 任务描述:命名实体识别是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。
- 实现一个简单的命名实体识别方法,该方法通过BiLSTM+CRF模型预测出文本中文字所对应的标签,再根据标签提取出文本中的实体。
- 从数据文件中加载数据并进行预处理、构建模型、训练模型、评估模型和测试模型。
- 说明:目前本文档仅作为示例,为了加快训练速度模型较为简单,词向量维度也比较低,因此导致模型准确率较低。
import tensorflow as tf
import numpy as np
import pandas as pd
import tensorflow_addons as tfa
tf 2.0 的新特性:eager execution
- 可以用tf.executing_eargerly()查看Eager Execution当前的启动状态,返回True则是开启,False是关闭。
- 可以用tf.compat.v1.enable_eager_execution()启动eager模式。
- 关闭eager模式的函数是 tf.compat.v1.disable_eager_execution()
tf.compat.v1.disable_eager_execution()
文本数准备
- 数据说明
- 数据整理
- 加载数据
数据说明
数据集共包含约2.7万中文文本,其中包括约2.08万训练集,0.23万验证集和0.46万测试集。
数据集分别命名为example.train,example.dev,example.test,保存在datasets目录下。
- 1.训练集:包含文本和对应的标签,用于模型训练。
- 2.验证集:包含文本和对应的标签,用于模型训练和参数调试。
- 3.测试集:包含文本和对应的标签,用于预测结果、验证效果。
数据集中标注有三种实体,分别为人名、地名、机构名,标注集合为{'O','B-PER','I-PER','B-ORG','I-ORG','B-LOC','I-LOC'}。
- 其中'O'表示非实体,
- 'B-'表示实体的首字,
- 'I-'表示实体的其他位置的字,
- 'PER'表示人名,
- 'ORG'表示机构名,
- 'LOC'表示地名。IOB(Inside–outside–beginning)是用于标记标志的通用标记格式。
数据整理
根据数据集中的字符建立字典,并保存在datasets/vocab.txt中, 标签根据数据集中字符建立字典,并保存在datasets/.txt中
def get_vocab_list(path_list):
= set()
vocab_set = list()
vocab_list for path in path_list:
with open(path,'r',encoding='utf-8') as f:
for line in f:
if len(line.strip()) == 0:
continue
if line[0] not in vocab_set:
0])
vocab_set.add(line[0])
vocab_list.append(line[return vocab_list
def save_vocab(path,vocab_list):
= ''.join([vocab + '\n' for vocab in vocab_list])
output with open(path,'w', encoding='utf-8') as f:
f.write(output)
= get_vocab_list(['./datasets/example.train','./datasets/example.dev','./datasets/example.test'])
vocab_list './datasets/vocab.txt',vocab_list) save_vocab(
vocab_list
['海',
'钓',
'比',
'赛',
'地',
'点',
'在',
'厦',
'门',
'与',
'金',
'之',
'间',
'的',
'域',
'。',
'这',
'座',
'依',
'山',
'傍',
'水',
'博',
'物',
'馆',
'由',
'国',
'内',
'一',
'流',
'设',
'计',
'师',
'主',
'持',
',',
'整',
'个',
'建',
'筑',
'群',
'精',
'美',
'而',
'恢',
'宏',
'但',
'作',
'为',
'共',
'产',
'党',
'员',
'、',
'人',
'民',
'公',
'仆',
'应',
'当',
'胸',
'怀',
'宽',
'阔',
'真',
'正',
'做',
'到',
'“',
'先',
'天',
'下',
'忧',
'后',
'乐',
'”',
'淡',
'化',
'名',
'利',
'得',
'失',
'和',
'宠',
'辱',
'悲',
'喜',
'把',
'改',
'革',
'大',
'业',
'摆',
'首',
'位',
'样',
'才',
'能',
'超',
'越',
'自',
'我',
'脱',
'世',
'俗',
'有',
'所',
'发',
'达',
'家',
'急',
'救',
'保',
'险',
'十',
'分',
'普',
'及',
'已',
'成',
'社',
'会',
'障',
'体',
'系',
'重',
'要',
'组',
'部',
'日',
'俄',
'两',
'政',
'局',
'都',
'充',
'满',
'变',
'数',
'尽',
'管',
'关',
'目',
'前',
'是',
'历',
'史',
'最',
'佳',
'时',
'期',
'其',
'脆',
'弱',
'性',
'不',
'言',
'明',
'克',
'马',
'尔',
'女',
'儿',
'让',
'娜',
'今',
'年',
'读',
'五',
'级',
'她',
'班',
'上',
'3',
'0',
'多',
'同',
'学',
'该',
'委',
'1',
'长',
'参',
'加',
'步',
'行',
'男',
'轻',
'也',
'中',
'沙',
'特',
'队',
'教',
'练',
'佩',
'雷',
'拉',
':',
'支',
'想',
'胜',
'因',
'此',
'出',
'了',
'努',
'力',
'种',
'混',
'乱',
'面',
'导',
'致',
'些',
'使',
'用',
'者',
'合',
'法',
'权',
'益',
'难',
'以',
'维',
'护',
'鲁',
'宾',
'确',
'指',
'对',
'府',
'控',
'完',
'全',
'没',
'事',
'实',
'根',
'据',
'向',
'转',
'敏',
'感',
'技',
'术',
'相',
'总',
'白',
'于',
';',
'众',
'议',
'院',
'令',
'非',
'常',
'望',
'将',
'商',
'卫',
'星',
'受',
'威',
'胁',
'竞',
'争',
'损',
'害',
'育',
'场',
'每',
'早',
'6',
'至',
'8',
'免',
'费',
'开',
'放',
'游',
'泳',
'等',
'则',
'增',
'综',
'服',
'务',
'延',
'采',
'取',
'灵',
'活',
'收',
'再',
'看',
'容',
'图',
'文',
'并',
'茂',
'简',
'短',
'字',
'准',
'反',
'映',
'六',
'族',
'风',
'土',
'情',
'传',
'统',
'各',
'讲',
'很',
'哥',
'伦',
'亚',
'号',
'航',
'飞',
'机',
'宇',
'边',
'进',
'验',
'继',
'续',
'抢',
'修',
'故',
'二',
'氧',
'碳',
'清',
'除',
'装',
'置',
'从',
'剥',
'削',
'阶',
'劳',
'动',
'生',
'率',
'低',
'况',
'占',
'限',
'剩',
'余',
'品',
'足',
'豪',
'华',
'需',
'量',
'扩',
'现',
'资',
'条',
'件',
'榨',
'价',
'值',
'供',
'身',
'求',
'外',
'又',
'本',
'新',
'雇',
'佣',
'私',
'来',
'料',
'集',
'代',
'表',
'澳',
'别',
'区',
'筹',
'备',
'第',
'次',
'午',
'北',
'京',
'堂',
'幕',
'副',
'理',
'任',
'钱',
'琛',
'词',
'工',
'经',
'启',
'临',
'紧',
'迫',
'们',
'道',
'远',
'希',
'齐',
'心',
'协',
'平',
'稳',
'过',
'渡',
'顺',
'交',
'接',
'贡',
'献',
'济',
'程',
'界',
'深',
'信',
'观',
'必',
'须',
'微',
'基',
'础',
'病',
'好',
'颈',
'背',
'躯',
'干',
'殖',
'器',
'可',
'见',
'龄',
'市',
'柔',
'县',
'试',
'遍',
'觉',
'四',
'节',
'课',
'饥',
'饿',
'消',
'川',
'省',
'江',
'油',
'丰',
'选',
'豆',
'奶',
'复',
'营',
'养',
'素',
'贫',
'血',
'降',
'百',
'照',
'只',
'.',
'4',
'宗',
'旨',
'决',
'定',
'奉',
'甘',
'愿',
'吃',
'亏',
'苦',
'享',
'困',
'危',
'留',
'给',
'己',
'方',
'便',
'安',
'初',
'央',
'形',
'势',
'快',
'速',
'策',
'立',
'研',
'究',
'派',
'就',
'提',
'许',
'富',
'意',
'味',
'论',
'话',
'题',
'书',
'记',
'粟',
'光',
'断',
'他',
'亲',
'兄',
'弟',
'签',
'!',
'熟',
'悉',
'运',
'士',
'说',
'贷',
'款',
'旦',
'被',
'推',
'迟',
'几',
'月',
'甚',
'更',
'考',
'虑',
'伍',
'义',
'气',
'原',
'惠',
'象',
'估',
'像',
'疤',
'痕',
'笨',
'拙',
'手',
'针',
'线',
'周',
'恩',
'那',
'送',
'株',
'万',
'古',
'青',
'友',
'谊',
'红',
'杉',
'吧',
'巴',
'谈',
'问',
'印',
'声',
'宣',
'称',
'何',
'三',
'介',
'入',
'久',
'赴',
'西',
'老',
'访',
'广',
'职',
'积',
'极',
'企',
'监',
'督',
'如',
'居',
'子',
'倘',
'若',
'客',
'环',
'境',
'钝',
'迅',
'判',
'陷',
'处',
'碰',
'壁',
'然',
'热',
'解',
'寻',
'找',
'联',
'邦',
'州',
'予',
'适',
'具',
'骤',
'吸',
'七',
'团',
'另',
'龙',
'口',
'科',
'投',
'视',
'息',
'创',
'跳',
'跃',
'式',
'展',
'强',
'调',
'高',
'培',
'训',
'认',
'识',
'密',
'结',
'小',
'九',
'升',
'或',
'段',
'少',
'懂',
'习',
'互',
'贵',
'贱',
'请',
'注',
'语',
'构',
'偏',
'孝',
'父',
'母',
'始',
'票',
'否',
'制',
'还',
'缺',
'乏',
'际',
'电',
'影',
'摄',
'录',
'音',
'剪',
'辑',
'诸',
'趋',
'激',
'烈',
'造',
'奇',
'夺',
'起',
'直',
'追',
'医',
'药',
'李',
'珍',
'闻',
'屡',
'仕',
'寄',
'托',
'八',
'股',
'兴',
'趣',
'酷',
'爱',
'召',
'吴',
'英',
'司',
'董',
'德',
'·',
'葛',
'夫',
'邀',
'席',
'车',
'闲',
'防',
'施',
'配',
'套',
'存',
'鹅',
'洲',
'源',
'终',
'连',
'串',
'井',
'序',
'顾',
'犯',
'罪',
'讳',
'审',
'死',
'刑',
'笔',
'融',
'农',
'假',
'币',
'知',
'巧',
'律',
'规',
'村',
'秩',
'『',
'范',
'茅',
'迹',
'览',
'』',
'磁',
'球',
'孩',
'格',
'散',
'着',
'独',
'魅',
'莱',
'坞',
'千',
'模',
'翻',
'版',
'?',
'燃',
'汽',
'仅',
'守',
'—',
'路',
'易',
'斯',
'切',
'迪',
'阿',
'塞',
'瓦',
'萨',
'卡',
'里',
'罗',
'弗',
'哈',
'丹',
'尼',
'扎',
'胡',
'埃',
'索',
'库',
'纳',
'吉',
'莫',
'帕',
'锋',
'米',
'贝',
'耶',
'冈',
'玻',
'乌',
'布',
'苏',
'念',
'案',
'罚',
'较',
'战',
'略',
'均',
'贸',
'拓',
'5',
'份',
'去',
'阅',
'室',
'刊',
'晚',
'智',
'藏',
'突',
'破',
'借',
'架',
'办',
'沃',
'盟',
'昨',
'约',
'南',
'举',
'空',
'军',
'演',
'示',
'欢',
'迎',
'帮',
'助',
'7',
'叫',
'迈',
'菲',
'查',
'奋',
'剂',
'通',
'未',
'勇',
'曲',
'绕',
'桥',
'绝',
'《',
'嫂',
'》',
'警',
'魂',
'片',
'获',
'房',
'石',
'香',
'港',
'朝',
'蓬',
'勃',
'拼',
'搏',
'斗',
'神',
'写',
'2',
'春',
'季',
'招',
'兵',
'募',
'既',
'食',
'预',
'止',
'癌',
'症',
'城',
'引',
'项',
'懈',
'液',
'尾',
'9',
'%',
'氢',
'减',
'污',
'染',
'双',
'网',
'抽',
'封',
'差',
'亟',
'待',
'单',
'麦',
'果',
'∶',
'松',
'赢',
'测',
'析',
'迷',
'叶',
'钦',
'岁',
'刻',
'哲',
'思',
'虽',
'担',
'负',
'领',
'责',
'专',
'却',
'爸',
'劲',
'抗',
'艰',
'聘',
'仍',
'治',
'洋',
'尊',
'庄',
'志',
'回',
'忆',
'淳',
'朴',
'报',
'届',
'张',
'君',
'秋',
'剧',
'角',
'艺',
'校',
'坚',
'质',
'围',
'侧',
'缓',
'财',
'状',
'聚',
'渠',
'逐',
'靠',
'优',
'征',
'稿',
'截',
'句',
'晤',
'纠',
'纷',
'朋',
'坏',
'它',
'促',
'岗',
'标',
'织',
'践',
'邓',
'按',
'署',
'挥',
'核',
'●',
'承',
'键',
'街',
'巷',
'横',
'幅',
'悬',
'画',
'头',
'欣',
'慰',
...]
def get_label_list(path_list):
= set()
label_set = list()
label_list for path in path_list:
with open(path,'r',encoding='utf-8') as f:
for line in f:
if len(line.strip()) == 0:
continue
if line[2:].strip() not in label_set:
2:].strip())
label_set.add(line[2:].strip())
label_list.append(line[return label_list
def save_label(path,label_list):
= ''.join([label + '\n' for label in label_list])
output with open(path,'w', encoding='utf-8') as f:
f.write(output)
= get_label_list(['./datasets/example.train','./datasets/example.dev','./datasets/example.test'])
label_list './datasets/label.txt',label_list) save_label(
label_list
['O', 'B-LOC', 'I-LOC', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG']
加载数据
分别获取vocab 和label与id的映射
def get_string2id(path): string2id = {} id2string = [] with open(path,'r',encoding='utf-8') as f: for line in f: string2id[line.strip()] = len(string2id) id2string.append(line.strip()) return id2string,string2idid2label,label2id = get_string2id("./datasets/label.txt")id2vocab,vocab2id = get_string2id("./datasets/vocab.txt")
id2label
['O', 'B-LOC', 'I-LOC', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG']
label2id
{'O': 0,
'B-LOC': 1,
'I-LOC': 2,
'B-PER': 3,
'I-PER': 4,
'B-ORG': 5,
'I-ORG': 6}
id2vocab
['海',
'钓',
'比',
'赛',
'地',
'点',
'在',
'厦',
'门',
'与',
'金',
'之',
'间',
'的',
'域',
'。',
'这',
'座',
'依',
'山',
'傍',
'水',
'博',
'物',
'馆',
'由',
'国',
'内',
'一',
'流',
'设',
'计',
'师',
'主',
'持',
',',
'整',
'个',
'建',
'筑',
'群',
'精',
'美',
'而',
'恢',
'宏',
'但',
'作',
'为',
'共',
'产',
'党',
'员',
'、',
'人',
'民',
'公',
'仆',
'应',
'当',
'胸',
'怀',
'宽',
'阔',
'真',
'正',
'做',
'到',
'“',
'先',
'天',
'下',
'忧',
'后',
'乐',
'”',
'淡',
'化',
'名',
'利',
'得',
'失',
'和',
'宠',
'辱',
'悲',
'喜',
'把',
'改',
'革',
'大',
'业',
'摆',
'首',
'位',
'样',
'才',
'能',
'超',
'越',
'自',
'我',
'脱',
'世',
'俗',
'有',
'所',
'发',
'达',
'家',
'急',
'救',
'保',
'险',
'十',
'分',
'普',
'及',
'已',
'成',
'社',
'会',
'障',
'体',
'系',
'重',
'要',
'组',
'部',
'日',
'俄',
'两',
'政',
'局',
'都',
'充',
'满',
'变',
'数',
'尽',
'管',
'关',
'目',
'前',
'是',
'历',
'史',
'最',
'佳',
'时',
'期',
'其',
'脆',
'弱',
'性',
'不',
'言',
'明',
'克',
'马',
'尔',
'女',
'儿',
'让',
'娜',
'今',
'年',
'读',
'五',
'级',
'她',
'班',
'上',
'3',
'0',
'多',
'同',
'学',
'该',
'委',
'1',
'长',
'参',
'加',
'步',
'行',
'男',
'轻',
'也',
'中',
'沙',
'特',
'队',
'教',
'练',
'佩',
'雷',
'拉',
':',
'支',
'想',
'胜',
'因',
'此',
'出',
'了',
'努',
'力',
'种',
'混',
'乱',
'面',
'导',
'致',
'些',
'使',
'用',
'者',
'合',
'法',
'权',
'益',
'难',
'以',
'维',
'护',
'鲁',
'宾',
'确',
'指',
'对',
'府',
'控',
'完',
'全',
'没',
'事',
'实',
'根',
'据',
'向',
'转',
'敏',
'感',
'技',
'术',
'相',
'总',
'白',
'于',
';',
'众',
'议',
'院',
'令',
'非',
'常',
'望',
'将',
'商',
'卫',
'星',
'受',
'威',
'胁',
'竞',
'争',
'损',
'害',
'育',
'场',
'每',
'早',
'6',
'至',
'8',
'免',
'费',
'开',
'放',
'游',
'泳',
'等',
'则',
'增',
'综',
'服',
'务',
'延',
'采',
'取',
'灵',
'活',
'收',
'再',
'看',
'容',
'图',
'文',
'并',
'茂',
'简',
'短',
'字',
'准',
'反',
'映',
'六',
'族',
'风',
'土',
'情',
'传',
'统',
'各',
'讲',
'很',
'哥',
'伦',
'亚',
'号',
'航',
'飞',
'机',
'宇',
'边',
'进',
'验',
'继',
'续',
'抢',
'修',
'故',
'二',
'氧',
'碳',
'清',
'除',
'装',
'置',
'从',
'剥',
'削',
'阶',
'劳',
'动',
'生',
'率',
'低',
'况',
'占',
'限',
'剩',
'余',
'品',
'足',
'豪',
'华',
'需',
'量',
'扩',
'现',
'资',
'条',
'件',
'榨',
'价',
'值',
'供',
'身',
'求',
'外',
'又',
'本',
'新',
'雇',
'佣',
'私',
'来',
'料',
'集',
'代',
'表',
'澳',
'别',
'区',
'筹',
'备',
'第',
'次',
'午',
'北',
'京',
'堂',
'幕',
'副',
'理',
'任',
'钱',
'琛',
'词',
'工',
'经',
'启',
'临',
'紧',
'迫',
'们',
'道',
'远',
'希',
'齐',
'心',
'协',
'平',
'稳',
'过',
'渡',
'顺',
'交',
'接',
'贡',
'献',
'济',
'程',
'界',
'深',
'信',
'观',
'必',
'须',
'微',
'基',
'础',
'病',
'好',
'颈',
'背',
'躯',
'干',
'殖',
'器',
'可',
'见',
'龄',
'市',
'柔',
'县',
'试',
'遍',
'觉',
'四',
'节',
'课',
'饥',
'饿',
'消',
'川',
'省',
'江',
'油',
'丰',
'选',
'豆',
'奶',
'复',
'营',
'养',
'素',
'贫',
'血',
'降',
'百',
'照',
'只',
'.',
'4',
'宗',
'旨',
'决',
'定',
'奉',
'甘',
'愿',
'吃',
'亏',
'苦',
'享',
'困',
'危',
'留',
'给',
'己',
'方',
'便',
'安',
'初',
'央',
'形',
'势',
'快',
'速',
'策',
'立',
'研',
'究',
'派',
'就',
'提',
'许',
'富',
'意',
'味',
'论',
'话',
'题',
'书',
'记',
'粟',
'光',
'断',
'他',
'亲',
'兄',
'弟',
'签',
'!',
'熟',
'悉',
'运',
'士',
'说',
'贷',
'款',
'旦',
'被',
'推',
'迟',
'几',
'月',
'甚',
'更',
'考',
'虑',
'伍',
'义',
'气',
'原',
'惠',
'象',
'估',
'像',
'疤',
'痕',
'笨',
'拙',
'手',
'针',
'线',
'周',
'恩',
'那',
'送',
'株',
'万',
'古',
'青',
'友',
'谊',
'红',
'杉',
'吧',
'巴',
'谈',
'问',
'印',
'声',
'宣',
'称',
'何',
'三',
'介',
'入',
'久',
'赴',
'西',
'老',
'访',
'广',
'职',
'积',
'极',
'企',
'监',
'督',
'如',
'居',
'子',
'倘',
'若',
'客',
'环',
'境',
'钝',
'迅',
'判',
'陷',
'处',
'碰',
'壁',
'然',
'热',
'解',
'寻',
'找',
'联',
'邦',
'州',
'予',
'适',
'具',
'骤',
'吸',
'七',
'团',
'另',
'龙',
'口',
'科',
'投',
'视',
'息',
'创',
'跳',
'跃',
'式',
'展',
'强',
'调',
'高',
'培',
'训',
'认',
'识',
'密',
'结',
'小',
'九',
'升',
'或',
'段',
'少',
'懂',
'习',
'互',
'贵',
'贱',
'请',
'注',
'语',
'构',
'偏',
'孝',
'父',
'母',
'始',
'票',
'否',
'制',
'还',
'缺',
'乏',
'际',
'电',
'影',
'摄',
'录',
'音',
'剪',
'辑',
'诸',
'趋',
'激',
'烈',
'造',
'奇',
'夺',
'起',
'直',
'追',
'医',
'药',
'李',
'珍',
'闻',
'屡',
'仕',
'寄',
'托',
'八',
'股',
'兴',
'趣',
'酷',
'爱',
'召',
'吴',
'英',
'司',
'董',
'德',
'·',
'葛',
'夫',
'邀',
'席',
'车',
'闲',
'防',
'施',
'配',
'套',
'存',
'鹅',
'洲',
'源',
'终',
'连',
'串',
'井',
'序',
'顾',
'犯',
'罪',
'讳',
'审',
'死',
'刑',
'笔',
'融',
'农',
'假',
'币',
'知',
'巧',
'律',
'规',
'村',
'秩',
'『',
'范',
'茅',
'迹',
'览',
'』',
'磁',
'球',
'孩',
'格',
'散',
'着',
'独',
'魅',
'莱',
'坞',
'千',
'模',
'翻',
'版',
'?',
'燃',
'汽',
'仅',
'守',
'—',
'路',
'易',
'斯',
'切',
'迪',
'阿',
'塞',
'瓦',
'萨',
'卡',
'里',
'罗',
'弗',
'哈',
'丹',
'尼',
'扎',
'胡',
'埃',
'索',
'库',
'纳',
'吉',
'莫',
'帕',
'锋',
'米',
'贝',
'耶',
'冈',
'玻',
'乌',
'布',
'苏',
'念',
'案',
'罚',
'较',
'战',
'略',
'均',
'贸',
'拓',
'5',
'份',
'去',
'阅',
'室',
'刊',
'晚',
'智',
'藏',
'突',
'破',
'借',
'架',
'办',
'沃',
'盟',
'昨',
'约',
'南',
'举',
'空',
'军',
'演',
'示',
'欢',
'迎',
'帮',
'助',
'7',
'叫',
'迈',
'菲',
'查',
'奋',
'剂',
'通',
'未',
'勇',
'曲',
'绕',
'桥',
'绝',
'《',
'嫂',
'》',
'警',
'魂',
'片',
'获',
'房',
'石',
'香',
'港',
'朝',
'蓬',
'勃',
'拼',
'搏',
'斗',
'神',
'写',
'2',
'春',
'季',
'招',
'兵',
'募',
'既',
'食',
'预',
'止',
'癌',
'症',
'城',
'引',
'项',
'懈',
'液',
'尾',
'9',
'%',
'氢',
'减',
'污',
'染',
'双',
'网',
'抽',
'封',
'差',
'亟',
'待',
'单',
'麦',
'果',
'∶',
'松',
'赢',
'测',
'析',
'迷',
'叶',
'钦',
'岁',
'刻',
'哲',
'思',
'虽',
'担',
'负',
'领',
'责',
'专',
'却',
'爸',
'劲',
'抗',
'艰',
'聘',
'仍',
'治',
'洋',
'尊',
'庄',
'志',
'回',
'忆',
'淳',
'朴',
'报',
'届',
'张',
'君',
'秋',
'剧',
'角',
'艺',
'校',
'坚',
'质',
'围',
'侧',
'缓',
'财',
'状',
'聚',
'渠',
'逐',
'靠',
'优',
'征',
'稿',
'截',
'句',
'晤',
'纠',
'纷',
'朋',
'坏',
'它',
'促',
'岗',
'标',
'织',
'践',
'邓',
'按',
'署',
'挥',
'核',
'●',
'承',
'键',
'街',
'巷',
'横',
'幅',
'悬',
'画',
'头',
'欣',
'慰',
...]
vocab2id
{'海': 0,
'钓': 1,
'比': 2,
'赛': 3,
'地': 4,
'点': 5,
'在': 6,
'厦': 7,
'门': 8,
'与': 9,
'金': 10,
'之': 11,
'间': 12,
'的': 13,
'域': 14,
'。': 15,
'这': 16,
'座': 17,
'依': 18,
'山': 19,
'傍': 20,
'水': 21,
'博': 22,
'物': 23,
'馆': 24,
'由': 25,
'国': 26,
'内': 27,
'一': 28,
'流': 29,
'设': 30,
'计': 31,
'师': 32,
'主': 33,
'持': 34,
',': 35,
'整': 36,
'个': 37,
'建': 38,
'筑': 39,
'群': 40,
'精': 41,
'美': 42,
'而': 43,
'恢': 44,
'宏': 45,
'但': 46,
'作': 47,
'为': 48,
'共': 49,
'产': 50,
'党': 51,
'员': 52,
'、': 53,
'人': 54,
'民': 55,
'公': 56,
'仆': 57,
'应': 58,
'当': 59,
'胸': 60,
'怀': 61,
'宽': 62,
'阔': 63,
'真': 64,
'正': 65,
'做': 66,
'到': 67,
'“': 68,
'先': 69,
'天': 70,
'下': 71,
'忧': 72,
'后': 73,
'乐': 74,
'”': 75,
'淡': 76,
'化': 77,
'名': 78,
'利': 79,
'得': 80,
'失': 81,
'和': 82,
'宠': 83,
'辱': 84,
'悲': 85,
'喜': 86,
'把': 87,
'改': 88,
'革': 89,
'大': 90,
'业': 91,
'摆': 92,
'首': 93,
'位': 94,
'样': 95,
'才': 96,
'能': 97,
'超': 98,
'越': 99,
'自': 100,
'我': 101,
'脱': 102,
'世': 103,
'俗': 104,
'有': 105,
'所': 106,
'发': 107,
'达': 108,
'家': 109,
'急': 110,
'救': 111,
'保': 112,
'险': 113,
'十': 114,
'分': 115,
'普': 116,
'及': 117,
'已': 118,
'成': 119,
'社': 120,
'会': 121,
'障': 122,
'体': 123,
'系': 124,
'重': 125,
'要': 126,
'组': 127,
'部': 128,
'日': 129,
'俄': 130,
'两': 131,
'政': 132,
'局': 133,
'都': 134,
'充': 135,
'满': 136,
'变': 137,
'数': 138,
'尽': 139,
'管': 140,
'关': 141,
'目': 142,
'前': 143,
'是': 144,
'历': 145,
'史': 146,
'最': 147,
'佳': 148,
'时': 149,
'期': 150,
'其': 151,
'脆': 152,
'弱': 153,
'性': 154,
'不': 155,
'言': 156,
'明': 157,
'克': 158,
'马': 159,
'尔': 160,
'女': 161,
'儿': 162,
'让': 163,
'娜': 164,
'今': 165,
'年': 166,
'读': 167,
'五': 168,
'级': 169,
'她': 170,
'班': 171,
'上': 172,
'3': 173,
'0': 174,
'多': 175,
'同': 176,
'学': 177,
'该': 178,
'委': 179,
'1': 180,
'长': 181,
'参': 182,
'加': 183,
'步': 184,
'行': 185,
'男': 186,
'轻': 187,
'也': 188,
'中': 189,
'沙': 190,
'特': 191,
'队': 192,
'教': 193,
'练': 194,
'佩': 195,
'雷': 196,
'拉': 197,
':': 198,
'支': 199,
'想': 200,
'胜': 201,
'因': 202,
'此': 203,
'出': 204,
'了': 205,
'努': 206,
'力': 207,
'种': 208,
'混': 209,
'乱': 210,
'面': 211,
'导': 212,
'致': 213,
'些': 214,
'使': 215,
'用': 216,
'者': 217,
'合': 218,
'法': 219,
'权': 220,
'益': 221,
'难': 222,
'以': 223,
'维': 224,
'护': 225,
'鲁': 226,
'宾': 227,
'确': 228,
'指': 229,
'对': 230,
'府': 231,
'控': 232,
'完': 233,
'全': 234,
'没': 235,
'事': 236,
'实': 237,
'根': 238,
'据': 239,
'向': 240,
'转': 241,
'敏': 242,
'感': 243,
'技': 244,
'术': 245,
'相': 246,
'总': 247,
'白': 248,
'于': 249,
';': 250,
'众': 251,
'议': 252,
'院': 253,
'令': 254,
'非': 255,
'常': 256,
'望': 257,
'将': 258,
'商': 259,
'卫': 260,
'星': 261,
'受': 262,
'威': 263,
'胁': 264,
'竞': 265,
'争': 266,
'损': 267,
'害': 268,
'育': 269,
'场': 270,
'每': 271,
'早': 272,
'6': 273,
'至': 274,
'8': 275,
'免': 276,
'费': 277,
'开': 278,
'放': 279,
'游': 280,
'泳': 281,
'等': 282,
'则': 283,
'增': 284,
'综': 285,
'服': 286,
'务': 287,
'延': 288,
'采': 289,
'取': 290,
'灵': 291,
'活': 292,
'收': 293,
'再': 294,
'看': 295,
'容': 296,
'图': 297,
'文': 298,
'并': 299,
'茂': 300,
'简': 301,
'短': 302,
'字': 303,
'准': 304,
'反': 305,
'映': 306,
'六': 307,
'族': 308,
'风': 309,
'土': 310,
'情': 311,
'传': 312,
'统': 313,
'各': 314,
'讲': 315,
'很': 316,
'哥': 317,
'伦': 318,
'亚': 319,
'号': 320,
'航': 321,
'飞': 322,
'机': 323,
'宇': 324,
'边': 325,
'进': 326,
'验': 327,
'继': 328,
'续': 329,
'抢': 330,
'修': 331,
'故': 332,
'二': 333,
'氧': 334,
'碳': 335,
'清': 336,
'除': 337,
'装': 338,
'置': 339,
'从': 340,
'剥': 341,
'削': 342,
'阶': 343,
'劳': 344,
'动': 345,
'生': 346,
'率': 347,
'低': 348,
'况': 349,
'占': 350,
'限': 351,
'剩': 352,
'余': 353,
'品': 354,
'足': 355,
'豪': 356,
'华': 357,
'需': 358,
'量': 359,
'扩': 360,
'现': 361,
'资': 362,
'条': 363,
'件': 364,
'榨': 365,
'价': 366,
'值': 367,
'供': 368,
'身': 369,
'求': 370,
'外': 371,
'又': 372,
'本': 373,
'新': 374,
'雇': 375,
'佣': 376,
'私': 377,
'来': 378,
'料': 379,
'集': 380,
'代': 381,
'表': 382,
'澳': 383,
'别': 384,
'区': 385,
'筹': 386,
'备': 387,
'第': 388,
'次': 389,
'午': 390,
'北': 391,
'京': 392,
'堂': 393,
'幕': 394,
'副': 395,
'理': 396,
'任': 397,
'钱': 398,
'琛': 399,
'词': 400,
'工': 401,
'经': 402,
'启': 403,
'临': 404,
'紧': 405,
'迫': 406,
'们': 407,
'道': 408,
'远': 409,
'希': 410,
'齐': 411,
'心': 412,
'协': 413,
'平': 414,
'稳': 415,
'过': 416,
'渡': 417,
'顺': 418,
'交': 419,
'接': 420,
'贡': 421,
'献': 422,
'济': 423,
'程': 424,
'界': 425,
'深': 426,
'信': 427,
'观': 428,
'必': 429,
'须': 430,
'微': 431,
'基': 432,
'础': 433,
'病': 434,
'好': 435,
'颈': 436,
'背': 437,
'躯': 438,
'干': 439,
'殖': 440,
'器': 441,
'可': 442,
'见': 443,
'龄': 444,
'市': 445,
'柔': 446,
'县': 447,
'试': 448,
'遍': 449,
'觉': 450,
'四': 451,
'节': 452,
'课': 453,
'饥': 454,
'饿': 455,
'消': 456,
'川': 457,
'省': 458,
'江': 459,
'油': 460,
'丰': 461,
'选': 462,
'豆': 463,
'奶': 464,
'复': 465,
'营': 466,
'养': 467,
'素': 468,
'贫': 469,
'血': 470,
'降': 471,
'百': 472,
'照': 473,
'只': 474,
'.': 475,
'4': 476,
'宗': 477,
'旨': 478,
'决': 479,
'定': 480,
'奉': 481,
'甘': 482,
'愿': 483,
'吃': 484,
'亏': 485,
'苦': 486,
'享': 487,
'困': 488,
'危': 489,
'留': 490,
'给': 491,
'己': 492,
'方': 493,
'便': 494,
'安': 495,
'初': 496,
'央': 497,
'形': 498,
'势': 499,
'快': 500,
'速': 501,
'策': 502,
'立': 503,
'研': 504,
'究': 505,
'派': 506,
'就': 507,
'提': 508,
'许': 509,
'富': 510,
'意': 511,
'味': 512,
'论': 513,
'话': 514,
'题': 515,
'书': 516,
'记': 517,
'粟': 518,
'光': 519,
'断': 520,
'他': 521,
'亲': 522,
'兄': 523,
'弟': 524,
'签': 525,
'!': 526,
'熟': 527,
'悉': 528,
'运': 529,
'士': 530,
'说': 531,
'贷': 532,
'款': 533,
'旦': 534,
'被': 535,
'推': 536,
'迟': 537,
'几': 538,
'月': 539,
'甚': 540,
'更': 541,
'考': 542,
'虑': 543,
'伍': 544,
'义': 545,
'气': 546,
'原': 547,
'惠': 548,
'象': 549,
'估': 550,
'像': 551,
'疤': 552,
'痕': 553,
'笨': 554,
'拙': 555,
'手': 556,
'针': 557,
'线': 558,
'周': 559,
'恩': 560,
'那': 561,
'送': 562,
'株': 563,
'万': 564,
'古': 565,
'青': 566,
'友': 567,
'谊': 568,
'红': 569,
'杉': 570,
'吧': 571,
'巴': 572,
'谈': 573,
'问': 574,
'印': 575,
'声': 576,
'宣': 577,
'称': 578,
'何': 579,
'三': 580,
'介': 581,
'入': 582,
'久': 583,
'赴': 584,
'西': 585,
'老': 586,
'访': 587,
'广': 588,
'职': 589,
'积': 590,
'极': 591,
'企': 592,
'监': 593,
'督': 594,
'如': 595,
'居': 596,
'子': 597,
'倘': 598,
'若': 599,
'客': 600,
'环': 601,
'境': 602,
'钝': 603,
'迅': 604,
'判': 605,
'陷': 606,
'处': 607,
'碰': 608,
'壁': 609,
'然': 610,
'热': 611,
'解': 612,
'寻': 613,
'找': 614,
'联': 615,
'邦': 616,
'州': 617,
'予': 618,
'适': 619,
'具': 620,
'骤': 621,
'吸': 622,
'七': 623,
'团': 624,
'另': 625,
'龙': 626,
'口': 627,
'科': 628,
'投': 629,
'视': 630,
'息': 631,
'创': 632,
'跳': 633,
'跃': 634,
'式': 635,
'展': 636,
'强': 637,
'调': 638,
'高': 639,
'培': 640,
'训': 641,
'认': 642,
'识': 643,
'密': 644,
'结': 645,
'小': 646,
'九': 647,
'升': 648,
'或': 649,
'段': 650,
'少': 651,
'懂': 652,
'习': 653,
'互': 654,
'贵': 655,
'贱': 656,
'请': 657,
'注': 658,
'语': 659,
'构': 660,
'偏': 661,
'孝': 662,
'父': 663,
'母': 664,
'始': 665,
'票': 666,
'否': 667,
'制': 668,
'还': 669,
'缺': 670,
'乏': 671,
'际': 672,
'电': 673,
'影': 674,
'摄': 675,
'录': 676,
'音': 677,
'剪': 678,
'辑': 679,
'诸': 680,
'趋': 681,
'激': 682,
'烈': 683,
'造': 684,
'奇': 685,
'夺': 686,
'起': 687,
'直': 688,
'追': 689,
'医': 690,
'药': 691,
'李': 692,
'珍': 693,
'闻': 694,
'屡': 695,
'仕': 696,
'寄': 697,
'托': 698,
'八': 699,
'股': 700,
'兴': 701,
'趣': 702,
'酷': 703,
'爱': 704,
'召': 705,
'吴': 706,
'英': 707,
'司': 708,
'董': 709,
'德': 710,
'·': 711,
'葛': 712,
'夫': 713,
'邀': 714,
'席': 715,
'车': 716,
'闲': 717,
'防': 718,
'施': 719,
'配': 720,
'套': 721,
'存': 722,
'鹅': 723,
'洲': 724,
'源': 725,
'终': 726,
'连': 727,
'串': 728,
'井': 729,
'序': 730,
'顾': 731,
'犯': 732,
'罪': 733,
'讳': 734,
'审': 735,
'死': 736,
'刑': 737,
'笔': 738,
'融': 739,
'农': 740,
'假': 741,
'币': 742,
'知': 743,
'巧': 744,
'律': 745,
'规': 746,
'村': 747,
'秩': 748,
'『': 749,
'范': 750,
'茅': 751,
'迹': 752,
'览': 753,
'』': 754,
'磁': 755,
'球': 756,
'孩': 757,
'格': 758,
'散': 759,
'着': 760,
'独': 761,
'魅': 762,
'莱': 763,
'坞': 764,
'千': 765,
'模': 766,
'翻': 767,
'版': 768,
'?': 769,
'燃': 770,
'汽': 771,
'仅': 772,
'守': 773,
'—': 774,
'路': 775,
'易': 776,
'斯': 777,
'切': 778,
'迪': 779,
'阿': 780,
'塞': 781,
'瓦': 782,
'萨': 783,
'卡': 784,
'里': 785,
'罗': 786,
'弗': 787,
'哈': 788,
'丹': 789,
'尼': 790,
'扎': 791,
'胡': 792,
'埃': 793,
'索': 794,
'库': 795,
'纳': 796,
'吉': 797,
'莫': 798,
'帕': 799,
'锋': 800,
'米': 801,
'贝': 802,
'耶': 803,
'冈': 804,
'玻': 805,
'乌': 806,
'布': 807,
'苏': 808,
'念': 809,
'案': 810,
'罚': 811,
'较': 812,
'战': 813,
'略': 814,
'均': 815,
'贸': 816,
'拓': 817,
'5': 818,
'份': 819,
'去': 820,
'阅': 821,
'室': 822,
'刊': 823,
'晚': 824,
'智': 825,
'藏': 826,
'突': 827,
'破': 828,
'借': 829,
'架': 830,
'办': 831,
'沃': 832,
'盟': 833,
'昨': 834,
'约': 835,
'南': 836,
'举': 837,
'空': 838,
'军': 839,
'演': 840,
'示': 841,
'欢': 842,
'迎': 843,
'帮': 844,
'助': 845,
'7': 846,
'叫': 847,
'迈': 848,
'菲': 849,
'查': 850,
'奋': 851,
'剂': 852,
'通': 853,
'未': 854,
'勇': 855,
'曲': 856,
'绕': 857,
'桥': 858,
'绝': 859,
'《': 860,
'嫂': 861,
'》': 862,
'警': 863,
'魂': 864,
'片': 865,
'获': 866,
'房': 867,
'石': 868,
'香': 869,
'港': 870,
'朝': 871,
'蓬': 872,
'勃': 873,
'拼': 874,
'搏': 875,
'斗': 876,
'神': 877,
'写': 878,
'2': 879,
'春': 880,
'季': 881,
'招': 882,
'兵': 883,
'募': 884,
'既': 885,
'食': 886,
'预': 887,
'止': 888,
'癌': 889,
'症': 890,
'城': 891,
'引': 892,
'项': 893,
'懈': 894,
'液': 895,
'尾': 896,
'9': 897,
'%': 898,
'氢': 899,
'减': 900,
'污': 901,
'染': 902,
'双': 903,
'网': 904,
'抽': 905,
'封': 906,
'差': 907,
'亟': 908,
'待': 909,
'单': 910,
'麦': 911,
'果': 912,
'∶': 913,
'松': 914,
'赢': 915,
'测': 916,
'析': 917,
'迷': 918,
'叶': 919,
'钦': 920,
'岁': 921,
'刻': 922,
'哲': 923,
'思': 924,
'虽': 925,
'担': 926,
'负': 927,
'领': 928,
'责': 929,
'专': 930,
'却': 931,
'爸': 932,
'劲': 933,
'抗': 934,
'艰': 935,
'聘': 936,
'仍': 937,
'治': 938,
'洋': 939,
'尊': 940,
'庄': 941,
'志': 942,
'回': 943,
'忆': 944,
'淳': 945,
'朴': 946,
'报': 947,
'届': 948,
'张': 949,
'君': 950,
'秋': 951,
'剧': 952,
'角': 953,
'艺': 954,
'校': 955,
'坚': 956,
'质': 957,
'围': 958,
'侧': 959,
'缓': 960,
'财': 961,
'状': 962,
'聚': 963,
'渠': 964,
'逐': 965,
'靠': 966,
'优': 967,
'征': 968,
'稿': 969,
'截': 970,
'句': 971,
'晤': 972,
'纠': 973,
'纷': 974,
'朋': 975,
'坏': 976,
'它': 977,
'促': 978,
'岗': 979,
'标': 980,
'织': 981,
'践': 982,
'邓': 983,
'按': 984,
'署': 985,
'挥': 986,
'核': 987,
'●': 988,
'承': 989,
'键': 990,
'街': 991,
'巷': 992,
'横': 993,
'幅': 994,
'悬': 995,
'画': 996,
'头': 997,
'欣': 998,
'慰': 999,
...}
获取每个句子的长度,并得到最大长度
def get_sequence_len(path):
= list()
sequence_len = 0
tmp_len with open(path,'r',encoding='utf-8') as f:
for line in f:
= line.strip()
line if len(line) == 0 :
# print(tmp_len)
sequence_len.append(tmp_len)= 0
tmp_len else:
+=1
tmp_len return np.array(sequence_len)
= get_sequence_len('./datasets/example.train')dev_sequence_len= get_sequence_len('./datasets/example.dev')test_sequence_len= get_sequence_len('./datasets/example.test') train_sequence_len
train_sequence_len,dev_sequence_len,test_sequence_len
(array([18, 35, 88, ..., 53, 65, 41]), array([69, 35, 54, ..., 46, 38, 29]), array([40, 39, 43, ..., 42, 29, 52]))
= max(max(train_sequence_len),max(dev_sequence_len),max(test_sequence_len)) max_length
max_length
577
读取数据,对不足最大长度的句子进行padding
def read_data(path,vocab2id,label2id,max_len): data_x = list() data_y = list() tmp_text = list() tmp_label = list() with open(path,'r', encoding='utf-8') as f: for line in f: line = line.strip() if len(line) ==0: # 数据集中以空行作为句子分隔符,说明前一个句子已经结束,tmp_text为vocab(id),tmp_label为label(id) # padding 至max_len tmp_text += [len(vocab2id)] * (max_len - len(tmp_text)) tmp_label += [0] * (max_len - len(tmp_label)) # 保存已经结束的句子并清空tmp data_x.append(tmp_text) data_y.append(tmp_label) tmp_text = list() tmp_label = list() else: # 将字符和标签转换为相应的id放入tmp # 根据数据格式,line[0]为vocab,line[1]为空格 # line[2:]为label tmp_text.append(vocab2id[line[0]]) tmp_label.append(label2id[line[2:]]) print('{} include sequences {}'.format(path,len(data_x))) return np.array(data_x), np.array(data_y)
= read_data("./datasets/example.train",vocab2id,label2id,max_length)dev_text,dev_label = read_data("./datasets/example.dev",vocab2id,label2id,max_length)test_text,test_label = read_data("./datasets/example.test",vocab2id,label2id,max_length) train_text,train_label
./datasets/example.train include sequences 20864./datasets/example.dev include sequences 2318./datasets/example.test include sequences 4636
0],train_label[0] train_text[
(array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
8, 11, 12, 13, 0, 14, 15, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465, 4465,
4465, 4465, 4465, 4465, 4465]),
array([0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0]))
讲数据通过tf.data.Dataset加载
Dataset可以看作是相同类型“元素”的有序列表,可以通过Iterator对其中的元素进行读取,通过初始化不同的initializer实现读取不同的数据
= tf.compat.v1.data.Dataset.from_tensor_slices((train_text,train_label,train_sequence_len))
train_dataset = train_dataset.batch(1) #指定读取数据时的batch_size train_dataset
= tf.compat.v1.data.Dataset.from_tensor_slices((dev_text,dev_label,dev_sequence_len))dev_dataset = dev_dataset.batch(1) #指定读取数据时的batch_size dev_dataset
= tf.compat.v1.data.Dataset.from_tensor_slices((test_text,test_label,test_sequence_len))test_dataset = test_dataset.batch(1) #指定读取数据时的batch_size test_dataset
= tf.compat.v1.data.Iterator.from_structure(train_dataset.output_types, train_dataset.output_shapes) iterator
WARNING:tensorflow:From <ipython-input-24-248b28ede763>:1: DatasetV1.output_types (from tensorflow.python.data.ops.dataset_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.compat.v1.data.get_output_types(dataset)`.
WARNING:tensorflow:From <ipython-input-24-248b28ede763>:2: DatasetV1.output_shapes (from tensorflow.python.data.ops.dataset_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.compat.v1.data.get_output_shapes(dataset)`.
#初始化不同的initializer,从X,Y,S读取的数据不同
= iterator.make_initializer(train_dataset)
train_initializer = iterator.make_initializer(dev_dataset)
dev_initializer = iterator.make_initializer(test_dataset)
test_initializer = iterator.get_next() #运行时每次读取一个batch_size的text,label和sequence_len X,Y,S
WARNING:tensorflow:From c:\users\ysilhouette\documents\pyenv\py_365_tf_2\lib\site-packages\tensorflow\python\data\ops\iterator_ops.py:336: Iterator.output_types (from tensorflow.python.data.ops.iterator_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.compat.v1.data.get_output_types(iterator)`.
WARNING:tensorflow:From c:\users\ysilhouette\documents\pyenv\py_365_tf_2\lib\site-packages\tensorflow\python\data\ops\iterator_ops.py:337: Iterator.output_shapes (from tensorflow.python.data.ops.iterator_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.compat.v1.data.get_output_shapes(iterator)`.
WARNING:tensorflow:From c:\users\ysilhouette\documents\pyenv\py_365_tf_2\lib\site-packages\tensorflow\python\data\ops\iterator_ops.py:339: Iterator.output_classes (from tensorflow.python.data.ops.iterator_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.compat.v1.data.get_output_classes(iterator)`.
命名实体识别模型构建
- 输入文本经过预处理后得到字符的id,
- 首先经过Embedding层得到字符向量,
- 然后经过BiLSTM层得到句子表示,
- 再经过CRF计算每个字符的标签得分,
- 对于每个字符,选取得分最高的标签作为该字符的类别。
= 5
embedding_size = 4 hidden_dim
# embedding层
with tf.compat.v1.variable_scope('embedding'): #随机生成字符向量
= tf.compat.v1.Variable(
embedding len(vocab2id)+1, embedding_size]),
tf.compat.v1.random_normal([= tf.compat.v1.float32
dtype
)= tf.compat.v1.nn.embedding_lookup(embedding,X) #将X中vocab的id转换为对应的字符向量 inputs
# BiLSTM隐藏层
# 前向lstm
= tf.compat.v1.nn.rnn_cell.LSTMCell(hidden_dim,reuse = tf.compat.v1.AUTO_REUSE)
lstm_fw_cell # 后向lstm
= tf.compat.v1.nn.rnn_cell.LSTMCell(hidden_dim,reuse = tf.compat.v1.AUTO_REUSE)
lstm_bw_cell # 组合成双向lstm
= tf.compat.v1.nn.bidirectional_dynamic_rnn(
(output,output_states)
lstm_fw_cell,
lstm_bw_cell,
inputs,
S,=tf.compat.v1.float32
dtype
)#list -> tensor [batch_size,max_len,hidden_dim * 2]
= tf.stack(output,axis=1)
output # -> [batch_size * max_len,hidden_dim * 2]
= tf.reshape(output,[-1,hidden_dim *2]) output
WARNING:tensorflow:From <ipython-input-28-215bd7d8a5e9>:12: bidirectional_dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `keras.layers.Bidirectional(keras.layers.RNN(cell))`, which is equivalent to this API
WARNING:tensorflow:From c:\users\ysilhouette\documents\pyenv\py_365_tf_2\lib\site-packages\tensorflow\python\ops\rnn.py:447: dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `keras.layers.RNN(cell)`, which is equivalent to this API
WARNING:tensorflow:From c:\users\ysilhouette\documents\pyenv\py_365_tf_2\lib\site-packages\keras\layers\legacy_rnn\rnn_cell_impl.py:979: calling Zeros.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
c:\users\ysilhouette\documents\pyenv\py_365_tf_2\lib\site-packages\keras\layers\legacy_rnn\rnn_cell_impl.py:901: UserWarning: `tf.nn.rnn_cell.LSTMCell` is deprecated and will be removed in a future version. This class is equivalent as `tf.keras.layers.LSTMCell`, and will be replaced by that in Tensorflow 2.0.
warnings.warn("`tf.nn.rnn_cell.LSTMCell` is deprecated and will be "
c:\users\ysilhouette\documents\pyenv\py_365_tf_2\lib\site-packages\keras\engine\base_layer_v1.py:1684: UserWarning: `layer.add_variable` is deprecated and will be removed in a future version. Please use `layer.add_weight` method instead.
warnings.warn('`layer.add_variable` is deprecated and '
# BiLSTM输出层
with tf.compat.v1.variable_scope('output'):
= tf.compat.v1.Variable(
W
tf.compat.v1.truncated_normal(=[hidden_dim *2 , len(label2id)],
shape=0,
mean=0.1),
stddev=tf.compat.v1.float32
dtype
)= tf.compat.v1.Variable(
B len(label2id)),
np.zeros(=tf.compat.v1.float32)
dtype#[batch_size * max_len,label_size]
= tf.matmul(output,W) + B
Y_out = tf.reshape(Y_out,[-1, max_length,len(label2id)]) #[batch_size,max_len,label_size] scores
scores
<tf.Tensor 'Reshape_1:0' shape=(None, 577, 7) dtype=float32>
Y
<tf.Tensor 'IteratorGetNext:1' shape=(None, 577) dtype=int32>
S
<tf.Tensor 'IteratorGetNext:2' shape=(None,) dtype=int32>
# CRF层
with tf.compat.v1.variable_scope('crf',reuse=tf.compat.v1.AUTO_REUSE):
= tf.compat.v1.get_variable('transition', [len(label2id),len(label2id)])
trans_matrix =tfa.text.crf_log_likelihood(scores,Y,S,trans_matrix)
log_likelihood,_ =tf.reduce_mean(-log_likelihood)
loss# optimizer = tf.keras.optimizers.SGD(learning_rate=0.5)
# train_op =optimizer.minimize(loss)#梯度下降法,学习率0.1
= tf.compat.v1.train.GradientDescentOptimizer(0.1).minimize(loss)#梯度下降法,学习率0.1
train_op = tf.compat.v1.train.Saver() #用来保存和加载模型
saver = int(1e8) #维护当前最小的Loss,初始化为一个较大的值 min_Loss
命名实体识别模型训练
- 通过训练集训练,并保存当前loss值最小的模型。
- 构建的模型抽象出来是一个包含计算和变量的图。定义变量时不会进行运算,也没有具体的值,变量在Session中进行初始化后才有值。
- 在Session中通过run可以执行图,进行相应的计算或取出对应的值。通过训练改变变量的值,最终可以得到模型需要的参数。
- 变量的值仅在一个Session中有效,通过saver保存变量后,可以在新的Session中通过saver加载变量,就无需再重新训练模型。
= tf.compat.v1.Session() # 创建一个Session
sess # 初始化所有变量
sess.run(tf.compat.v1.global_variables_initializer()) for epoch in range(100):
#初始化训练集和initializer
sess.run(train_initializer) for step in range(10): #使用了10个batch的数据
= sess.run(
tf_train_scores,tf_trans_matrix,Loss,_
[scores,trans_matrix,loss,train_op]# 执行训练过程
)
if Loss <min_Loss:
'model/my_model') # 保存当前loss最小的model
saver.save(sess,= Loss
min_Loss print("** epoch",epoch+1,"Loss",Loss)
** epoch 1 Loss 58.72455
** epoch 2 Loss 53.927124
** epoch 3 Loss 50.51535
** epoch 4 Loss 49.02472
** epoch 5 Loss 50.43283
** epoch 6 Loss 50.08667
** epoch 7 Loss 46.792816
** epoch 8 Loss 44.00418
** epoch 9 Loss 42.740723
** epoch 10 Loss 38.633057
** epoch 11 Loss 34.638123
** epoch 12 Loss 30.238342
** epoch 13 Loss 31.892944
** epoch 14 Loss 28.726074
** epoch 15 Loss 27.086182
** epoch 16 Loss 25.640747
** epoch 17 Loss 24.253967
** epoch 18 Loss 23.045715
** epoch 19 Loss 22.389526
** epoch 20 Loss 21.917236
** epoch 21 Loss 21.551575
** epoch 22 Loss 21.257202
** epoch 23 Loss 21.010925
** epoch 24 Loss 20.801147
** epoch 25 Loss 20.622559
** epoch 26 Loss 20.46753
** epoch 27 Loss 20.330994
** epoch 28 Loss 20.209717
** epoch 29 Loss 20.09906
** epoch 30 Loss 20.002686
** epoch 31 Loss 19.913574
** epoch 32 Loss 19.83197
** epoch 33 Loss 19.756409
** epoch 34 Loss 19.690308
** epoch 35 Loss 19.62616
** epoch 36 Loss 19.563904
** epoch 37 Loss 19.511597
** epoch 38 Loss 19.460754
** epoch 39 Loss 19.409851
** epoch 40 Loss 19.362366
** epoch 41 Loss 19.32257
** epoch 42 Loss 19.281921
** epoch 43 Loss 19.241943
** epoch 44 Loss 19.204895
** epoch 45 Loss 19.17163
** epoch 46 Loss 19.14154
** epoch 47 Loss 19.10846
** epoch 48 Loss 19.077393
** epoch 49 Loss 19.050842
** epoch 50 Loss 19.02295
** epoch 51 Loss 18.999817
** epoch 52 Loss 18.973328
** epoch 53 Loss 18.948425
** epoch 54 Loss 18.927612
** epoch 55 Loss 18.903809
** epoch 56 Loss 18.88678
** epoch 57 Loss 18.864624
** epoch 58 Loss 18.844116
** epoch 59 Loss 18.824219
** epoch 60 Loss 18.807495
** epoch 61 Loss 18.79132
** epoch 62 Loss 18.773804
** epoch 63 Loss 18.757812
** epoch 64 Loss 18.743103
** epoch 65 Loss 18.72815
** epoch 66 Loss 18.71283
** epoch 67 Loss 18.69812
** epoch 68 Loss 18.68335
** epoch 69 Loss 18.670227
** epoch 70 Loss 18.656555
** epoch 71 Loss 18.646484
** epoch 72 Loss 18.633667
** epoch 73 Loss 18.621033
** epoch 74 Loss 18.611145
** epoch 75 Loss 18.603027
** epoch 76 Loss 18.591614
** epoch 77 Loss 18.577148
** epoch 78 Loss 18.568176
** epoch 79 Loss 18.558899
** epoch 80 Loss 18.550049
** epoch 81 Loss 18.5401
** epoch 82 Loss 18.531128
** epoch 83 Loss 18.52301
** epoch 84 Loss 18.51294
** epoch 85 Loss 18.504944
** epoch 86 Loss 18.495544
** epoch 87 Loss 18.486633
** epoch 88 Loss 18.481384
** epoch 89 Loss 18.473328
** epoch 90 Loss 18.466125
** epoch 91 Loss 18.459839
** epoch 92 Loss 18.45227
** epoch 93 Loss 18.444885
** epoch 94 Loss 18.435303
** epoch 95 Loss 18.432373
** epoch 96 Loss 18.423462
** epoch 97 Loss 18.418274
** epoch 98 Loss 18.411194
** epoch 99 Loss 18.403381
** epoch 100 Loss 18.400818
命名实体识别模型评估
计算验证集f1_score并查看验证集预测结果。
- 精确率pression、召回率recall和f1_score
- 对于结果仅包括“正负”的二分类问题,
- “预测为正,实际也为正”被称为真阳性,“预测为正,实际为负”被称为假阳性,“预测为负,实际为正”被称为假阴性,
- 精确率定义为\(\frac {真阳性}{真阳性+假阳性}\),召回率定义为\(\frac{真阳性}{真阳性+假阴性}\),f1_score可以看作是精确率和召回率的一种加权平均,定义为$ 2*$。
- 对于多分类问题
- 既可以分别计算出每一类的精确率、召回率和f1_score
- 计算某一类时可认为该类为“正”,其他所有类为“负”,以此得到每一类的真阳性、假阳性和假阴性数量),再计算出f1_score的平均值,这种f1_score被称为macro-f1。
- 也可以计算出总的精确率和召回率
- 得到每一类的真阳性、假阳性和假阴性数量,分别求和得到总的数量),再计算出f1_score,这种f1_score被称为micro-f1
- 当预测结果未出现错误类别(即未包含在类别集合的类别)时,这种方式计算得到的精确率、召回率和f1_score都相等,值为$ $。
- 既可以分别计算出每一类的精确率、召回率和f1_score
# 初始化验证集的 initializer
sess.run(dev_initializer) = sess.run(
tf_dev_scores,tf_trans_matrix,tf_dev_text,tf_dev_label,tf_dev_sequence_len
[scores,trans_matrix,X,Y,S]
)# viterbi_decode每次处理一个句子,这里因为我们设定的batch_size为1,可以直接通过reshape将该维去掉
# 同时去掉句子的padding部分
= int(tf_dev_sequence_len)
tf_dev_sequence_len = tf_dev_text.reshape(max_length)[:tf_dev_sequence_len]
tf_dev_text
= tf_dev_scores.reshape(max_length,len(label2id))[:tf_dev_sequence_len]
tf_dev_scores = tf_dev_label.reshape(max_length)[:tf_dev_sequence_len]
tf_dev_label
# viterbi_decode传入的scores参数的shape应为[sequence_length,label_size],trans_matix应为[label_size,label_size]
= tfa.text.viterbi_decode(tf_dev_scores,tf_trans_matrix)
viterbi_sequence,_
= np.sum(np.equal(viterbi_sequence,tf_dev_label)) # 预测正确的标签数
correct_labels print("f1_score:{}".format(correct_labels / tf_dev_sequence_len))
print(viterbi_sequence)
f1_score:0.463768115942029
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0]
命名实体识别模型预测
加载模型
= tf.compat.v1.Session()
sess "model/my_model") #加载模型参数
saver.restore(sess,# 初始化测试集的initializer
sess.run(test_initializer)
= sess.run(
tf_test_scores,tf_test_matrix,tf_test_text,tf_test_label,tf_test_sequence_len
[scores,trans_matrix,X,Y,S]
)= int(tf_test_sequence_len)
tf_test_sequence_len = tf_test_text.reshape(max_length)[:tf_test_sequence_len]
tf_test_text
= tf_test_scores.reshape(max_length,len(label2id))[:tf_test_sequence_len]
tf_test_scores = tf_test_label.reshape(max_length)[:tf_test_sequence_len]
tf_test_label
= tfa.text.viterbi_decode(tf_test_scores,tf_trans_matrix)
viterbi_sequence,_
= [id2vocab[vocab] for vocab in tf_test_text] # id转换为vocab
example_test_text = [id2label[label] for label in viterbi_sequence] # id转换为label
example_prediction_label
print([id2vocab[tf_test_text[index]] + '' + id2label[viterbi_sequence[index]] for index in range(len(tf_test_text))])
sess.close()
INFO:tensorflow:Restoring parameters from model/my_model
['我I-ORG', '们I-ORG', '变I-ORG', '而O', '以O', '书O', '会O', '友O', ',O', '以O', '书O', '结O', '缘O', ',O', '把O', '欧O', '美O', '、O', '港O', '台O', '流B-ORG', '行I-ORG', '的I-ORG', '食I-ORG', '品I-ORG', '类I-ORG', '图I-ORG', '谱I-ORG', '、I-ORG', '画I-ORG', '册I-ORG', '、I-ORG', '工I-ORG', '具I-ORG', '书I-ORG', '汇I-ORG', '集I-ORG', '一I-ORG', '堂I-ORG', '。O']
example_test_text
['我',
'们',
'变',
'而',
'以',
'书',
'会',
'友',
',',
'以',
'书',
'结',
'缘',
',',
'把',
'欧',
'美',
'、',
'港',
'台',
'流',
'行',
'的',
'食',
'品',
'类',
'图',
'谱',
'、',
'画',
'册',
'、',
'工',
'具',
'书',
'汇',
'集',
'一',
'堂',
'。']
example_prediction_label
['I-ORG',
'I-ORG',
'I-ORG',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'O',
'B-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'I-ORG',
'O']
结果展示
= ['我','们','变','而','以','书','会','友',',','以','书','结','缘',',',
exam_test_text '把','欧','美','、','港','台','流','行','的','食','品','类','图','谱','、',
'画','册','、','工','具','书','汇','集','一','堂','。']
= ['O','O','O','O','O','O','O','O','O','O','O','O','O','O',
exam_prediction_label 'O','B-LOC','B-LOC','O','B-LOC','B-LOC','O','O','O','O','O','O','O','O','O',
'O','O','O','O','O','O','O','O','O','O','O']
def get_named_entity(text,labels):
= set() #去重,同一个实体只记录一次
named_entity_set = list()
named_entity_list = ''
cur_type= False
is_entity = ''
tmp_named_entity
for index in range(len(text)):
= labels[index]
label if label =='O' or label[:2] == 'B-': # 可能是前一个实体的结束
if is_entity == True: # 一个实体的结束
if tmp_named_entity not in named_entity_set:
named_entity_set.add(tmp_named_entity)'text':tmp_named_entity,'type':cur_type})
named_entity_list.append({
=False
is_entity =''
tmp_named_entity if label == 'O':
continue
= label[2:] # 若为'B-',说明此时是回一个实体的开头
cur_type =True
is_entity += text[index]
tmp_named_entity else: # 'I-'
+= text[index]
tmp_named_entity return named_entity_list
= get_named_entity(exam_test_text,exam_prediction_label)
named_entity_list print(named_entity_list)
[{'text': '欧', 'type': 'LOC'}, {'text': '美', 'type': 'LOC'}, {'text': '港', 'type': 'LOC'}, {'text': '台', 'type': 'LOC'}]
About ME
👋 读书城南,🤔 在未来面前,我们都是孩子~
- 📙 一个热衷于探索学习新方向、新事物的智能产品经理,闲暇时间喜欢coding💻、画图🎨、音乐🎵、学习ing~
👋 Social Media
🛠️ Blog: http://oceaneyes.top
⚡ PM导航: https://pmhub.oceangzy.top
☘️ CNBLOG: https://www.cnblogs.com/oceaneyes-gzy/
🌱 AI PRJ自己部署的一些算法demo: http://ai.oceangzy.top/
📫 Email: 1450136519@qq.com
💬 WeChat: OCEANGZY
💬 公众号: UncleJoker-GZY
👋 加入小组~
👋 感谢打赏~
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 OCAEN.GZY读书城南!