- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试通过使用NLTK's brill module训练特定的分块器(为简单起见,请使用名词分块器)。我想使用三个功能,即。字,POS标签,IOB标签。
(Ramshaw and Marcus, 1995:7)显示了100个模板,这些模板是通过这三个功能的组合生成的,例如,
W0, P0, T0 # current word, pos tag, iob tag
W-1, P0, T-1 # prev word, pos tag, prev iob tag
...
nltk.tbl.feature
中,但是只有两种特征对象,即。
brill.Word
和
brill.Pos
。受设计的限制,我只能将单词和POS功能像(word,pos)放在一起,并因此使用((word,pos),iob)作为训练功能。例如,
from nltk.tbl import Template
from nltk.tag import brill, brill_trainer, untag
from nltk.corpus import treebank_chunk
from nltk.chunk.util import tree2conlltags, conlltags2tree
# Codes from (Perkins, 2013)
def train_brill_tagger(initial_tagger, train_sents, **kwargs):
templates = [
brill.Template(brill.Word([0])),
brill.Template(brill.Pos([-1])),
brill.Template(brill.Word([-1])),
brill.Template(brill.Word([0]),brill.Pos([-1])),]
trainer = brill_trainer.BrillTaggerTrainer(initial_tagger, templates, trace=3,)
return trainer.train(train_sents, **kwargs)
# generating ((word, pos),iob) pairs as feature.
def chunk_trees2train_chunks(chunk_sents):
tag_sents = [tree2conlltags(sent) for sent in chunk_sents]
return [[((w,t),c) for (w,t,c) in sent] for sent in tag_sents]
>>> from nltk.tag import DefaultTagger
>>> tagger = DefaultTagger('NN')
>>> train = treebank_chunk.chunked_sents()[:2]
>>> t = chunk_trees2train_chunks(train)
>>> bt = train_brill_tagger(tagger, t)
TBL train (fast) (seqs: 2; tokens: 31; tpls: 4; min score: 2; min acc: None)
Finding initial useful rules...
Found 79 useful rules.
B |
S F r O | Score = Fixed - Broken
c i o t | R Fixed = num tags changed incorrect -> correct
o x k h | u Broken = num tags changed correct -> incorrect
r e e e | l Other = num tags changed incorrect -> incorrect
e d n r | e
------------------+-------------------------------------------------------
12 12 0 17 | NN->I-NP if Pos:NN@[-1]
3 3 0 0 | I-NP->O if Word:(',', ',')@[0]
2 2 0 0 | I-NP->B-NP if Word:('the', 'DT')@[0]
2 2 0 0 | I-NP->O if Word:('.', '.')@[0]
nltk.tbl.feature
中单独实现word,pos,iob功能吗?
最佳答案
nltk3 brill训练器API(我写过)确实处理了关于用多维描述的令牌序列的训练
功能,例如您的数据。但是,实际限制可能很严格。多维学习中可能的模板数量
急剧增加,并且当前nilk实现的brill训练器会交换内存
关于速度,类似于Ramshaw和Marcus 1994,“探索变换规则序列的统计推导...”。
内存消耗可能很大,并且
与系统相比,为系统提供更多的数据和/或模板非常容易
它可以处理。一个有用的策略是对
模板,根据它们产生良好规则的频率(请参阅
在下面的示例中为print_template_statistics()。
通常,您可以舍弃得分最低的分数(例如50-90%)
几乎没有或没有任何性能损失,并且大大减少了培训时间。
另一种或其他可能性是使用nltk
Brill原始算法的实现,该算法在内存速度折衷方面有很大不同;它没有索引,因此将使用更少的内存。它使用了一些优化,实际上找到最佳规则的速度相当快,但是当有许多竞争性的,低分的候选人出现时,通常在训练结束时非常慢。有时候,无论如何,您不需要这些。由于某种原因,新的nltks似乎已省略了此实现,但这是源(我刚刚对其进行了测试)http://www.nltk.org/_modules/nltk/tag/brill_trainer_orig.html。
还有其他折衷的算法,并且
特别是Florian和Ngai 2000的快速高效存储索引算法
(http://www.aclweb.org/anthology/N/N01/N01-1006.pdf)和
1998年塞缪尔概率规则抽样
(https://www.aaai.org/Papers/FLAIRS/1998/FLAIRS98-045.pdf)将是一个有用的补充。另外,正如您所注意到的那样,文档还不完整,并且过于专注于词性标记,并且不清楚如何从中进行概括。修复文档(也)在待办事项列表上。
但是,对于nltk中的通用(非POS标记)tbl的兴趣非常有限(nltk2的完全不适合的api被使用了10年之久),因此请不要屏住呼吸。如果您不耐烦,则不妨查看更多专用的替代方法,
特别是mutbl和fntbl(在Google上,我仅以两个链接而闻名)。
无论如何,这是nltk的快速草图:
首先,nltk中的硬编码约定是标记序列(“标记”表示任何标签
您想分配给您的数据,不一定代表词性)
作为成对的序列[[token1,tag1),(token2,tag2),...]。标签是字符串;在
许多基本应用程序,令牌也是如此。例如,令牌可以是单词
和他们的POS字符串,如
[('And', 'CC'), ('now', 'RB'), ('for', 'IN'), ('something', 'NN'), ('completely', 'RB'), ('different', 'JJ')]
[token for (token, _tag) in tagged_sequence]
[x.token for x in tagged_sequence]
[({'word': 'Pierre', 'tag': 'NNP', 'iob': 'B-NP'}, 'NNP'),
({'word': 'Vinken', 'tag': 'NNP', 'iob': 'I-NP'}, 'NNP'),
({'word': ',', 'tag': ',', 'iob': 'O' }, ','),
...
]
from __future__ import division, print_function, unicode_literals
import sys
from nltk import tbl, untag
from nltk.tag.brill_trainer import BrillTaggerTrainer
# or:
# from nltk.tag.brill_trainer_orig import BrillTaggerTrainer
# 100 templates and a tiny 500 sentences (11700
# tokens) produce 420000 rules and uses a
# whopping 1.3GB of memory on my system;
# brill_trainer_orig is much slower, but uses 0.43GB
from nltk.corpus import treebank_chunk
from nltk.chunk.util import tree2conlltags
from nltk.tag import DefaultTagger
def get_templates():
wds10 = [[Word([0])],
[Word([-1])],
[Word([1])],
[Word([-1]), Word([0])],
[Word([0]), Word([1])],
[Word([-1]), Word([1])],
[Word([-2]), Word([-1])],
[Word([1]), Word([2])],
[Word([-1,-2,-3])],
[Word([1,2,3])]]
pos10 = [[POS([0])],
[POS([-1])],
[POS([1])],
[POS([-1]), POS([0])],
[POS([0]), POS([1])],
[POS([-1]), POS([1])],
[POS([-2]), POS([-1])],
[POS([1]), POS([2])],
[POS([-1, -2, -3])],
[POS([1, 2, 3])]]
iobs5 = [[IOB([0])],
[IOB([-1]), IOB([0])],
[IOB([0]), IOB([1])],
[IOB([-2]), IOB([-1])],
[IOB([1]), IOB([2])]]
# the 5 * (10+10) = 100 3-feature templates
# of Ramshaw and Marcus
templates = [tbl.Template(*wdspos+iob)
for wdspos in wds10+pos10 for iob in iobs5]
# Footnote:
# any template-generating functions in new code
# (as opposed to recreating templates from earlier
# experiments like Ramshaw and Marcus) might
# also consider the mass generating Feature.expand()
# and Template.expand(). See the docs, or for
# some examples the original pull request at
# https://github.com/nltk/nltk/pull/549
# ("Feature- and Template-generating factory functions")
return templates
def build_multifeature_corpus():
# The true value of the target fields is unknown in testing,
# and, of course, templates must not refer to it in training.
# But we may wish to keep it for reference (here, truepos).
def tuple2dict_featureset(sent, tagnames=("word", "truepos", "iob")):
return (dict(zip(tagnames, t)) for t in sent)
def tag_tokens(tokens):
return [(t, t["truepos"]) for t in tokens]
# connlltagged_sents :: [[(word,tag,iob)]]
connlltagged_sents = (tree2conlltags(sent)
for sent in treebank_chunk.chunked_sents())
conlltagged_tokenses = (tuple2dict_featureset(sent)
for sent in connlltagged_sents)
conlltagged_sequences = (tag_tokens(sent)
for sent in conlltagged_tokenses)
return conlltagged_sequences
class Word(tbl.Feature):
@staticmethod
def extract_property(tokens, index):
return tokens[index][0]["word"]
class IOB(tbl.Feature):
@staticmethod
def extract_property(tokens, index):
return tokens[index][0]["iob"]
class POS(tbl.Feature):
@staticmethod
def extract_property(tokens, index):
return tokens[index][1]
class MyInitialTagger(DefaultTagger):
def choose_tag(self, tokens, index, history):
tokens_ = [t["word"] for t in tokens]
return super().choose_tag(tokens_, index, history)
def main(argv):
templates = get_templates()
trainon = 100
corpus = list(build_multifeature_corpus())
train, test = corpus[:trainon], corpus[trainon:]
print(train[0], "\n")
initial_tagger = MyInitialTagger('NN')
print(initial_tagger.tag(untag(train[0])), "\n")
trainer = BrillTaggerTrainer(initial_tagger, templates, trace=3)
tagger = trainer.train(train)
taggedtest = tagger.tag_sents([untag(t) for t in test])
print(test[0])
print(initial_tagger.tag(untag(test[0])))
print(taggedtest[0])
print()
tagger.print_template_statistics()
if __name__ == '__main__':
sys.exit(main(sys.argv))
def build_multifeature_corpus():
...
def tuple2dict_featureset(sent, tagnames=("word", "pos", "trueiob")):
return (dict(zip(tagnames, t)) for t in sent)
def tag_tokens(tokens):
return [(t, t["trueiob"]) for t in tokens]
...
...
initial_tagger = MyInitialTagger('O')
...
class POS(tbl.Feature):
@staticmethod
def extract_property(tokens, index):
return tokens[index][0]["pos"]
class IOB(tbl.Feature):
@staticmethod
def extract_property(tokens, index):
return tokens[index][1]
关于python - 使用nltk.tag.brill_trainer(基于转换的学习)训练IOB Chunker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37960667/
Java - opennlp 我是 opennlp 的新手,我尝试分析句子并获得 post 标签和块结果,但我无法理解值的含义。是否有任何表格可以解释帖子标签和块结果值的完整含义? Tokens: [
我正在尝试使用 NLTK 的词性标记作为正则表达式来分块句子。根据句子中单词的标签,定义了 2 条规则来识别短语。 主要是,我想捕获一个或多个动词后跟一个可选的限定词,最后是一个或多个名词。这是定义中
我需要在 Opennlp 中训练 Chunker 以将训练数据分类为名词短语。我该如何进行?在线文档没有解释如何在没有命令行的情况下将其合并到程序中。它说要使用 en-chunker.train,但是
我正在尝试通过使用NLTK's brill module训练特定的分块器(为简单起见,请使用名词分块器)。我想使用三个功能,即。字,POS标签,IOB标签。 (Ramshaw and Marcus,
我是一名优秀的程序员,十分优秀!