CRF简介

CRF是序列标注场景中常用的模型,比HMM能利用更多的特征,比MEMM更能抵抗标记偏置的问题。

[gerative-discriminative.png]

CRF训练

这类耗时的任务,还是交给了用C++实现的CRF++。关于CRF++输出的CRF模型,请参考《CRF++模型格式说明》。

CRF解码

解码采用维特比算法实现。并且稍有改进,用中文伪码与白话描述如下:

首先任何字的标签不仅取决于它自己的参数,还取决于前一个字的标签。但是第一个字前面并没有字,何来标签?所以第一个字的处理稍有不同,假设第0个字的标签为X,遍历X计算第一个字的标签,取分数最大的那一个。

如何计算一个字的某个标签的分数呢?某个字根据CRF模型提供的模板生成了一系列特征函数,这些函数的输出值乘以该函数的权值最后求和得出了一个分数。该分数只是“点函数”的得分,还需加上“边函数”的得分。边函数在本分词模型中简化为f(s’,s),其中s’为前一个字的标签,s为当前字的标签。于是该边函数就可以用一个4*4的矩阵描述,相当于HMM中的转移概率。

实现了评分函数后,从第二字开始即可运用维特比后向解码,为所有字打上BEMS标签。

实例

还是取经典的“商品和服务”为例,首先HanLP的CRFSegment分词器将其拆分为一张表:

null表示分词器还没有对该字标注。

代码

上面说了这么多,其实我的实现非常简练:

标注结果

标注后将table打印出来:

最终处理

将BEMS该合并的合并,得到:

[商品/null, 和/null, 服务/null]

然后将词语送到词典中查询一下,没查到的暂时当作nx,并记下位置(因为这是个新词,为了表示它的特殊性,最后词性设为null),再次使用维特比标注词性:

[商品/n, 和/cc, 服务/vn]

新词识别

CRF对新词有很好的识别能力,比如:

CRFSegment segment = new CRFSegment();

segment.enablePartOfSpeechTagging(true);

System.out.println(segment.seg("你看过穆赫兰道吗"));

输出

CRF标注结果

你   S

看   S

过   S

穆   B

赫   M

兰   M

道   E

吗   S

[你/rr, 看/v, 过/uguo, 穆赫兰道/null, 吗/y]

null表示新词。

最新文章

  1. javascript的正则表达式学习
  2. 【SQL语句】update ... ... from ......
  3. DOM位置参数
  4. Domain Space
  5. C语言函数指针基础
  6. 关于WinRT中c++和c#相互调用的问题
  7. 如何在Html的div+css中去除<li>标签前面小黑点,和ul、LI部分属性方法
  8. poj 1966 Cable TV Network 顶点连通度
  9. 2732: [HNOI2012]射箭( 半平面交 )
  10. .Net Core 2.0生态(4):Entity Framework Core 2.0 特性介绍和使用指南
  11. su 和 sudo 命令的区别-转载
  12. OpenCV 初体验
  13. Linux学习笔记 软链接和硬链接
  14. 从word得到表格数据插入数据库(6位行业代码)
  15. lower_bound && upper_bound
  16. python学习 day01 基础介绍
  17. 01: 安装zabbix server
  18. Pwn with File结构体(四)
  19. 如何使用FLASHGOT下载网页FLASH
  20. selenium + python自动化测试unittest框架学习(五)webdriver的二次封装

热门文章

  1. 多路复用 阻塞/非阻塞IO模型 网络IO两个阶段
  2. 界面设计-Edit控件的Style设置
  3. ubantu 安装nginx HTTP反向代理服务器
  4. Java虚拟机的组成
  5. HDU 4704 Sum(隔板原理+组合数求和公式+费马小定理+快速幂)
  6. OpenVPN多用户配置
  7. 【opencv基础】imwrite函数与图像存储质量
  8. shell常用函数封装-main.sh
  9. flask中的request和response
  10. 数据结构HUFFman求权值