Skip to content
smithnlp edited this page Feb 15, 2018 · 10 revisions

FNLP入门教程

(by h4x3rotab

目录

1 快速入门

FNLP是一个致力于中文自然语言处理的开源项目,提供了进行自然语言处理的工具,包括分词、词性标注、句法分析、文本相似度计算等等,以及进行处理所需的数据集。从功能的角度而言,FNLP与著名的Python自然语言处理工具包NLTK较为类似,但后者对中文处理的能力较差。

FNLP采用Java编写,使得它可以轻松运行在各种不同的平台之上,不仅可以通过命令行调用,同时也可以十分便捷的集成到各种Java项目之中。

1.1 下载与编译

1.1.1 下载FNLP

FNLP是一个开源项目,其代码托管在Github.com之上。有多种方法从FNLP的Github页面下载最新源码。

  • 直接下载ZIP包

    进入Github中的FNLP项目首页,在页面右侧点击“Download ZIP”按钮,即可从Github下载到FNLP的最新源码包。得到的ZIP包解压缩后即可使用。用这种方法得到的是一份纯净的FNLP源码。

  • 直接利用Git下载

    对于习惯使用源码管理工具Git的用户,可以直接使用Git下载最新源码,命令如下:

      git clone https://github.com/xpqiu/fnlp.git
    

    采用这种方法得到的是一份包含Git仓库的源码,除了纯净的源码外,还可以利用Git的版本控制功能查阅每个文件的任何一个历史版本。Git是一个支持多人协作的源码版本管理系统,详情参见Wikipedia页面,或Git官方网站

除了源码文件,还需要下载FNLP语言模型文件。由于模型文件交大,不便于存放在源码库之中,请至Release页面下载,并将模型文件放在“models”目录。

  • seg.m 分词模型
  • pos.m 词性标注模型
  • dep.m 依存句法分析模型

下载后得到文件结构应与FNLP Github页面中呈现的一致,确认无误后即可开始编译运行。

1.1.2 编译FNLP

FNLP的编译并不复杂,但需要确保系统中已经安装好了编译所必备的工具。

  • 安装与配置JDK

    在编译前,确保已经正确安装并配置了JDK(版本需Java 1.6或以上)。配置后,PATH环境变量中应包含JDK目录,确保可以在命令行中运行javajavac工具。

      java -version
      javac -version
    
  • 安装与配置Maven

    Maven是一款先进的Java项目管理工具,用于项目的管理与编译,FNLP也采用Maven构建。完成了Maven的安装与配置后,确保可以在命令行中查看Maven版本号:

      mvn -version
    
  • 编译FNLP

    在命令行中进入FNLP的源码目录(即“README.md”所在的目录),执行如下命令进行编译:

      mvn install -Dmaven.test.skip=true
    

此时Maven会显示编译结果,如果见到类似如下的语句,说明编译成功。

[INFO] Reactor Summary:
[INFO] 
[INFO] fnlp-all ........................................... SUCCESS [  0.225 s]
[INFO] fnlp-core .......................................... SUCCESS [  1.417 s]
[INFO] fnlp-dev ........................................... SUCCESS [  0.182 s]
[INFO] fnlp-train ......................................... SUCCESS [  0.193 s]
[INFO] fnlp-app ........................................... SUCCESS [  0.246 s]
[INFO] fnlp-demo .......................................... SUCCESS [  0.153 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

通过这种方法,会编译四个Jar包:fnlp-corefnlp-devfnlp-trainfnlp-appfnlp-demo。它们分别位于源码目录中,各自对应目录中的"target"目录之中,例如fnlp-core的软件包位于: fnlp-core/target/fnlp-core-2.0-SNAPSHOT.jar

如果遇到错误“软件包 org.junit 不存在”,则可修改源码目录下的“pom.xml”文件。找到包含“junit”的依赖设置: junit junit 4.11 test 删除其中的scope元素所在行。完成编辑保存后,再次执行编译命令,即可顺利编译。

1.2 命令行调用

FNLP提供了命令行下的调用方法,这也是测试是否正确编译最简单的手段。下面简单地列举FNLP支持的部分功能与使用方式。 然而在执行前,还需要下载两个Java工具包。

假设命令行当前位于源码目录,且依赖的Jar包位于“libs”目录下

可以通过两种方式:

1 执行maven命令:

mvn dependency:copy-dependencies -DoutputDirectory=libs

这样jar包都会copy到工程目录下的libs里面

2 手动方式:

下载两个依赖包,下载后的工具包可以存放于“libs”目录。

FNLP目录结构

然后可以通过下列命令调用FNLP。

  • 中文分词

      java -Xmx1024m -Dfile.encoding=UTF-8 -classpath "fnlp-core/target/fnlp-core-2.1-SNAPSHOT.jar:libs/trove4j-3.0.3.jar:libs/commons-cli-1.2.jar" org.fnlp.nlp.cn.tag.CWSTagger -s models/seg.m "自然语言是人类交流和思维的主要工具,是人类智慧的结晶。"
    

    执行结果如下:

      自然 语言 是 人类 交流 和 思维 的 主要 工具 , 是 人类 智慧 的 结晶 。
    

    命令行运行截图

    参数“-Xmx1024m”设置Java虚拟机的可用内存为1024M。FNLP载入语言模型所需内存较大,因此可以利用此参数修改可用内存量。

    参数“-classpath ...”载入Jar文件。因此在引号内依次写下fnlp-core、trove、commons-cli的Jar包路径,使用英文冒号分隔文件名(Windows系统下用英文分号分隔文件名)。

    参数“org.fnlp.nlp.cn.tag.CWSTagger”指定了本次调用的类名,表示调用中文分词器CWSTagger。而后续的参数是根据所调用的类确定的,例如,CWSTagger需要通过“-s”参数指定语言模型文件“models/seg.m”。

    中文分词从输入文件:

      java -Xmx1024m -Dfile.encoding=UTF-8 -classpath "fnlp-core/target/fnlp-core-2.1-SNAPSHOT.jar:libs/trove4j-3.0.3.jar:libs/commons-cli-1.2.jar" org.fnlp.nlp.cn.tag.CWSTagger -f models/seg.m <input file> <output file>
    

    以"-f"代"-s"参数来分词从文件。

  • 中文词性标注

      java -Xmx1024m -Dfile.encoding=UTF-8 -classpath "fnlp-core/target/fnlp-core-2.1-SNAPSHOT.jar:libs/trove4j-3.0.3.jar:libs/commons-cli-1.2.jar" org.fnlp.nlp.cn.tag.POSTagger -s models/seg.m models/pos.m "周杰伦出生于台湾,生日为79年1月18日,他曾经的绯闻女友是蔡依林。"
    

    执行结果如下:

      周杰伦/人名 出生/动词 于/介词 台湾/地名 ,/标点 生日/名词 为/介词 79年/时间短语 1月/时间短语 18日/时间短语 ,/标点 他/人称代词 曾经/副词 的/结构助词 绯闻/名词 女友/名词 是/动词 蔡依林/人名 。/标点
    
  • 实体名识别

      java -Xmx1024m -Dfile.encoding=UTF-8 -classpath "fnlp-core/target/fnlp-core-2.1-SNAPSHOT.jar:libs/trove4j-3.0.3.jar:libs/commons-cli-1.2.jar" org.fnlp.nlp.cn.tag.NERTagger -s models/seg.m models/pos.m "詹姆斯·默多克和丽贝卡·布鲁克斯 鲁珀特·默多克旗下的美国小报《纽约邮报》的职员被公司律师告知,保存任何也许与电话窃听及贿赂有关的文件。"
    

    执行结果如下:

      {詹姆斯·默多克=人名, 鲁珀特·默多克旗=人名, 丽贝卡·布鲁克斯=人名, 纽约=地名, 美国=地名}
    

使用命令行的方式,不必编写Java代码即可体验到FNLP的强大功能,是进行功能测试与开发轻量级应用的绝佳方法。除了以上三种功能,FNLP还提供了更多的命令行接口,将在第3章节详细介绍。同时,下一个版本的FNLP也会开放更多的命令行接口供用户使用。

1.3 调用FNLP库

虽然FNLP提供了方便的命令行接口,当希望在Java项目中使用FNLP强大的语言处理能力,最佳方式仍然是以库的形式调用FNLP。在这一部分讲介绍如何在两种常见的IDE中引用FNLP,并简单的介绍库的使用方法。

1.3.1 在Eclipse项目中引用FNLP

Eclipse是老牌的Java IDE,在项目中引用FNLP非常简单(以JUNO 4.2版本为例)。

  • 添加库引用

    在IDE左侧的Package Explorer中选择项目名称,右击,在菜单中选择Build PathAdd External Archives...,则会弹出文件选择对话框,依次查找并添加下列文件:

    • fnlp-core-2.1-SNAPSHOT.jar
    • trove4j-3.0.3.jar
    • commons-cli-1.2.jar

    Add External Archives菜单

    这三个文件分别为FNLP的核心程序包,与两个库依赖的工具包。前者通过FNLP源码编译得到,而后者可以从互联网中下载。在命令行调用一节中已经提供了下载地址。

    完成以上操作后,在Package Explorer中的项目目录之下,可以在Referenced Libraries目录中看到以上三个Jar程序包,则成功引用了FNLP。

  • 修改最大内存量

    接下来修改程序的可用内存大小。由于FNLP的语言模型加载需要较大内存,Java默认的内存量通常不足,因此尽量设为1024MB或更大。

    Package Explorer中选择项目名称,右击,在菜单中选择Properties。在弹出的属性窗口左侧选择Run/Debug Settings,则会呈现项目所有的启动配置。选择当前的启动配置,并点击右侧Edit...,出现Edit Configuration窗口。选择Arguments栏,找到VM arguments输入框,并添加如下参数:

      -Xmx2048m
    

    其中2048m表示允许最大内存空间2048MB,可以按需要进行修改,最后点击确认离开配置窗口。

    修改内存量

  • 添加模型文件

    模型文件指词典、训练后的中文分词器、POS标注器等,它们位于FNLP源码目录下的“models”目录之中。将此目录复制到Eclipse项目目录之下即可。

    项目目录可以通过如下方法找到:在Package Explorer的项目名称上右击,选择Properties,出现属性窗口。窗口左侧选择Resource,则Location的内容即为项目目录。

    Eclipse项目文件结构

1.3.2 在Intellij IDEA中引用FNLP

Intellij IDEA是近几年流行起来的IDE,引用FNLP库也十分简单(以IDEA 13版本为例)。

  • 添加库引用

    对于单个模块的应用程序,建议在IDE左侧Project视图的项目目录中添加“libs”目录,查找并向此目录中复制如下Jar文件:

    • fnlp-core-2.1-SNAPSHOT.jar
    • trove4j-3.0.3.jar
    • commons-cli-1.2.jar

    以上三个文件的获取请参考上一节。完成上述操作后,可以在Project视图的“libs”目录中看到三个Jar文件。依次在文件上右键,选择Add as Library...,出现创建库窗口,在窗口中选择合适的配置,确认即可。

    对于多模块的应用程序,也可以在Project Structure窗口的Libraries中添加库引用。使用这种方法添加的引用,需要添加了如上三个Jar程序包后,在Libraries中的程序包上分别右键,选择Add to Modules...,选择合适模块,以便所有调用FNLP的模块可以得到引用。

  • 修改最大内存量

    FNLP在载入语言模型时需要内存量较大,建议设为1024MB以上。点击菜单RunEdit Configurations...,出现运行配置窗口。在窗口的左侧Application栏目中选择当前的应用程序后,在窗口中的VM options中添加如下参数:

      -Xmx2048m
    

    其中2040m表示最大内存为2048MB,可以按需要进行修改,最后点击确认离开配置窗口。

    Intellij IDEA 修改内存量

  • 添加模型文件

    FNLP的模型文件包含中文词典、已训练的分词器、POS标注器等,它们位于FNLP源码目录的“models”目录之中。只需把“models”目录复制到当前的项目目录即可。

    项目目录可以通过如下方式查找:在IDE的Project视图中,选择项目名称,右击并选择Show in Explorer(Windows系统)或Reveal in Finder(OS X系统)。

1.3.3 Hello World!

创建一个Java项目,参考上一节准备好环境配置,就可以顺利的调用FNLP进行自然语言处理了。接下来以一个控制台项目为例,一步一步实现最简单常见的任务。

FNLP提供了一系列中文处理工具,其中中文分词、词性标注、实体名识别等基础功能已经封装在工厂类CNFactory之中。CNFactory位于org.fnlp.nlp.cn包之中,经过初始化后就可以使用其提供的全部功能:

import org.fnlp.nlp.cn.CNFactory;
	
CNFactory factory = CNFactory.getInstance("models");

以上代码创建了一个CNFactory对象,并载入位于“models”目录下的模型文件。接下来就可以使用CNFactory的对象来进行各种中文语言处理任务。

  • 中文分词

    CNFactory.seg(String)方法提供了中文分词功能。在main函数中写入如下代码:

     public static void main(String[] args) throws Exception {
    
     	// 创建中文处理工厂对象,并使用“models”目录下的模型文件初始化
     	CNFactory factory = CNFactory.getInstance("models");
    
     	// 使用分词器对中文句子进行分词,得到分词结果
     	String[] words = factory.seg("关注自然语言处理、语音识别、深度学习等方向的前沿技术和业界动态。");
    
     	// 打印分词结果
     	for(String word : words) {
     		System.out.print(word + " ");
     	}
      	 System.out.println();
     }

    编译运行,就可以得到分词结果:

      关注 自然 语言 处理 、 语音 识别 、 深度 学习 等 方向 的 前沿 技术 和 业界 动态 。
    
  • 中文词性标注

    CNFactory.tag2String方法提供了中文词性标注功能。在main函数处写入如下代码:

     public static void main(String[] args) throws Exception {
    
     	// 创建中文处理工厂对象,并使用“models”目录下的模型文件初始化
     	CNFactory factory = CNFactory.getInstance("models");
    
     	// 使用标注器对中文句子进行标注,得到标注结果
     	String result = factory.tag2String("关注自然语言处理、语音识别、深度学习等方向的前沿技术和业界动态。");
    
     	// 显示标注结果
     	System.out.println(result);
     	
     }

    编译运行,可以得到标注结果:

      关注/动词 自然/名词 语言/名词 处理/动词 、/标点 语音/名词 识别/名词 、/标点 深度/形容词 学习/名词 等/省略词 方向/名词 的/结构助词 前沿/名词 技术/名词 和/并列连词 业界/名词 动态/名词 。/标点
    
  • 实体名识别

    CNFactory.ner(String)函数提供了实体名识别功能。在main函数中写入如下代码:

     public static void main(String[] args) throws Exception {
    
     	// 创建中文处理工厂对象,并使用“models”目录下的模型文件初始化
     	CNFactory factory = CNFactory.getInstance("models");
    
     	// 使用标注器对包含实体名的句子进行标注,得到结果
     	HashMap<String, String> result = factory.ner("詹姆斯·默多克和丽贝卡·布鲁克斯 鲁珀特·默多克旗下的美国小报《纽约邮报》的职员被公司律师告知,保存任何也许与电话窃听及贿赂有关的文件。");
    
     	// 显示标注结果
     	System.out.println(result);
    
     }

    编译运行,得到识别结果:

      {詹姆斯·默多克=人名, 鲁珀特·默多克旗=人名, 丽贝卡·布鲁克斯=人名, 纽约=地名, 美国=地名}
    

1.4 更多资料

快速入门这一章节简单的介绍了FNLP库的编译安装、命令行调用,以及使用FNLP库。相信在这一章的介绍后,读者已经对FNLP的使用有了初步的认识。除了本教程以外,还可以通过互联网上的许多资源来更深入地研究、学习FNLP,下面就列出了部分相关的资料。如果您愿意与大家分享学习FNLP的经验,欢迎联系我们,这个列表将会不停更新下去。

(仍在进一步整理中……)