【NLP】中文文本处理常用工具集[2024.10更新]

本文对比了XMNLP和Pycorrector在中文自然语言处理中的应用,特别关注了文本纠错功能,指出XMNLP虽全面但纠错能力有限,而Pycorrector在纠错领域更胜一筹。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工欲善其事,必先利其器,熟练的掌握几个趁手的工具,才能真正的用于解决实际问题。

下面的工具发展至今往往具备一个或多个任务处理能力,如jieba除了可用于分词还具备关键词提取功能,但以常用的应用场景进行归纳。

中文分词&词性标注

这两个任务通常是同时进行的

  • ‌jieba:2012年,基于《人民日报》构建了词典,分词时将词典转换为前缀字典树,采用最大匹配算法查找最大切分组合,若遇到未登录词(OOV),则基于训练完成的HMM进行分词。提供多种分词模式,对于一般的场景足够使用,属于老牌健将;缺点是对于新词和网络用语的识别效果比较差。
  • SnowNLP:2012年,最开始是在jieba的基础上增加了情感分析,发展至今已具备文本分类、拼音转换、繁简转换、文本断句、关键词提取、文本摘要等功能。
    教程
  • ‌LAC:百度出品,感觉比较好用【推荐】

依存句法分析

  • ‌Spacy:画图很棒

命名实体识别

  • ‌LAC+自定义词典:配合自定义词典准确率很高
  • Bert+CRF:能解决前者不能识别新词的问题,接近SOTA的性能。

关系抽取

  • ‌DeepKE:工具,浙大开发,涵盖多种深度学习模型,如BERT,CNN,Transformer等,目前还支持LLM了
  • PURE:算法,pipleline方向的经典算法;
  • TPlinker:算法,Joint式的,目前基本上是Joint的天下

标注工具

  • ‌YEDDA:若只实体抽取,则很不错
  • ‌MarkTOOL:关系抽取首选,国产之光,免费好用。

标点符号恢复

  • auto_punc:百度出品

文本纠错

文本纠错是一个很基础又比较难的任务。

  • pycorrector:持续更新的一个工具,有很多算法模型可以选择,目前github 4.5K star,属于中文纠错领域最热门的一个工具
import pycorrector

corrected_sent, detail = pycorrector.correct('客户反映发动机故障等亮')
print(corrected_sent, detail)

输出:
客户反映发动机故障灯亮 [(‘等亮’, ‘灯亮’, 9, 11)]

  • xmnlp:是中文领域内的一个比较综合的工具,包含了分词,文本纠错等功能。
    请添加图片描述
import xmnlp
import datetime
xmnlp.set_model(r'F:\pretrained_model\xmnlp-onnx-models')

'''
python 3.7版本,程序执行的结果可能有问题,
python3.8版本,程序执行结果正常
注意文件名不要设置成xmnlp.py会报错!
'''

# demo演示集合

text = "xmnlp 是一款开箱即用的轻量级中文自然语言处理工具🔧。"
text2 = "现任美国总统是拜登。"

# 1.中文分词功能
# (默认),基于逆向最大匹配来分词,采用 RoBERTa + CRF 来进行新词识别。
print(xmnlp.seg(text))
# 基于逆向最大匹配来分词,不包含新词识别,速度较快。
print(xmnlp.fast_seg(text))
# 基于 RoBERTa + CRF 模型,速度较慢。当前深度接口只支持简体中文,不支持繁体。
print(xmnlp.deep_seg(text))


# 2.词性标注功能
print(xmnlp.tag(text))
# 基于逆向最大匹配,不包含新词识别,速度较快。
print(xmnlp.fast_tag(text))
# 基于 RoBERTa + CRF 模型,速度较慢。当前深度接口只支持简体中文,不支持繁体。
print(xmnlp.deep_tag(text))


# 3.命名实体识别
'''
命名体识别,支持识别的实体类型为:
TIME:时间
LOCATION:地点
PERSON:人物
JOB:职业
ORGANIZAIRION:机构
'''
print(xmnlp.ner(text2))

# 4.关键字提取
# 从文本中提取关键词,基于 Textrank 算法。
'''
参数:
text:文本输入
k:返回关键词的个数
stopword:是否去除停用词
allowPOS:配置允许的词性
'''
text3 = """自然语言处理: 是人工智能和语言学领域的分支学科。
    ...: 在这此领域中探讨如何处理及运用自然语言;自然语言认知则是指让电脑“懂”人类的
    ...: 语言。
    ...: 自然语言生成系统把计算机数据转化为自然语言。自然语言理解系统把自然语言转化
    ...: 为计算机程序更易于处理的形式。"""
print(xmnlp.keyword(text3))

# 5.关键句提取
# 从文本中提取关键句,基于 Textrank 算法。
'''
参数:
text:文本输入
k:返回关键词的个数
stopword:是否去除停用词
'''
print(xmnlp.keyphrase(text3, k=2))

# 6.情感识别
text = '这本书真不错,下次还要买'
print(xmnlp.sentiment(text))

# 7.文本转拼音
text = '自然语言处理'
print(xmnlp.pinyin(text))

# 8.提取文本部首
print(xmnlp.radical(text))

# 9.文本纠错
'''
参数:
text:输入文本
suggest:是否返回建议词
k:返回建议词的个数
max_k:拼音搜索最大次数(建议保持默认值)
'''
text = "不能适应体育专业选拔人材的要求"
print(xmnlp.checker(text))

# 10.句向量
'''
SentenceVector 初始化函数
model_dir: 模型保存地址,默认加载 xmnlp 提供的模型权重
genre: 内容类型,目前支持 ['通用', '金融', '国际'] 三种
max_length: 输入文本的最大长度,默认 512
以下是 SentenceVector 的三个成员函数

xmnlp.sv.SentenceVector.transform(self, text: str) -> np.ndarray
xmnlp.sv.SentenceVector.similarity(self, x: Union[str, np.ndarray], y: Union[str, np.ndarray]) -> float
xmnlp.sv.SentenceVector.most_similar(self, query: str, docs: List[str], k: int = 1, **kwargs) -> List[Tuple[str, float]]
'''
import numpy as np
from xmnlp.sv import SentenceVector


query = '我想买手机'
docs = [
    '我想买苹果手机',
    '我喜欢吃苹果'
]

sv = SentenceVector(genre='通用')
for doc in docs:
    print('doc:', doc)
    print('similarity:', sv.similarity(query, doc))
print('most similar doc:', sv.most_similar(query, docs))
print('query representation shape:', sv.transform(query).shape)

输出:
Lazy load lexical…
[‘xmnlp’, ‘是’, ‘一款’, ‘开箱’, ‘即用’, ‘的’, ‘轻量级’, ‘中文’, ‘自然语言’, ‘处理’, ‘工具’, ‘🔧’, ‘。’]
[‘xmnlp’, ‘是’, ‘一款’, ‘开箱’, ‘即’, ‘用’, ‘的’, ‘轻量级’, ‘中文’, ‘自然语言’, ‘处理’, ‘工具’, ‘🔧’, ‘。’]
[‘xmnlp’, ‘是’, ‘一款’, ‘开箱’, ‘即’, ‘用’, ‘的’, ‘轻量级’, ‘中文’, ‘自然’, ‘语言’, ‘处理’, ‘工具’, ‘🔧’, ‘。’]
[(‘xmnlp’, ‘eng’), (‘是’, ‘v’), (‘一款’, ‘m’), (‘开箱’, ‘n’), (‘即用’, ‘v’), (‘的’, ‘u’), (‘轻量级’, ‘b’), (‘中文’, ‘nz’), (‘自然语言’, ‘l’), (‘处理’, ‘v’), (‘工具’, ‘n’), (‘🔧’, ‘x’), (‘。’, ‘x’)]
[(‘xmnlp’, ‘eng’), (‘是’, ‘v’), (‘一款’, ‘m’), (‘开箱’, ‘n’), (‘即’, ‘v’), (‘用’, ‘p’), (‘的’, ‘uj’), (‘轻量级’, ‘b’), (‘中文’, ‘nz’), (‘自然语言’, ‘l’), (‘处理’, ‘v’), (‘工具’, ‘n’), (‘🔧’, ‘x’), (‘。’, ‘x’)]
[(‘xmnlp’, ‘x’), (‘是’, ‘v’), (‘一款’, ‘m’), (‘开箱’, ‘v’), (‘即’, ‘v’), (‘用’, ‘p’), (‘的’, ‘u’), (‘轻量级’, ‘b’), (‘中文’, ‘nz’), (‘自然’, ‘n’), (‘语言’, ‘n’), (‘处理’, ‘v’), (‘工具’, ‘n’), (‘🔧’, ‘w’), (‘。’, ‘w’)]
[(‘美国’, ‘LOCATION’, 2, 4), (‘总统’, ‘JOB’, 4, 6), (‘拜登’, ‘PERSON’, 7, 9)]
[(‘自然语言’, 2.8920740242414), (‘系统’, 1.5495636532565644), (‘领域’, 1.1162693207905752), (‘人类’, 1.0519329564403876), (‘语言’, 1.0502996716485162), (‘生成’, 1.0501464978363533), (‘认知’, 0.9545588302125269), (‘指’, 0.9483085210979528), (‘转’, 0.9470901879922168), (‘懂’, 0.9398191745259709)]
[‘…:为计算机程序更易于处理的形式’, ‘自然语言理解系统把自然语言转化’]
Lazy load sentiment…
(0.027278266847133636, 0.9727216958999634)
(Lazy Load) Loading model…
[‘Zi’, ‘ran’, ‘yu’, ‘yan’, ‘chu’, ‘li’]
(Lazy Load) Loading model…
[‘自’, ‘灬’, ‘讠’, ‘言’, ‘夂’, ‘王’]
Lazy load checker…
{(11, ‘材’): [(‘才’, 1.5083076357841492), (‘材’, 1.0015756158391014), (‘裁’, 1.000024348288207), (‘员’, 0.38437268137931824), (‘数’, 0.02577337808907032)]}
doc: 我想买苹果手机
similarity: 0.68668646
doc: 我喜欢吃苹果
similarity: 0.3020076
most similar doc: [(‘我想买苹果手机’, 16.255546509314417)]
query representation shape: (312,)

PK一下:
xmnlp是一个综合性的工具,整体还是不错的,但在文本纠错任务上,它用的是人民日报的预料进行训练的,也就是说对于一些常见的错误还可以,但是对于一些特定领域的问题就不是很好了,比如“客户反映发动机故障等亮”,它识别不了。但pycorrector可以,相比较而言,在文本纠错领域pycorrector更牛逼一些,但xmnlp有很多开箱即用的工具,也很不错。

关键词提取

  • 英文关键词:Spacy+pytextrank
  • 中文关键词:Spacy+pytextrank4zh

问答系统

  • Rasa:很不错,很友好。

总结

这个表随着对工具的认识增加,持续更新,✔表示某工具支持某任务

工具中文分词词性标注句法分析分本分类文本纠错实体抽取关系抽取情感分类备注
Jieba适合中文分词
LAC
Spacy综合性工具
pycorrector文本纠错工具
xmnlp综合性工具

参考

《TextRank中文,英文关键词提取》https://blog.youkuaiyun.com/Cocktail_py/article/details/113339568?utm_source=app&app_version=5.0.1&code=app_1562916241&uLinkId=usr1mkqgl919blen

### 文本分组的操作与方法 在处理文本时,可以通过正则表达式的分组功能实现复杂的模式匹配提取需求。以下是几种常用的分组方式及其具体应用: #### 1. **非捕获分组** 非捕获分组允许对正则表达式的一部分进行逻辑分组而不保存其匹配的内容。这通常用于控制优先级或重复次数。 语法为 `(?:re)`,表示该部分不会被捕获并存储供后续引用。 例如,在 Ruby 中,如果希望匹配 `foo` 或者 `barbaz` 而不需要单独捕获 `bar` `baz` 的话,可以写成如下形式: ```ruby pattern = /foo|bar(?:baz)/ ``` 这里,`(?)` 不会形成独立的捕获组[^1]。 #### 2. **捕获分组** 捕获分组不仅能够将一部分正则表达式划分为一组,还可以将其匹配的结果保留下来以备后用。通过圆括号 `()` 实现,默认情况下每一个左括号都会增加一个新的捕获编号。 比如下面这个 Python 正则表达式例子展示了如何利用捕获组来验证回文结构: ```python import re text = "level" match = re.search(r"(?i)(\w+)\b.*?\b\1", text) if match: print(f"Matched palindrome: {match.group(1)}") else: print("No palindrome found.") ``` 上述代码中的 `\1` 是指代第一个捕获组所捕捉到的内容[^3]。 #### 3. **带名称的捕获分组** 除了简单的索引外,也可以给每一段感兴趣的数据指定更具可读性的名字而不是仅仅依靠位置序号。这种方式尤其适合复杂查询场景下提高维护性理解度。 Python 支持具名群的形式定义为 `(?P<name>...)` ,之后可以用相同的名字再次调取它:`(?P=name)` 。举个实际的例子来说就是日期解析任务里经常遇到的不同格式混杂的情况。 ```python date_str = "Start date: 2023-10-05 End Date: 2024/01/17" dates_pattern = r""" Start\s+date:\s+(?P<start>\d{4}-\d\d-\d\d)\s+ End\s+Date:\s+(?P<end>\d{4}/\d\d/\d\d) """ matches = re.finditer(dates_pattern, date_str, flags=re.X) for m in matches: start_date = m['start'] end_date = m['end'] print(start_date, "->", end_date) ``` 此脚本片段中分别命名了两个不同的时间字段作为我们的目标对象,并且可以直接通过键访问它们对应的值[^4]。 #### 4. **忽略常见无意义词汇** 当构建自然语言处理模型或者执行关键词统计分析的时候,往往需要排除那些频繁出现却缺乏实质含义的词语——即所谓的“停用词”。借助像 scikit-learn 这样的库函数参数设置即可轻松达成目的。 考虑这样一个情景:我们需要从大量文档摘要里面抽取出最具代表性的术语组合(单字、双连串以及三联串),同时剔除掉诸如‘the’之类的干扰项。 ```python from sklearn.feature_extraction.text import CountVectorizer vectorizer = CountVectorizer(ngram_range=(1, 3), stop_words='english') X = vectorizer.fit_transform(corpus) terms = vectorizer.get_feature_names_out() ``` 在这里设置了 `ngram_range` 参数范围覆盖了一至三个连续单元的可能性;另外还特别强调移除英文环境下的典型噪声源[^2]。 --- ### 总结 以上介绍了四种主要针对不同应用场景设计出来的文本分割技术手段,包括但不限于标准型态学上的简单分类直至高级语义层面的理解挖掘过程。合理选用这些工具可以帮助开发者更高效准确地完成各自领域内的特定挑战。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值