:version: 3.2.1
:icons: font

== 快速入门

该章节介绍如何安装和简单使用mynlp的基础功能。

=== 安装

mynlp已经发布在Maven中央仓库中，所以只需要在Maven或者Gradle中引入mynlp.jar依赖即可。

.Gradle
[subs="attributes+"]
----
compile 'com.mayabot.mynlp:mynlp:{version}'
----

.Maven
[source,xml,subs="attributes+"]
----
<dependency>
  <groupId>com.mayabot.mynlp</groupId>
  <artifactId>mynlp</artifactId>
  <version>{version}</version>
</dependency>
----

因为资源文件较大，所以mynlp.jar包默认不包括资源文件（词典和模型文件）依赖。

懒人方案，通过引用mynlp-all依赖默认提供的资源词典，满足大部分需求。

.依赖 mynlp-all
[subs="attributes+"]
----
compile 'com.mayabot.mynlp:mynlp-all:{version}'
----

=== 词典和模型资源

.词典&模型资源列表
[cols="6,^1,^1,4"]
|===
|Gradle 坐标 | mynlp-all依赖 |文件大小 |说明

|com.mayabot.mynlp.resource:mynlp-resource-coredict:1.0.0
|Y
|18.2M
|核心词典（20w+词，500w+二元）

|com.mayabot.mynlp.resource:mynlp-resource-pos:1.0.0
|Y
|17.5M
|词性标注模型（感知机模型）

|com.mayabot.mynlp.resource:mynlp-resource-ner:1.0.0
|Y
|13.4M
|命名实体识别（人名识别、其他NER）

|com.mayabot.mynlp.resource:mynlp-resource-pinyin:1.1.0
|Y
|272K
|拼音词典、拼音切分模型

|com.mayabot.mynlp.resource:mynlp-resource-transform:1.0.0
|Y
|478K
|繁简体词典

|com.mayabot.mynlp.resource:mynlp-resource-cws:1.0.0
|N
|62.4M
|感知机分词模型

|com.mayabot.mynlp.resource:mynlp-resource-custom:1.0.0
|N
|2.19M
|自定义扩展词库

|===

<<<

根据实际的需要，按需引入资源包。

[source]
.一个Gradle引用的例子
----
compile 'com.mayabot.mynlp:mynlp:3.2.0'

// 核心词典
implementation 'com.mayabot.mynlp.resource:mynlp-resource-coredict:1.0.0'

// 词性标注
implementation 'com.mayabot.mynlp.resource:mynlp-resource-pos:1.0.0'

// 命名实体
implementation 'com.mayabot.mynlp.resource:mynlp-resource-ner:1.0.0'

// 拼音
implementation 'com.mayabot.mynlp.resource:mynlp-resource-pinyin:1.1.0'

// 繁简体转换
implementation 'com.mayabot.mynlp.resource:mynlp-resource-transform:1.0.0'

// 感知机分词模型
//   implementation 'com.mayabot.mynlp.resource:mynlp-resource-cws:1.0.0'

// 自定义扩展词库
//   implementation 'com.mayabot.mynlp.resource:mynlp-resource-custom:1.0.0'
----

=== 基本用法

==== 中文分词

Lexer是一个词法分析器的接口，通过Builder可以构建不同功能的分词器。

====
词法分析包括分词、词性标注、实体识别。
====

===== CORE分词器

CORE分词器是基于词典和二元语言模型的分词算法实现。

.CORE分词器
[source,java]
----
Lexer lexer = Lexers.coreBuilder()      // <1>
                     .withPos()      // <2>
                     .withPersonName()  // <3>
                     .build();

Sentence sentence = lexer.scan("mynlp是mayabot开源的中文NLP工具包。");

System.out.println(sentence.toList());
----
<1> CORE分词器构建器
<2> 开启词性标注功能
<3> 开启人名识别功能

.输出：
....
[mynlp/x, 是/v, mayabot/x, 开源/v, 的/u, 中文/nz, nlp/x, 工具包/n, 。/w]
....

===== 感知机分词

感知机分词器是基于BEMS标注的，结构化感知机分词算法实现。

.感知机分词器：
[source,java]
----
Lexer lexer = Lexers
                .perceptronBuilder()//<1>
                .withPos()
                .withPersonName()
                .withNer()//<2>
                .build();

System.out.println(lexer.scan("2001年，他还在纽约医学院工作时，在英国学术刊物《自然》上发表一篇论文"));
----
<1> 感知机分词器
<2> 开启命名实体识别

.输出：
....
2001年/t ,/w 他/r 还/d 在/p 纽约医学院/nt 工作/n 时/t ,/w 在/p 英国/ns 学术/n 刊物/n 《/w 自然/d 》/w 上/f 发表/v 一/m 篇/q 论文/n
....

===== Pipeline插件示例

Lexer是基于Pipeline结构实现的，通过Plugin机制可以任意扩展Lexer的功能和行为。下面的实例演示了自定义词典的插件。

.Lexer自定义扩展插件示例
[source,java]
----
MemCustomDictionary dictionary = new MemCustomDictionary();//<1>
dictionary.addWord("逛吃");
dictionary.rebuild(); // <2>

FluentLexerBuilder builder = Lexers.coreBuilder()
        .withPos()
        .withPersonName();

builder.with(new CustomDictionaryPlugin(dictionary));//<3>

Lexer lexer = builder.build();

System.out.println(lexer.scan("逛吃行动小组成立"));
----
<1> 一个自定义词典的实现
<2> 词典需要rebuild生效
<3> 配置CustomDictionaryPlugin插件

==== 拼音转换

===== 中文转拼音

.转换中文到对应的拼音
[source,java]
----
PinyinResult result = Pinyins.convert("招商银行,推出朝朝盈理财产品");

System.out.println(result.asString());//<1>
System.out.println(result.asHeadString(","));//<2>

result.fuzzy(true);//<3>
System.out.println(result.fuzzy(true).asString());

result.keepPunctuation(true);//<4>
//result.keepAlpha(true);
//result.keepNum(true);
//result.keepOthers(true);

System.out.println(result.asString());
----
<1> 完整拼音字符串
<2> 只输出拼音首字母，逗号分隔
<3> 输出模糊拼音后鼻音等
<4> 保留标点

.输出：
....
zhao shang yin hang tui chu chao chao ying li cai chan pin
z,s,y,h,t,c,c,c,y,l,c,c,p
zao sang yin han tui cu cao cao yin li cai can pin
zao sang yin han , tui cu cao cao yin li cai can pin
....

===== 拼音流切分

拼音流切分是指，将连续的拼音字母切分为一个一个原子单位。

.拼音流切分
[source,java]
----
System.out.println(PinyinSplits.split("nizhidaowozaishuoshenmema"));
----

.输出:
....
[ni, zhi, dao, wo, zai, shuo, shen, me, ma]
....

==== 文本分类

mynlp采用fasttext算法提供文本分类功能，你可以训练、评估自己的分类模型。

训练数据是个纯文本文件，每一行一条数据，词之间使用空格分开，每一行必须包含至少一个label标签。默认 情况下，是一个带`__label__`前缀的字符串。

....
__label__tag1  saints rally to beat 49ers the new orleans saints survived it all hurricane ivan

__label__积极  这个 商品 很 好 用 。
....

所以你的训练语料需要提前进行分词预处理。

在这里查看link:https://github.com/mayabot/mynlp/blob/master/modules/mynlp-classification/src/test/java/com/mayabot/mynlp/HotelCommentExampleTrain.java[HotelCommentExampleTrain.java]

[source,java]
----
// 训练参数
InputArgs trainArgs = new InputArgs();
trainArgs.setLoss(LossName.hs);
trainArgs.setEpoch(10);
trainArgs.setDim(100);
trainArgs.setLr(0.2);

FastText fastText = FastText.trainSupervised(trainFile, trainArgs);//<1>

FastText qFastText = fastText.quantize(); //<2>

//fastText.saveModel("example.data/hotel.model");<3>

fastText.test(testFile,1,0.0f,true);//<4>
System.out.println("--------------");
qFastText.test(testFile,1,0.0f,true);
----
<1> 训练一个分类模型
<2> 使用乘积量化压缩模型
<3> 保存模型文件
<4> 使用测试数据评估模型

.输出
....
Read file build dictionary ...
Read 0M words

Number of words:  14339
Number of labels: 2
Number of wordHash2Id: 19121
Progress: 100.00% words/sec/thread: Infinity arg.loss: 0.22259
Train use time 790 ms
pq 100%
compute_codes...
compute_codes success
F1-Score : 0.915167 Precision : 0.903553 Recall : 0.927083  __label__neg
F1-Score : 0.919708 Precision : 0.931034 Recall : 0.908654  __label__pos
N	400
P@1	0.918
R@1	0.918

--------------

F1-Score : 0.917526 Precision : 0.908163 Recall : 0.927083  __label__neg
F1-Score : 0.922330 Precision : 0.931373 Recall : 0.913462  __label__pos
N	400
P@1	0.920
R@1	0.920
....

==== 简繁转换

[source,java]
----
Simplified2Traditional s2t = TransformService.simplified2Traditional();
System.out.println(s2t.transform("软件和体育的艺术"));

Traditional2Simplified t2s = TransformService.traditional2Simplified();
System.out.println(t2s.transform("軟件和體育的藝術"));

----

.输出
....
軟件和體育的藝術
软件和体育的艺术
....

==== 简单文本摘要

文本摘要包含了两个简单TextRank的实现。

.关键字摘要
[source,java]
----
KeywordSummary keywordSummary = new KeywordSummary();
keywordSummary.keyword("text",10);
----

.句子摘要
[source,java]
----
SentenceSummary sentenceSummary = new SentenceSummary();
List<String> result = sentenceSummary.summarySentences(document, 10);
----

KeywordSummary和SentenceSummary内置了默认的分词实现，你可以配置自定义的Lexer对象,参加具体文档。
