1.什么是词性标注?
词性(POS)主要指比如名词,形容词,动词等等。虽然目前最先进的词性标注算法在预测给定单词的词性上已经有了较高的精确度(约97%)。
首先,我们需要学习一些现成的POS标注器。
主要的词性有哪些呢?
标签 | 相关说明 |
---|---|
NNP | 专用名词的单数形式 |
NNPS | 专用名词的复数形式 |
PDT | 前置限定词 |
POS | 所有格结束符 |
PRP | 人称代词 |
PRP$ | 所有格代词 |
RB | 副词 |
RBR | 相对副词 |
RBS | 最高级副词 |
RP | 小品词 |
SYM | 符号(数学符号或特殊符号) |
TO | To |
UH | 叹词 |
VB | 动词的基本形式 |
VBD | 动词的过去式 |
VBG | 动词的动名词用法 |
VBN | 动词的过去分词 |
WP | Wh-代词 |
WP$ | 所有格wh-代词 |
WRB | Wh-副词 |
# | 井号符 |
$ | 美元符 |
. | 句号 |
, | 逗号 |
: | 分号,分隔符 |
( | 左括号 |
) | 右括号 |
" | 直双引号 |
‘ | 左单引号 |
“ | 左双引号 |
’ | 右单引号 |
” | 右双引号 |
2.利用pos标注器
简单代码:
import nltk
from nltk import word_tokenize
s="I was watching TV."
print(nltk.pos_tag(word_tokenize(s)))
结果显示:
D:\IR_lab\venv\Scripts\python.exe D:/IR_lab/learn.py
[('I', 'PRP'), ('was', 'VBD'), ('watching', 'VBG'), ('TV', 'NN'), ('.', '.')]
Process finished with exit code 0
其中
PRP----人称代词
VBD—动词的过去式
VBG—动词的动名词用法
NN—专用名词
筛选词性
比如筛选出名次:
#导入库
import nltk
from nltk import word_tokenize
s="I was watching TV."
#对字符串s标注
tagged=nltk.pos_tag(word_tokenize(s))
#输出所有词性里边的名词
all_noun=[word for word ,pos in tagged if pos in ['NN','mnp']]
print(all_noun)
结果:
D:\IR_lab\venv\Scripts\python.exe D:/IR_lab/learn.py ['TV']
Process finished with exit code 0
注意:不能在词性标注之前删除停用词,否则语义不通
虽然Pos标注器能够区分不同词性,但其正确率并不高
3.顺序标注器
N-gram标注器是一种顺序标注器,会在其所在的上下文环境中标注出前n个单词,并预测给定词项的Pos标签。
import nltk
from nltk.corpus import brown
#一元模型标注,只考虑条件概率
from nltk.tag import UnigramTagger
from nltk.tag import DefaultTagger
#会考虑给定单词和该单词前一个单词
from nltk.tag import BigramTagger
#与前面两个都有关
from nltk.tag import TrigramTagger
#brown训练集
brown_tagged_sents = brown.tagged_sents(categories='news')
default_tagger = nltk.DefaultTagger('NN')
#训练集
train_data=brown_tagged_sents[:int(len(brown_tagged_sents)*0.9)]
test_data=brown_tagged_sents[int(len(brown_tagged_sents)*0.9):]
#backoff是指当不能进行正确的标签预测时会咨询backoff
#一元模型
unigram_tagger=UnigramTagger(train_data,backoff=default_tagger)
print(unigram_tagger.evaluate(test_data))
#二元模型
bigram_tagger=BigramTagger(train_data,backoff=unigram_tagger)
print(bigram_tagger.evaluate(test_data))
#三元模型
trigram_tagger=TrigramTagger(train_data,backoff=bigram_tagger)
print(trigram_tagger.evaluate(test_data))
结果:
D:\IR_lab\venv\Scripts\python.exe D:/IR_lab/learn.py
0.8361407355726104
0.8452108043456593
0.843317053722715
4.正则表达式标注器
比如任何以ness结尾的词很可能是名次。NLTK的RegexpTagger参数会为我们提供基于POS模式的标注。
代码如下:
#导入训练集
from nltk.corpus import brown
#NLTK正则标注器
from nltk.tag.sequential import RegexpTagger
#对词性进行标注
brown_tagged_sents = brown.tagged_sents(categories='news')
#测试集
test_data = brown_tagged_sents[int(len(brown_tagged_sents) * 0.9):]
regexp_tagger=RegexpTagger([
( r'^-?[0-9]+(.[0-9]+)?$', 'CD'),
( r'(The|the|A|a|An|an)$', 'AT'),
( r'.*able$', 'JJ'),
( r'.*ness$', 'NN'), #以Ness结尾大多是名词
( r'.*ly$', 'RB'), #以ly结尾大多是副词
( r'.*s$', 'NNS'), #以s结尾的大多是复数名词
(r'.*ing$', 'VBG'), #以ing结尾的大多是动名词
(r'.*ed$', 'VBD'), #以ed结尾的大多数是动词过去式
(r'.*', 'NN')
])
print(regexp_tagger.evaluate(test_data))
结果如下:
D:\IR_lab\venv\Scripts\python.exe D:/IR_lab/learn.py
0.31306687929831556
正确率大约有30%
5.命名实体识别(NER)
NER主要由实体名、位置和组织等。NLTK库提供了ne_chunk方法。需要先对语句进行标识化处理,然后再进行语块分解和词性标注的处理顺序,之后进行命名实体标注。
简单看一看
import nltk
from nltk import word_tokenize
from nltk import ne_chunk
sent="Mark is studying at Stanford University in California"
print(ne_chunk(nltk.pos_tag(word_tokenize(sent)),binary=False))
结果如下:
D:\IR_lab\venv\Scripts\python.exe D:/IR_lab/learn.py
(S
(PERSON Mark/NNP)
is/VBZ
studying/VBG
at/IN
(ORGANIZATION Stanford/NNP University/NNP)
in/IN
(GPE California/NNP))
no_chunk能够识别相关人名,地点和组织。
本章小结:
主要学习的是关于词性标注。主要方法有利用POS标注器、N-gram标注还有正则表达式标注
也虚席了NER标注器。