NLP入门学习1 您所在的位置:网站首页 NLP学习十 NLP入门学习1

NLP入门学习1

2024-06-27 04:05| 来源: 网络整理| 查看: 265

NLP入门学习1——分词和词性标注 0.简介1.概念和工具1.1 词性标注1.2 NLTK1.3 jieba1.4 LAC 2.代码实现2.1 分词2.1.1 使用nltk进行分词:2.1.2 使用jieba进行分词2.1.3 使用LAC进行分词 2.2 词性标注2.2.1 使用nltk工具实现词性标注2.2.2 使用LAC工具实现词性标注 3.遇到的问题及解决3.1 Resource punkt not found 4.结束

0.简介

本文主要介绍NLP中最基础的任务分词和词性标注。难度属于入门级别。 本文的主要参考如下: 参考链接1 参考链接2 参考链接3 参考链接4

1.概念和工具 1.1 词性标注

词性标注是NLP四大基本任务中序列标注中的一项,其目的是对文本中的词汇实现词性的划分。标注的结果是一个由二元组组成的list,其中每一个二元组中标明了每个token对应的词性。

1.2 NLTK

NLTK全称natural language toolkit是一个基于python编写的自然语言处理工具箱。 安装非常简单,直接用conda或者pip安装即可。

conda install nltk

在nltk中,将词性归为以下类别:

简写全称含义CCcoordinating conjunction并列连词CDcardinal digit基数DTdeterminer限定词EXexistentialthere存在句FWforeignword外来语INpreposition/subordinating conjunction介词/从属连词JJadjective形容词JJRadjective, comparative比较级形式JJSadjective, superlative最高级MDmodal情态动词NNnoun名词单数形式NNSnoun名词复数形式NNPpropernoun专有名词单数形式NNPSpropernoun专有名词复数形式PDTpredeterminer前位限定词POSpossessiveending属有词’sPRPpersonalpronoun人称代词PRP$possessive pronoun物主代词RBadverb very副词RBRadverb,comparative副词比较级RBSadverb,superlative副词最高级RPparticle与动词构成短语的副词或介词TOtotoUHinterjection感叹词VBverb动词VBDverb动词过去式VBGverb现在分词VBNverb过去分词VBPverb动词现在VBZverb动词 第三人称WDTwh-determiner限定词which等WPwh-pronoun代词who, what 等WP$possessivewh-pronoun所有格 whoseWRBwh-abverbwhere, when 副词 1.3 jieba

jieba是一个优秀的中文分词库,同样是基于python。 支持精确模式,全模式,搜索引擎模式等多种模式。 Github:jieba

jieba安装可以在conda命令行通过如下指令完成:

conda install --channel https://conda.anaconda.org/conda-forge jieba 1.4 LAC

LAC全称Lexical Analysis of Chinese,是百度自然语言处理部研发的一款联合的词法分析工具,实现中文分词、词性标注、专名识别等功能。 GitHub:LAC LAC的安装也非常简单:

pip install lac -i https://mirror.baidu.com/pypi/simple

在词性标注任务中,LAC将词性归为以下类: 图片来自LAC的git主页

2.代码实现 2.1 分词

分词可以使用nltk实现,也可以使用其他工具如jieba实现。 使用nltk工具进行分词可以直接由文本到token划分,也可以先进行sentence level的分词。

2.1.1 使用nltk进行分词:

(1)直接划分

words = nltk.word_tokenize(text) words

结果:

Out[1]: ['life', 'is', 'short', '.', 'play', 'more', 'sport', '.']

(2)先进行句子划分:

import nltk text = 'life is short. play more sport.' sents = nltk.sent_tokenize(text) sents

结果:

Out[1]: ['life is short.', 'play more sport.']

再进行分词:

words = [nltk.word_tokenize(i) for i in sents] words

结果:

Out[1]: [['life', 'is', 'short', '.'], ['play', 'more', 'sport', '.']]

但没有加载中文语料库的情况下,试图使用nltk进行中文分词就会出现问题:

words = nltk.word_tokenize('吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮') words

结果可以看出分词并没有成功:

['吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮']

接下来就介绍可以用于中文分词的工具。

2.1.2 使用jieba进行分词

jieba的分词功能可以由两个函数实现,cut函数返回的是一个generator,lcut函数直接返回一个list,具体的使用方法: (1) cut:

import jieba import jieba.analyse words = jieba.cut(text) print('/'.join(words))

结果:

life/ /is/ /short/./ /play/ /more/ /sport/.

(2) lcut:

words = jieba.lcut(text) print(words)

结果:

['life', ' ', 'is', ' ', 'short', '.', ' ', 'play', ' ', 'more', ' ', 'sport', '.']

在这里可以看出jieba分词与nltk之间的一个区别在于,jieba的分词结果中把空格也包含进去了,不限要空格的话就把它删掉就好了。

words = jieba.lcut(text) while ' ' in words: words.remove(' ') print(words)

结果:

['life', 'is', 'short', '.', 'play', 'more', 'sport', '.']

jieba除了可以进行英文分词,也可以进行中文分词。

words = jieba.lcut('吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮') words

结果:

['吃', '葡萄', '不吐', '葡萄', '皮', ',', '不吃', '葡萄', '倒', '吐', '葡萄', '皮'] 2.1.3 使用LAC进行分词

使用LAC进行分词也很简单,下面是LAC官方的操作指引和样例结果。

from LAC import LAC # 装载分词模型 lac = LAC(mode='seg') # 单个样本输入,输入为Unicode编码的字符串 text = "LAC是个优秀的分词工具" seg_result = lac.run(text) # 批量样本输入, 输入为多个句子组成的list,平均速率会更快 texts = ["LAC是个优秀的分词工具", "百度是一家高科技公司"] seg_result = lac.run(texts)

结果:

【单样本】:seg_result = [LAC, 是, 个, 优秀, 的, 分词, 工具] 【批量样本】:seg_result = [[LAC, 是, 个, 优秀, 的, 分词, 工具], [百度, 是, 一家, 高科技, 公司]] 2.2 词性标注 2.2.1 使用nltk工具实现词性标注 pos_tags =nltk.pos_tag(words) print(pos_tags)

结果:

[('life', 'NN'), ('is', 'VBZ'), ('short', 'JJ'), ('.', '.'), ('play', 'VB'), ('more', 'JJR'), ('sport', 'NN'), ('.', '.')]

可以看出在英文分词方面nltk工具的效果还是很准确,很精细的。

上文中提到nltk在中文分词中不灵了,那么如果将分好的token输入给nltk,是否能够完成词性标注了?

words = jieba.lcut('吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮') pos_tags =nltk.pos_tag(words) pos_tags

结果:

[('吃', 'JJ'), ('葡萄', 'NNP'), ('不吐', 'NNP'), ('葡萄', 'NNP'), ('皮', 'NNP'), (',', 'NNP'), ('不吃', 'NNP'), ('葡萄', 'NNP'), ('倒', 'NNP'), ('吐', 'NNP'), ('葡萄', 'NNP'), ('皮', 'NN')]

尽管标注完成了,但是通过判断发现它的标注并不准确,把“吃”标注成了形容词,“不吐”标注成了名词。

2.2.2 使用LAC工具实现词性标注 from LAC import LAC # 装载LAC模型 lac = LAC(mode='lac') # 单个样本输入,输入为Unicode编码的字符串 text = u"LAC是个优秀的分词工具" lac_result = lac.run(text) # 批量样本输入, 输入为多个句子组成的list,平均速率更快 texts = [u"LAC是个优秀的分词工具", u"百度是一家高科技公司"] lac_result = lac.run(texts)

结果:

【单样本】: lac_result = ([百度, 是, 一家, 高科技, 公司], [ORG, v, m, n, n]) 【批量样本】:lac_result = [ ([百度, 是, 一家, 高科技, 公司], [ORG, v, m, n, n]), ([LAC, 是, 个, 优秀, 的, 分词, 工具], [nz, v, q, a, u, n, n]) ]

再来测试一下我们自己的例子:

from LAC import LAC # 装载LAC模型 lac = LAC(mode='lac') # 单个样本输入,输入为Unicode编码的字符串 text = u"吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮" lac_result = lac.run(text)

结果:

[['吃', '葡萄', '不', '吐', '葡萄皮', ',', '不', '吃', '葡萄', '倒', '吐', '葡萄皮'], ['v', 'nz', 'd', 'v', 'n', 'w', 'd', 'v', 'n', 'd', 'v', 'n']]

结果同样十分准确,并且相比jieba分词的结果,吧“葡萄皮”作为一个整体保留下来了。

3.遇到的问题及解决 3.1 Resource punkt not found

使用nltk分词时,报错LookupError Resource punkt not found,按照提示下载,nltk.download(‘punkt’),提示failed。 这是因为资源在外网,所以访问不了。解决方法,手动下载,并保存在指定位置. 下载链接在git上还有很多人的博客上都可以找到,为了防止失效,我又在自己的网盘里传了一个。 地址:https://pan.baidu.com/s/14KpU-BNuST6IwAFhWOosBA 提取码:s8zt

下载之后把缺少的包放在自动搜索的路径下,如各盘的根目录,在这里我把它放在了anaconda的路径下。 在…\anaconda\share路径下创建文件夹nltk_data,以punkt为例,把下载的数据解压,把punkt中的english.pickle 放在…\anaconda\share\nltk_data\tokenizers\punkt\PY3\english.pickle,就可以了。 有一个细节需要注意一下,在解压之后的文件夹中并没有包含名为PY3的文件夹,如果不自己创建一个的话,仍然会报错。 类似的问题也采用类似的解决方法。

如果以上的内容中出现了任何错误和不准确的地方,还请帮忙指出,谢谢。

4.结束

接下来的一段时间里,我会从最基础的内容开始NLP的学习,主要会记录一些基本的概念和NLP工具和模型在使用的过程中遇到的问题。那么我们下期再见。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有