Hanlp中使用纯JAVA实现CRF分词

与基于隐马尔可夫模型的最短路径分词、N-最短路径分词相比,基于条件随机场(CRF)的分词对未登录词有更好的支持。本文(HanLP)使用纯Java实现CRF模型的读取与维特比后向解码,内部特征函数采用 双数组Trie树(DoubleArrayTrie)储存,得到了一个高性能的中文分词器。

开源项目

本文代码已集成到HanLP中开源:http://hanlp.com/

CRF简介

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

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该合并的合并,得到:

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

新词识别

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

输出:

null表示新词。

转载自hankcs的博客

Hanlp中使用纯JAVA实现CRF分词的更多相关文章

  1. CRF分词的纯Java实现

    与基于隐马尔可夫模型的最短路径分词.N-最短路径分词相比,基于随机条件场(CRF)的分词对未登录词有更好的支持.本文(HanLP)使用纯Java实现CRF模型的读取与维特比后向解码,内部特征函数采用  ...

  2. JAVA从字符串中提取纯数字

    /** * 从字符串中提取纯数字 * @param str * @return */ public static String getNumeric(String str) { String regE ...

  3. 11大Java开源中文分词器的使用方法和分词效果对比,当前几个主要的Lucene中文分词器的比较

    本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...

  4. 11大Java开源中文分词器的使用方法和分词效果对比

    本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...

  5. HanLP中人名识别分析

    HanLP中人名识别分析 在看源码之前,先看几遍论文<基于角色标注的中国人名自动识别研究> 关于命名识别的一些问题,可参考下列一些issue: 名字识别的问题 #387 机构名识别错误 关 ...

  6. HanLP中人名识别分析详解

    HanLP中人名识别分析详解 在看源码之前,先看几遍论文<基于角色标注的中国人名自动识别研究> 关于命名识别的一些问题,可参考下列一些issue: l ·名字识别的问题 #387 l ·机 ...

  7. HanLP中的人名识别分析详解

    在看源码之前,先看几遍论文<基于角色标注的中国人名自动识别研究> 关于命名识别的一些问题,可参考下列一些issue: u u名字识别的问题 #387 u u机构名识别错误 u u关于层叠H ...

  8. hanlp中文自然语言处理的几种分词方法

    自然语言处理在大数据以及近年来大火的人工智能方面都有着非同寻常的意义.那么,什么是自然语言处理呢?在没有接触到大数据这方面的时候,也只是以前在学习计算机方面知识时听说过自然语言处理.书本上对于自然语言 ...

  9. 纯java配置SpringMVC

    一般情况下,我们会在web.xml下配置好Spring和SpringMVC,并指定好它们的配置文件 是最常用的也是最方便的方法 例如: web.xml <!-- The definition o ...

随机推荐

  1. JS数据的基本类型

    字符串   String 数字    Number 布尔    Boolean Null     空 Undefined Object   对象  Array 数组   json   function ...

  2. ssm 配置多个数据源

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  3. JavaScript中的函数-7---函数的作用,定义,调用

    JavaScript中的函数 函数也是对象,并且是javascript中的一等公民,可以用来创建普通对象.对象只是属性和值的集合 学习目标 1.掌握函数的作用 2.掌握函数的定义 3.掌握函数的调用 ...

  4. angular checkbox

    Error: ngModel:constexpr Non-Constant Expression 1.3版本 <input type="checkbox" ng-model= ...

  5. Gym - 101806T: Touch The Sky(贪心)

    Figure: The house floats up in the sky by balloons. This picture is also used in 2018 KAIST RUN Spri ...

  6. xdoj 1241--余神的rp机(区间dp)

    xdoj  1241---余神的rp机 核

  7. java-Arrays类

    1.Arrays类概述: - 针对数组进行操作的工具类. - 提供了排序,查找等功能. 2.成员方法: - 转换成字符串:public static String toString(int[] a)  ...

  8. C++学习(三)(C语言部分)之 基本数据类型

    基本数据类型 上期回顾 stdlib.h system,命令release MT导入ico文件 基本数据类型 整数 int浮点型(小数 实型) float double字符型 char 变量 常量速度 ...

  9. hdu4614 Vases and Flowers 线段树

    Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...

  10. maven settings.xml配置优化

    <?xml version="1.0" encoding="UTF-8"?> <settings> <localRepositor ...