hanlp库的使用!🐈

hanlp库的使用

1.安装

1
pip install hanlp

1.1 多任务模型

1
2
import hanlp
HanLP = hanlp.load(hanlp.pretrained.mtl.CLOSE_TOK_POS_NER_SRL_DEP_SDP_CON_ELECTRA_SMALL_ZH) # 世界最大中文语料库

通过代码将模型下载到本地

将模型移动到本地调用的位置

模型库:https://hanlp.hankcs.com/docs/api/hanlp/pretrained/mtl.html

1.2 单任务模型

多任务学习的优势在于速度和显存,然而精度往往不如单任务模型。所以,HanLP预训练了许多单任务模型并设计了优雅的流水线模式将其组装起来。

1
2
3
4
5
6
7
8
9
import hanlp
HanLP = hanlp.pipeline() \
.append(hanlp.utils.rules.split_sentence, output_key='sentences') \
.append(hanlp.load('FINE_ELECTRA_SMALL_ZH'), output_key='tok') \
.append(hanlp.load('CTB9_POS_ELECTRA_SMALL'), output_key='pos') \
.append(hanlp.load('MSRA_NER_ELECTRA_SMALL_ZH'), output_key='ner', input_key='tok') \
.append(hanlp.load('CTB9_DEP_ELECTRA_SMALL', conll=0), output_key='dep', input_key='tok')\
.append(hanlp.load('CTB9_CON_ELECTRA_SMALL'), output_key='con', input_key='tok')
HanLP('2021年HanLPv2.1为生产环境带来次世代最先进的多语种NLP技术。阿婆主来到北京立方庭参观自然语义科技公司。')

同多任务模型,将单任务模型保存到本地。

2.调用

2.1 多任务

2.1.1 批量分析

1
2
doc = HanLP(['2021年HanLPv2.1为生产环境带来次世代最先进的多语种NLP技术。', '阿婆主来到北京立方庭参观自然语义科技公司。'])
print(doc)

2.1.2 可视化

1
doc.pretty_print()

2.1.3 指定任务

分词:

1
HanLP('阿婆主来到北京立方庭参观自然语义科技公司。', tasks='tok').pretty_print()

粗颗粒度分词:

1
HanLP('阿婆主来到北京立方庭参观自然语义科技公司。', tasks='tok/coarse').pretty_print()

分词和PKU词性标注:

1
HanLP('阿婆主来到北京立方庭参观自然语义科技公司。', tasks='pos/pku').pretty_print()

粗颗粒度分词和PKU词性标注:

1
HanLP('阿婆主来到北京立方庭参观自然语义科技公司。', tasks=['tok/coarse', 'pos/pku'], skip_tasks='tok/fine').pretty_print()

分词和MSRA标准NER:

1
HanLP('阿婆主来到北京立方庭参观自然语义科技公司。', tasks='ner/msra').pretty_print()

分词、词性标注和依存句法分析:

1
2
3
4
5
doc = HanLP('阿婆主来到北京立方庭参观自然语义科技公司。', tasks=['pos', 'dep'])
doc.pretty_print()

转换为CoNLL格式:
print(doc.to_conll())

分词、词性标注和短语成分分析:

1
2
3
4
5
doc = HanLP('阿婆主来到北京立方庭参观自然语义科技公司。', tasks=['pos', 'con'])
doc.pretty_print()

将短语结构树以bracketed形式打印
print(doc['con'])

语义依存分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
sdp = hanlp.load('SEMEVAL16_ALL_ELECTRA_SMALL_ZH')
graph = sdp(["2021年", "HanLPv2.1", "为", "生产", "环境", "带来", "次", "世代", "最", "先进", "的", "多", "语种", "NLP", "技术", "。"])
print(graph)

或者:
import hanlp
HanLP = hanlp.pipeline() \
.append(hanlp.utils.rules.split_sentence, output_key='sentences').append(hanlp.load('D:/Python/new_pytorch/HanLP/single_task/tok/fine_electra_small'), output_key='tok')
tok = HanLP('2021年HanLPv2.1为生产环境带来次世代最先进的多语种NLP技术。阿婆主来到北京立方庭参观自然语义科技公司。', tasks='tok/fine')
print(tok["tok"][0])
sdp = hanlp.load('D:/Python/new_pytorch/HanLP/single_task/sdp/semeval16_sdp_electra_small')
graph = sdp(tok["tok"][0])
print(graph)

2.1.4 删除冗余任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import hanlp
from hanlp.components.mtl.multi_task_learning import MultiTaskLearning
from hanlp_common.document import Document

HanLP: MultiTaskLearning = hanlp.load(hanlp.pretrained.mtl.OPEN_TOK_POS_NER_SRL_DEP_SDP_CON_ELECTRA_SMALL_ZH)
tasks = list(HanLP.tasks.keys())
print(tasks) # Pick what you need from what we have
for task in tasks:
if task not in ('tok', 'pos'):
del HanLP[task]
# You can save it as a new component
# HanLP.save('path/to/new/component')
# HanLP.load('path/to/new/component')
print(HanLP.tasks.keys())
doc: Document = HanLP(['2021年HanLPv2.1为生产环境带来次世代最先进的多语种NLP技术。', 'up主来到北京立方庭参观自然语义科技公司。'])
print(doc)
doc.pretty_print()

2.1.5 自定义词典

先获取分词任务:

1
tok = HanLP['tok/fine']

以“商品和服务项目”为例,不做任何修改的情况:

1
2
3
4
5
tok.dict_force = tok.dict_combine = None
HanLP("商品和服务项目", tasks='tok/fine').pretty_print()

输出:
商品 和 服务 项目

强制模式(强制模式优先输出正向最长匹配到的自定义词条):

1
2
3
4
5
tok.dict_force = {'和服', '服务项目'}
HanLP("商品和服务项目", tasks='tok/fine').pretty_print()

输出:
商品 和服 务 项目

强制校正模式(匹配到的自定义词条替换为相应的分词结果):

1
2
3
4
5
tok.dict_force = {'和服务': ['和', '服务']}
HanLP("商品和服务项目", tasks='tok/fine').pretty_print()

输出:
商品 和 服务 项目

合并模式(合并模式的优先级低于统计模型,即dict_combine会在统计模型的分词结果上执行最长匹配并合并匹配到的词条):

1
2
3
4
5
6
tok.dict_force = None
tok.dict_combine = {'和服', '服务项目'}
HanLP("商品和服务项目", tasks='tok/fine').pretty_print()

输出:
商品 和 服务项目

2.1.6 单词位置

HanLP支持输出每个单词在文本中的原始位置,以便用于搜索引擎等场景。在词法分析中,非语素字符(空格、换行、制表符等)会被剔除,此时需要额外的位置信息才能定位每个单词:

1
2
3
4
5
6
7
tok.config.output_spans = True
sent = '2021 年\nHanLPv2.1 为生产环境带来次世代最先进的多语种NLP技术。'
word_offsets = HanLP(sent, tasks='tok/fine')['tok/fine']
print(word_offsets)

输出:
[['2021 年', 0, 6], ['HanLPv2.1', 7, 16], ['为', 17, 18], ['生产', 18, 20], ['环境', 20, 22], ['带来', 22, 24], ['次', 24, 25], ['世代', 25, 27], ['最', 27, 28], ['先进', 28, 30], ['的', 30, 31], ['多', 31, 32], ['语种', 32, 34], ['NLP', 34, 37], ['技术', 37, 39], ['。', 39, 40]]

2.2 单任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import hanlp
HanLP = hanlp.pipeline() \
.append(hanlp.utils.rules.split_sentence, output_key='sentences') \
.append(hanlp.load('FINE_ELECTRA_SMALL_ZH'), output_key='tok') \
.append(hanlp.load('CTB9_POS_ELECTRA_SMALL'), output_key='pos') \
.append(hanlp.load('MSRA_NER_ELECTRA_SMALL_ZH'), output_key='ner', input_key='tok') \
.append(hanlp.load('CTB9_DEP_ELECTRA_SMALL', conll=0), output_key='dep', input_key='tok')\
.append(hanlp.load('CTB9_CON_ELECTRA_SMALL'), output_key='con', input_key='tok')

HanLP('2021年HanLPv2.1为生产环境带来次世代最先进的多语种NLP技术。阿婆主来到北京立方庭参观自然语义科技公司。', tasks='tok/fine').pretty_print()

输出:
2021年 HanLPv2.1 为 生产 环境 带来 次 世代 最 先进 的 多 语种 NLP 技术 。
阿婆主 来到 北京 立方庭 参观 自然 语义 科技 公司 。

2.3 word2vec

2.3.1 加载模型

1
2
import hanlp
word2vec = hanlp.load("/HanLP/word2vec/MERGE_SGNS_BIGRAM_CHAR_300_ZH")

2.3.2 输出向量

1
print(word2vec('先进'))

2.3.3 计算相似度

1
2
3
import torch
print(torch.nn.functional.cosine_similarity(word2vec('先进'), word2vec('优秀'), dim=0))
print(torch.nn.functional.cosine_similarity(word2vec('先进'), word2vec('水果'), dim=0))

2.3.4 最相似单词

1
2
3
4
5
6
7
8
9
10
11
12
13
word2vec.most_similar('上海')

输出:
{'广州': 0.8630875945091248,
'北京': 0.8542779088020325,
'天津': 0.8537402153015137,
'深圳': 0.8526542782783508,
'成都': 0.8255313634872437,
'西安': 0.8215534687042236,
'杭州': 0.8207105398178101,
'厦门': 0.8186136484146118,
'昆明': 0.8184518814086914,
'武汉': 0.8055384755134583}

Word2Vec 通常无法处理 OOV 或短语

Doc2Vec 与 Word2Vec 模型相反,可以通过平均一组单词来创建矢量化表示。要为 OOV 和短语启用 Doc2Vec,请传递 doc2vec=True

1
2
3
4
5
6
7
8
9
10
11
12
13
word2vec.most_similar('非常寒冷', doc2vec=True)

输出:
{'寒冷': 0.7510591745376587,
'非常': 0.7510591745376587,
'很': 0.7312490344047546,
'比较': 0.6991080045700073,
'无比': 0.685967743396759,
'极其': 0.6834490895271301,
'十分': 0.6786675453186035,
'潮湿': 0.67008376121521,
'焦躁不安': 0.6699174642562866,
'阴冷': 0.6695235967636108}

2.4 mlm

1
2
3
from hanlp.components.lm.mlm import MaskedLanguageModel
mlm = MaskedLanguageModel()
mlm.load('bert-base-chinese')
1
2
3
4
5
6
7
8
9
10
11
12
13
mlm('生活的真谛是[MASK]。')

输出:
[{'美': 0.3407564163208008,
'爱': 0.2292439043521881,
'乐': 0.032554809004068375,
'人': 0.022961532697081566,
':': 0.01942446455359459,
'笑': 0.017893701791763306,
'-': 0.016441352665424347,
'玩': 0.016314353793859482,
'活': 0.014588544145226479,
'好': 0.013642454519867897}]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
mlm(['生活的真谛是[MASK]。', '巴黎是[MASK][MASK]的首都。'])

输出:
[[{'美': 0.3407564163208008,
'爱': 0.2292439043521881,
'乐': 0.032554809004068375,
'人': 0.022961532697081566,
':': 0.01942446455359459,
'笑': 0.017893701791763306,
'-': 0.016441352665424347,
'玩': 0.016314353793859482,
'活': 0.014588544145226479,
'好': 0.013642454519867897}],
[{'法': 0.5057310461997986,
'德': 0.08851869404315948,
'歐': 0.06904969364404678,
'巴': 0.04269423708319664,
'瑞': 0.039870887994766235,
'英': 0.03201477229595184,
'美': 0.02721557952463627,
'荷': 0.02194151096045971,
'中': 0.018307117745280266,
'欧': 0.011474725790321827},
{'國': 0.6981891989707947,
'国': 0.10869748890399933,
'洲': 0.03609883040189743,
'蘭': 0.013893415220081806,
'臘': 0.010245074518024921,
'士': 0.009544524364173412,
'盟': 0.00916974525898695,
'西': 0.005254795774817467,
'典': 0.004525361582636833,
'邦': 0.0044594407081604}]]

hanlp库的使用!🐈
https://yangchuanzhi20.github.io/2024/04/09/人工智能/NLP/库的使用/hanlp库的使用/
作者
白色很哇塞
发布于
2024年4月9日
许可协议