1词法分析PaddleNLP / examples / lexical_analysis

在这里插入图片描述
https://gitee.com/paddlepaddle/PaddleNLP/tree/develop/examples/lexical_analysis/#1-%E7%AE%80%E4%BB%8B

词法分析
1. 简介
词法分析任务的输入是一个字符串(我们后面使用『句子』来指代它),而输出是句子中的词边界和词性、实体类别。序列标注是词法分析的经典建模方式,我们使用基于 GRU 的网络结构学习特征,将学习到的特征接入 CRF 解码层完成序列标注。模型结构如下所示:

GRU-CRF-MODEL

输入采用 one-hot 方式表示,每个字以一个 id 表示
one-hot 序列通过字表,转换为实向量表示的字向量序列;
字向量序列作为双向 GRU 的输入,学习输入序列的特征表示,得到新的特性表示序列,我们堆叠了两层双向 GRU 以增加学习能力;
CRF 以 GRU 学习到的特征为输入,以标记序列为监督信号,实现序列标注。
快速开始
数据准备
我们提供了少数样本用以示例输入数据格式。执行以下命令,下载并解压示例数据集:

python download.py --data_dir ./  
训练使用的数据可以由用户根据实际的应用场景,自己组织数据。除了第一行是 text_a\tlabel 固定的开头,后面的每行数据都是由两列组成,以制表符分隔,第一列是 utf-8 编码的中文文本,以 \002 分割,第二列是对应每个字的标注,以 \002 分隔。我们采用 IOB2 标注体系,即以 X-B 作为类型为 X 的词的开始,以 X-I 作为类型为 X 的词的持续,以 O 表示不关注的字(实际上,在词性、专名联合标注中,不存在 O )。示例如下:

除\002了\002他\002续\002任\002十\002二\002届\002政\002协\002委\002员\002,\002马\002化\002腾\002,\002雷\002军\002,\002李\002彦\002宏\002也\002被\002推\002选\002为\002新\002一\002届\002全\002国\002人\002大\002代\002表\002或\002全\002国\002政\002协\002委\002员    p-B\002p-I\002r-B\002v-B\002v-I\002m-B\002m-I\002m-I\002ORG-B\002ORG-I\002n-B\002n-I\002w-B\002PER-B\002PER-I\002PER-I\002w-B\002PER-B\002PER-I\002w-B\002PER-B\002PER-I\002PER-I\002d-B\002p-B\002v-B\002v-I\002v-B\002a-B\002m-B\002m-I\002ORG-B\002ORG-I\002ORG-I\002ORG-I\002n-B\002n-I\002c-B\002n-B\002n-I\002ORG-B\002ORG-I\002n-B\002n-I
其中词性和专名类别标签集合如下表,包含词性标签 24 个(小写字母),专名类别标签 4 个(大写字母)。这里需要说明的是,人名、地名、机构名和时间四个类别,存在(PER / LOC / ORG / TIME 和 nr / ns / nt / t)两套标签,被标注为第二套标签的词,是模型判断为低置信度的人名、地名、机构名和时间词。开发者可以基于这两套标签,在四个类别的准确、召回之间做出自己的权衡。

标签	含义	标签	含义	标签	含义	标签	含义
n	普通名词	f	方位名词	s	处所名词	t	时间
nr	人名	ns	地名	nt	机构名	nw	作品名
nz	其他专名	v	普通动词	vd	动副词	vn	名动词
a	形容词	ad	副形词	an	名形词	d	副词
m	数量词	q	量词	r	代词	p	介词
c	连词	u	助词	xc	其他虚词	w	标点符号
PER	人名	LOC	地名	ORG	机构名	TIME	时间
模型训练
单卡训练
启动方式如下:

python train.py \
        --data_dir ./lexical_analysis_dataset_tiny \
        --model_save_dir ./save_dir \
        --epochs 10 \
        --batch_size 32 \
        --device gpu \
        # --init_checkpoint ./save_dir/final
其中参数释义如下:

data_dir: 数据集所在文件夹路径.
model_save_dir: 训练期间模型保存路径。
epochs: 模型训练迭代轮数。
batch_size: 表示每次迭代每张卡上的样本数目。
device: 训练使用的设备, 'gpu'表示使用GPU, 'xpu'表示使用百度昆仑卡, 'cpu'表示使用CPU。
init_checkpoint: 模型加载路径,通过设置init_checkpoint可以启动增量训练。
多卡训练
启动方式如下:

python -m paddle.distributed.launch --gpus "0,1"  train.py \
        --data_dir ./lexical_analysis_dataset_tiny \
        --model_save_dir ./save_dir \
        --epochs 10 \
        --batch_size 32 \
        --device gpu \
        # --init_checkpoint ./save_dir/final
模型评估
通过加载训练保存的模型,可以对测试集数据进行验证,启动方式如下:

python eval.py --data_dir ./lexical_analysis_dataset_tiny \
        --init_checkpoint ./save_dir/model_100.pdparams \
        --batch_size 32 \
        --device gpu
其中./save_dir/model_100.pdparams是训练过程中保存的参数文件,请更换为实际得到的训练保存路径。

模型导出
使用动态图训练结束之后,还可以将动态图参数导出成静态图参数,具体代码见export_model.py。静态图参数保存在output_path指定路径中。

运行方式:

python export_model.py --data_dir=./lexical_analysis_dataset_tiny --params_path=./save_dir/model_100.pdparams --output_path=./infer_model/static_graph_params
其中./save_dir/model_100.pdparams是训练过程中保存的参数文件,请更换为实际得到的训练保存路径。

params_path是指动态图训练保存的参数路径
output_path是指静态图参数导出路径。
导出模型之后,可以用于部署,deploy/python/predict.py文件提供了python部署预测示例。运行方式:

python deploy/python/predict.py --model_file=infer_model/static_graph_params.pdmodel --params_file=infer_model/static_graph_params.pdiparams
模型预测
对无标签数据可以启动模型预测:

python predict.py --data_dir ./lexical_analysis_dataset_tiny \
        --init_checkpoint ./save_dir/model_100.pdparams \
        --batch_size 32 \
        --device gpu
得到类似以下输出:

(大学, n)(学籍, n)(证明, n)(怎么, r)(, v)
(电车, n)(, u)(英文, nz)
(什么, r)(, v)(司法, n)(鉴定人, vn)
预训练模型
如果您希望使用已经预训练好了的LAC模型完成词法分析任务,请参考:

Lexical Analysis of Chinese

PaddleHub分词模型

如果您希望使用已经预训练好了的LAC模型完成词法分析任务,请参考:
https://github.com/baidu/lac

工具介绍
LAC全称Lexical Analysis of Chinese,是百度自然语言处理部研发的一款联合的词法分析工具,实现中文分词、词性标注、专名识别等功能。该工具具有以下特点与优势:

效果好:通过深度学习模型联合学习分词、词性标注、专名识别任务,词语重要性,整体效果F1值超过0.91,词性标注F1值超过0.94,专名识别F1值超过0.85,效果业内领先。
效率高:精简模型参数,结合Paddle预测库的性能优化,CPU单线程性能达800QPS,效率业内领先。
可定制:实现简单可控的干预机制,精准匹配用户词典对模型进行干预。词典支持长片段形式,使得干预更为精准。
调用便捷:支持一键安装,同时提供了Python、Java和C++调用接口与调用示例,实现快速调用和集成。
支持移动端: 定制超轻量级模型,体积仅为2M,主流千元手机单线程性能达200QPS,满足大多数移动端应用的需求,同等体积量级效果业内领先。
安装与使用
在此我们主要介绍Python安装与使用,其他语言使用:

C++
JAVA
Android
安装说明
代码兼容Python2/3

全自动安装: pip install lac

半自动下载:先下载http://pypi.python.org/pypi/lac/,解压后运行 python setup.py install

安装完成后可在命令行输入lac或lac --segonly,lac --rank启动服务,进行快速体验。

国内网络可使用百度源安装,安装速率更快:pip install lac -i https://mirror.baidu.com/pypi/simple

功能与使用
分词
代码示例:
from LAC import LAC

# 装载分词模型
lac = LAC(mode='seg')

# 单个样本输入,输入为Unicode编码的字符串
text = u"LAC是个优秀的分词工具"
seg_result = lac.run(text)

# 批量样本输入, 输入为多个句子组成的list,平均速率会更快
texts = [u"LAC是个优秀的分词工具", u"百度是一家高科技公司"]
seg_result = lac.run(texts)
输出:
【单样本】:seg_result = [LAC,,, 优秀,, 分词, 工具]
【批量样本】:seg_result = [[LAC,,, 优秀,, 分词, 工具], [百度,, 一家, 高科技, 公司]]
词性标注与实体识别
代码示例:
from LAC import LAC

# 装载LAC模型
lac = LAC(mode='lac')

# 单个样本输入,输入为Unicode编码的字符串
text = u"LAC是个优秀的分词工具"
lac_result = lac.run(text)

# 批量样本输入, 输入为多个句子组成的list,平均速率更快
texts = [u"LAC是个优秀的分词工具", u"百度是一家高科技公司"]
lac_result = lac.run(texts)
输出:
每个句子的输出其切词结果word_list以及对每个单词的标注tags_list,其格式为(word_list, tags_list)

【单样本】: lac_result = ([百度,, 一家, 高科技, 公司], [ORG, v, m, n, n])
【批量样本】:lac_result = [
                    ([百度,, 一家, 高科技, 公司], [ORG, v, m, n, n]),
                    ([LAC,,, 优秀,, 分词, 工具], [nz, v, q, a, u, n, n])
                ]
词性和专名类别标签集合如下表,其中我们将最常用的4个专名类别标记为大写的形式:

标签	含义	标签	含义	标签	含义	标签	含义
n	普通名词	f	方位名词	s	处所名词	nw	作品名
nz	其他专名	v	普通动词	vd	动副词	vn	名动词
a	形容词	ad	副形词	an	名形词	d	副词
m	数量词	q	量词	r	代词	p	介词
c	连词	u	助词	xc	其他虚词	w	标点符号
PER	人名	LOC	地名	ORG	机构名	TIME	时间
词语重要性
代码示例:
from LAC import LAC

# 装载词语重要性模型
lac = LAC(mode='rank')

# 单个样本输入,输入为Unicode编码的字符串
text = u"LAC是个优秀的分词工具"
rank_result = lac.run(text)

# 批量样本输入, 输入为多个句子组成的list,平均速率会更快
texts = [u"LAC是个优秀的分词工具", u"百度是一家高科技公司"]
rank_result = lac.run(texts)
输出:
【单样本】:rank_result = [['LAC', '是', '个', '优秀', '的', '分词', '工具'], 
                        [nz, v, q, a, u, n, n],[3, 0, 0, 2, 0, 3, 1]]
【批量样本】:rank_result = [
                    (['LAC', '是', '个', '优秀', '的', '分词', '工具'], 
                     [nz, v, q, a, u, n, n], [3, 0, 0, 2, 0, 3, 1]),  
                    (['百度', '是', '一家', '高科技', '公司'], 
                     [ORG, v, m, n, n], [3, 0, 2, 3, 1])
                ]
词语重要性各类别标签集合如下表,我们使用4-Level梯度进行分类:

标签	含义	常见于词性
0	query中表述的冗余词	p, w, xc ...
1	query中限定较弱的词	r, c, u ...
2	query中强限定的词	n, s, v ...
3	query中的核心词	nz, nw, LOC ...
定制化功能
在模型输出的基础上,LAC还支持用户配置定制化的切分结果和专名类型输出。当模型预测匹配到词典的中的item时,会用定制化的结果替代原有结果。为了实现更加精确的匹配,我们支持以由多个单词组成的长片段作为一个item。

我们通过装载词典文件的形式实现该功能,词典文件每行表示一个定制化的item,由一个单词或多个连续的单词组成,每个单词后使用'/'表示标签,如果没有'/'标签则会使用模型默认的标签。每个item单词数越多,干预效果会越精准。

词典文件示例

这里仅作为示例,展现各种需求情况下的结果。后续还将开放以通配符配置词典的模式,敬请期待。

春天/SEASON
花/n 开/v
秋天的风
落 阳
代码示例
from LAC import LAC
lac = LAC()

# 装载干预词典, sep参数表示词典文件采用的分隔符,为None时默认使用空格或制表符'\t'
lac.load_customization('custom.txt', sep=None)

# 干预后结果
custom_result = lac.run(u"春天的花开秋天的风以及冬天的落阳")
以输入“春天的花开秋天的风以及冬天的落阳”为例,原本输出结果为:
春天/TIME 的/u 花开/v 秋天/TIME 的/u 风/n 以及/c 冬天/TIME 的/u 落阳/n
添加示例中的词典文件后的结果为:
春天/SEASON 的/u 花/n 开/v 秋天的风/n 以及/c 冬天/TIME 的/u 落/n 阳/n
增量训练
我们也提供了增量训练的接口,用户可以使用自己的数据,进行增量训练,首先需要将数据转换为模型输入的格式,并且所有数据文件均为"UTF-8"编码:

1. 分词训练
数据样例

与大多数开源分词数据集格式一致,使用空格作为单词切分标记,如下所示:

LAC 是 个 优秀 的 分词 工具 。
百度 是 一家 高科技 公司 。
春天 的 花开 秋天 的 风 以及 冬天 的 落阳 。
代码示例
from LAC import LAC

# 选择使用分词模型
lac = LAC(mode = 'seg')

# 训练和测试数据集,格式一致
train_file = "./data/seg_train.tsv"
test_file = "./data/seg_test.tsv"
lac.train(model_save_dir='./my_seg_model/',train_data=train_file, test_data=test_file)

# 使用自己训练好的模型
my_lac = LAC(model_path='my_seg_model')
2. 词法分析训练
样例数据

在分词数据的基础上,每个单词以“/type”的形式标记其词性或实体类别。值得注意的是,词法分析的训练目前仅支持标签体系与我们一致的数据。后续也会开放支持新的标签体系,敬请期待。

LAC/nz 是/v 个/q 优秀/a 的/u 分词/n 工具/n 。/w
百度/ORG 是/v 一家/m 高科技/n 公司/n 。/w
春天/TIME 的/u 花开/v 秋天/TIME 的/u 风/n 以及/c 冬天/TIME 的/u 落阳/n 。/w
代码示例
from LAC import LAC

# 选择使用默认的词法分析模型
lac = LAC()

# 训练和测试数据集,格式一致
train_file = "./data/lac_train.tsv"
test_file = "./data/lac_test.tsv"
lac.train(model_save_dir='./my_lac_model/',train_data=train_file, test_data=test_file)

# 使用自己训练好的模型
my_lac = LAC(model_path='my_lac_model')
文件结构
.
├── python                      # Python调用的脚本
├── c++                         # C++调用的代码
├── java                        # Java调用的代码
├── Android                     # Android调用的示例
├── README.md                   # 本文件
└── CMakeList.txt               # 编译C++和Java调用的脚本
在论文中引用LAC
如果您的学术工作成果中使用了LAC,请您增加下述引用。我们非常欣慰LAC能够对您的学术工作带来帮助。

@article{jiao2018LAC,
	title={Chinese Lexical Analysis with Deep Bi-GRU-CRF Network},
	author={Jiao, Zhenyu and Sun, Shuqi and Sun, Ke},
	journal={arXiv preprint arXiv:1807.01882},
	year={2018},
	url={https://arxiv.org/abs/1807.01882}
}

PaddleHub分词模型
https://www.paddlepaddle.org.cn/hubdetail?name=lac&en_category=LexicalAnalysis

便捷地获取PaddlePaddle生态下的预训练模型,完成模型的管理和一键预测。配合使用Fine-tune API,可以基于大规模预训练模型快速完成迁移学习,让预训练模型能更好地服务于用户特定场景的应用
PaddleHub 首页文本 - 词法分析lac
lac
类别文本 - 词法分析
网络BiGRU+CRF
数据集百度自建数据集
模型概述
Lexical Analysis of Chinese,简称 LAC,是一个联合的词法分析模型,能整体性地完成中文分词、词性标注、专名识别任务。在百度自建数据集上评测,LAC效果:Precision=88.0%,Recall=88.7%,F1-Score=88.4%。该PaddleHub Module支持预测。
选择模型版本进行安装
$ hub install lac==2.2.0
 
LAC模型框架图

更多详情请参考LAC论文

命令行预测示例
$ hub run lac --input_text "今天是个好日子"
$ hub run lac --input_file test.txt --user_dict user.dict
test.txt 存放待分词文本, 如:

今天是个好日子     
今天天气晴朗      
user.dict为用户自定义词典,可以不指定,当指定自定义词典时,可以干预默认分词结果。

词典文件每行表示一个定制化的item,由一个单词或多个连续的单词组成,每个单词后使用'/'表示标签,如果没有'/'标签则会使用模型默认的标签。每个item单词数越多,干预效果会越精准。

春天/SEASON
花/n 开/v
秋天的风
落 阳  
Note

该PaddleHub Module使用词典干预功能时,依赖于第三方库pyahocorasick,请自行安装
请不要直接复制示例文本使用,复制后的格式可能存在问题
LAC API 说明
__init__(user_dict=None)
构造LAC对象

参数

user_dict(str): 自定义词典路径。如果需要使用自定义词典,则可通过该参数设置,否则不用传入该参数。
cut(text, use_gpu=False, batch_size=1, return_tag=True)
lac预测接口,预测输入句子的分词结果

参数

text(str or list): 待预测数据,单句预测数据(str类型)或者批量预测(list,每个元素为str
use_gpu(bool): 是否使用GPU预测,如果使用GPU预测,则在预测之前,请设置CUDA_VISIBLE_DEVICES环境变量,否则不用设置
batch_size(int): 批处理大小
return_tag(bool): 预测结果是否需要返回分词标签结果
lexical_analysis(texts=[], data={}, use_gpu=False, batch_size=1, return_tag=True)
该接口将会在未来版本被废弃,如有需要,请使用cut接口预测

lac预测接口,预测输入句子的分词结果

参数

texts(list): 待预测数据,如果使用texts参数,则不用传入data参数,二选一即可
data(dict): 预测数据,key必须为text,value是带预测数据。如果使用data参数,则不用传入texts参数,二选一即可。建议使用texts参数,data参数后续会废弃。
use_gpu(bool): 是否使用GPU预测
batch_size(int): 批处理大小
return_tag(bool): 预测结果是否需要返回分词标签结果
返回

results(list): 分词结果
context(trainable=False)
获取lac的预训练program以及program的输入输出变量

参数

trainable(bool): trainable=True表示program中的参数在Fine-tune时需要微调,否则保持不变
返回

inputs(dict): program的输入变量
outputs(dict): program的输出变量
main_program(Program): 带有预训练参数的program
set_user_dict(dict_path)
加载用户自定义词典

参数

dict_path(str ): 自定义词典路径
del_user_dict()
删除自定义词典

get_tags()
获取lac的标签

返回

tag_name_dict(dict): lac的标签
get_vocab_path()
获取预训练时使用的词汇表

返回

vocab_path(str): 词汇表路径
代码示例

import paddlehub as hub

lac = hub.Module(name="lac")
test_text = ["今天是个好日子", "天气预报说今天要下雨", "下一班地铁马上就要到了"]

results = lac.cut(text=test_text, use_gpu=False, batch_size=1, return_tag=True)

for result in results:
    print(result['word'])
    print(result['tag'])
LAC 服务部署
PaddleHub Serving可以部署一个在线词法分析服务,可以将此接口用于词法分析、在线分词等在线web应用。

第一步:启动PaddleHub Serving
运行启动命令:

$ hub serving start -c serving_config.json
serving_config.json的内容如下:

{
  "modules_info": {
    "lac": {
      "init_args": {
        "version": "2.2.0"
        "user_dict": "./test_dict.txt"
      }
    }
  },
  "port": 8866,
  "use_singleprocess": false,
  "workers": 2
}
其中user_dict含义为自定义词典路径,如果不使用lac自定义词典功能,则可以不填入。

这样就完成了一个词法分析服务化API的部署,默认端口号为8866。

NOTE: 如使用GPU预测,则需要在启动服务之前,请设置CUDA_VISIBLE_DEVICES环境变量,否则不用设置。

第二步:发送预测请求
配置好服务端,以下数行代码即可实现发送预测请求,获取预测结果

import request
import json

# 待预测数据
text = ["今天是个好日子", "天气预报说今天要下雨"]

# 设置运行配置
# 对应本地预测lac.cut(text=text, batch_size=1)
data = {"text": text, "batch_size": 1}

# 指定预测方法为lac并发送post请求,content-type类型应指定json方式
# HOST_IP为服务器IP
url = "http://HOST_IP:8866/predict/lac"
headers = {"Content-Type": "application/json"}
r = requests.post(url=url, headers=headers, data=json.dumps(data))

# 打印预测结果
print(json.dumps(r.json(), indent=4, ensure_ascii=False))
关于PaddleHub Serving更多信息参考服务部署
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值