4

【NLP】hanlp

 2 years ago
source link: https://www.guofei.site/2021/05/01/hanlp.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【NLP】hanlp

2021年05月01日

Author: Guofei

文章归类: 2-4-NLP ,文章编号: 341


版权声明:本文作者是郭飞。转载随意,但需要标明原文链接,并通知本人
原文链接:https://www.guofei.site/2021/05/01/hanlp.html

Edit

介绍

python版本安装

pip install pyhanlp

# 命令行试试(分词)
hanlp segment <<< '欢迎新老师生前来就餐'
<dependency>
    <groupId>com.hankcs</groupId>
    <artifactId>hanlp</artifactId>
    <version>portable-1.7.5</version>
</dependency>

语言模型

一个句子出现的概率 P(s)=p(w1w2…wn)=p(w1∣w0)p(w2∣w0w1)…p(wk+1∣w0w1…wk)P(s)=p(w1w2…wn)=p(w1∣w0)p(w2∣w0w1)…p(wk+1∣w0w1…wk)

  • 其中 w0=w0= BOS (Begin Of Sentence)

上面的模型是极难计算的,因此做一些简化:

  • 假设满足马尔可夫性,也就是说 p(wt∣w0w1…wt−1)=P(wt∣wt−1)p(wt∣w0w1…wt−1)=P(wt∣wt−1) ,于是 P(s)=p(w1∣w0)p(w2∣w1)…p(wk+1∣wk)P(s)=p(w1∣w0)p(w2∣w1)…p(wk+1∣wk),称为 二元模型(bigram)
  • n元语法(n-gram) 指的是每个单词的概率取决于之前的 n-1 个单词
  • 1元语法(unigram) 其实就是记录每个单词的频率

平滑策略
n 越大,越有可能稀疏,我们可以用线性插值来平滑它。
例如 p(wt∣wt−1)p(wt∣wt−1) 很可能在语料中未出现,因此计算得到概率为0,但它的实际概率肯定不是0,这就是稀疏性。于是我们用一个平滑因子来平滑它 p(wt∣wt−1):=λp(wt∣wt−1)+(1−λ)p(wt)p(wt∣wt−1):=λp(wt∣wt−1)+(1−λ)p(wt)

分词

System.out.println(HanLP.segment("王国维和服务员"));
# [王国维/nr, 和/c, 服务员/n]

词典

TreeMap<String, CoreDictionary.Attribute> dictionary =
    IOUtil.loadDictionary("data/dictionary/CoreNatureDictionary.mini.txt");

dictionary.size()

理论

给出了4种切分方法,代码

  • 完全切分:找到全部可能的词,保留在词典种的那些
  • 正向最长匹配:从左到右做最长的匹配。bad case:商品, 和服, 务
  • 反向最长匹配:从右往左。bad case:项, 目的, 研究
  • 双向最长匹配。把正向和反向都做一遍,然后选出词数最少的(如果词数一样,选单字最少的)

上面的代码用的最粗暴的遍历,为了提升性能,显然有写做法:

应用

HanLP 对上面的算法做了封装,直接拿来用即可:(AC自动机+DoubleArrayTrie)

String dict1="src/test/CoreNatureDictionary.mini.txt"; // 用户可以自定义词典
HanLP.Config.ShowTermNature = false; //不显示词性
AhoCorasickDoubleArrayTrieSegment segment = new AhoCorasickDoubleArrayTrieSegment(dict1);
System.out.println(segment.seg("江西鄱阳湖干枯,中国最大淡水湖变成大草原"));

[江西, 鄱阳湖, 干枯, ,, 中国, 最, 大, 淡水湖, 变成, 大, 草原]

还可以显示词性(DoubleArrayTrie)

String dict1 = "src/main/data/dictionary/CoreNatureDictionary.mini.txt";
String dict2 = "src/main/data/dictionary/custom/上海地名.txt ns";
DoubleArrayTrieSegment segment = new DoubleArrayTrieSegment(dict1, dict2);

segment.enablePartOfSpeechTagging(true);    // 激活数词和英文识别
HanLP.Config.ShowTermNature = true;         // 显示词性


System.out.println(segment.seg("江西鄱阳湖干枯,中国最大淡水湖变成大草原"));
System.out.println(segment.seg("上海市虹口区大连西路550号SISU"));


// 显示每个词的词性:
for (Term term : segment.seg("上海市虹口区大连西路550号SISU")) {
    System.out.printf("单词:%s 词性:%s\n", term.word, term.nature);
}

停用词

去除停用词

繁简体互转

from pyhanlp import HanLP

print(HanLP.segment("王国维和服务员"))

您的支持将鼓励我继续创作!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK