将 NLTK 的通用标签集与非英语语料库一起使用
Using NLTK's universalt tagset with non-English corpora
我在 Python 3.4.3+ 中使用 NLTK (3.0.4-1),我想使用通用标签集(我必须安装)处理一些标记语料库, as explained in NLTK book, chapter 5.
我可以使用它们的原始 PoS 标签集访问这些语料库中的任何一个,例如:
from nltk.corpus import brown, cess_esp, floresta
print(brown.tagged_sents()[0])
[('The', 'AT'), ('Fulton', 'NP-TL'), ('County', 'NN-TL'), ('Grand', 'JJ-TL'), ('Jury', 'NN-TL'), ('said', 'VBD'), ('Friday', 'NR'), ('an', 'AT'), ('investigation', 'NN'), ('of', 'IN'), ("Atlanta's", 'NP$'), ('recent', 'JJ'), ('primary', 'NN'), ('election', 'NN'), ('produced', 'VBD'), ('``', '``'), ('no', 'AT'), ('evidence', 'NN'), ("''", "''"), ('that', 'CS'), ('any', 'DTI'), ('irregularities', 'NNS'), ('took', 'VBD'), ('place', 'NN'), ('.', '.')]
print(cess_esp.tagged_sents()[0])
[('El', 'da0ms0'), ('grupo', 'ncms000'), ('estatal', 'aq0cs0'), ('Electricité_de_France', 'np00000'), ('-Fpa-', 'Fpa'), ('EDF', 'np00000'), ('-Fpt-', 'Fpt'), ('anunció', 'vmis3s0'), ('hoy', 'rg'), (',', 'Fc'), ('jueves', 'W'), (',', 'Fc'), ('la', 'da0fs0'), ('compra', 'ncfs000'), ('del', 'spcms'), ('51_por_ciento', 'Zp'), ('de', 'sps00'), ('la', 'da0fs0'), ('empresa', 'ncfs000'), ('mexicana', 'aq0fs0'), ('Electricidad_Águila_de_Altamira', 'np00000'), ('-Fpa-', 'Fpa'), ('EAA', 'np00000'), ('-Fpt-', 'Fpt'), (',', 'Fc'), ('creada', 'aq0fsp'), ('por', 'sps00'), ('el', 'da0ms0'), ('japonés', 'aq0ms0'), ('Mitsubishi_Corporation', 'np00000'), ('para', 'sps00'), ('poner_en_marcha', 'vmn0000'), ('una', 'di0fs0'), ('central', 'ncfs000'), ('de', 'sps00'), ('gas', 'ncms000'), ('de', 'sps00'), ('495', 'Z'), ('megavatios', 'ncmp000'), ('.', 'Fp')]
print(floresta.tagged_sents()[0])
[('Um', '>N+art'), ('revivalismo', 'H+n'), ('refrescante', 'N<+adj')]
到目前为止一切顺利,但是当我使用选项 tagset='universal'
访问 PoS 标签的简化版本时,它仅适用于 Brown 语料库。
print(brown.tagged_sents(tagset='universal')[0])
[('The', 'DET'), ('Fulton', 'NOUN'), ('County', 'NOUN'), ('Grand', 'ADJ'), ('Jury', 'NOUN'), ('said', 'VERB'), ('Friday', 'NOUN'), ('an', 'DET'), ('investigation', 'NOUN'), ('of', 'ADP'), ("Atlanta's", 'NOUN'), ('recent', 'ADJ'), ('primary', 'NOUN'), ('election', 'NOUN'), ('produced', 'VERB'), ('``', '.'), ('no', 'DET'), ('evidence', 'NOUN'), ("''", '.'), ('that', 'ADP'), ('any', 'DET'), ('irregularities', 'NOUN'), ('took', 'VERB'), ('place', 'NOUN'), ('.', '.')]
访问西班牙语和葡萄牙语语料库时,出现一长串错误和 LookupError
异常。
print(cess_esp.tagged_sents(tagset='universal')[0])
---------------------------------------------------------------------------
LookupError Traceback (most recent call last)
<ipython-input-6-4e2e43e54e2d> in <module>()
----> 1 print(cess_esp.tagged_sents(tagset='universal')[0])
[...]
LookupError:
**********************************************************************
Resource 'taggers/universal_tagset/unknown.map' not found.
Please use the NLTK Downloader to obtain the resource: >>>
nltk.download()
Searched in:
- '/home/victor/nltk_data'
- '/usr/share/nltk_data'
- '/usr/local/share/nltk_data'
- '/usr/lib/nltk_data'
- '/usr/local/lib/nltk_data'
- ''
**********************************************************************
在我的 taggers/universal_tagset
目录中的映射中,我可以找到西班牙语 (es-cast3lb.map
) 和葡萄牙语 (pt-bosque.map
) 的映射,但我没有任何 unknown.map
文件。任何想法如何解决它?
提前致谢:-)
这是个有趣的问题。借助您在 nltk_data/taggers/universal_tagset/
中找到的固定映射,NLTK 仅针对固定的语料库集合实现到通用标签集的映射。除了少数特殊情况(包括将棕色语料库视为命名为 en-brown
)外,规则是查找与用于语料库的标签集同名的映射文件。在您的情况下,标签集设置为 "unknown",这就是您看到该消息的原因。
现在,您确定 "the mapping for Spanish",即地图 es-cast3lb.map
确实与您语料库的标签集匹配吗?我当然不会假设它确实如此,因为任何项目都可以创建自己的标签集和使用规则。 如果这与您的语料库使用的标签集相同,您的问题有一个简单的解决方案:
初始化语料库时 reader,例如cess_esp
,在构造函数中添加选项tagset="es-cast3lb"
。如有必要,例如对于已经由 NLTK 使用 tagset="unknown"
加载的语料库,您可以在初始化后覆盖标签集,如下所示:
cess_esp._tagset = "es-cast3lb"
这告诉语料库 reader 语料库中使用了什么标签集。之后,指定 tagset="universal"
应该会导致应用选定的映射。
如果这个标签集实际上不适合您的语料库,您的第一项工作是研究语料库的标签集文档,并创建到通用标签集的适当映射;正如您可能已经看到的那样,格式非常简单。然后,您可以通过将映射放入 nltk_data/taggers/universal_tagset
来运行您的映射。将您自己的资源添加到 nltk_data
区域绝对是一种 hack,但如果您做到了这一点,我建议您将您的标签集映射贡献给 nltk... 这将在事后解决 hack。
编辑: 所以(根据评论)它是正确的标签集,但映射字典中只有 1-2 个字母的 POS 标签(标签的其余部分大概描述了词形变化的特征)。这是动态扩展映射字典的快速方法,以便您可以看到通用标签:
import nltk
from nltk.corpus import cess_esp
cess_esp._tagset = "es-cast3lb"
nltk.tag.mapping._load_universal_map("es-cast3lb") # initialize; normally loaded on demand
mapdict = nltk.tag.mapping._MAPPINGS["es-cast3lb"]["universal"] # shortcut to the map
alltags = set(t for w, t in cess_esp.tagged_words())
for tag in alltags:
if len(tag) <= 2: # These are complete
continue
mapdict[tag] = mapdict[tag[:2]]
这会丢弃协议信息。如果您想用它装饰 "universal" 标签,只需将 mapdict[tag]
设置为 mapdict[tag[:2]]+"-"+tag[2:]
。
我会将这个词典保存到如上所述的文件中,这样您就不必在每次加载语料库时都重新计算映射。
我在 Python 3.4.3+ 中使用 NLTK (3.0.4-1),我想使用通用标签集(我必须安装)处理一些标记语料库, as explained in NLTK book, chapter 5.
我可以使用它们的原始 PoS 标签集访问这些语料库中的任何一个,例如:
from nltk.corpus import brown, cess_esp, floresta
print(brown.tagged_sents()[0])
[('The', 'AT'), ('Fulton', 'NP-TL'), ('County', 'NN-TL'), ('Grand', 'JJ-TL'), ('Jury', 'NN-TL'), ('said', 'VBD'), ('Friday', 'NR'), ('an', 'AT'), ('investigation', 'NN'), ('of', 'IN'), ("Atlanta's", 'NP$'), ('recent', 'JJ'), ('primary', 'NN'), ('election', 'NN'), ('produced', 'VBD'), ('``', '``'), ('no', 'AT'), ('evidence', 'NN'), ("''", "''"), ('that', 'CS'), ('any', 'DTI'), ('irregularities', 'NNS'), ('took', 'VBD'), ('place', 'NN'), ('.', '.')]
print(cess_esp.tagged_sents()[0])
[('El', 'da0ms0'), ('grupo', 'ncms000'), ('estatal', 'aq0cs0'), ('Electricité_de_France', 'np00000'), ('-Fpa-', 'Fpa'), ('EDF', 'np00000'), ('-Fpt-', 'Fpt'), ('anunció', 'vmis3s0'), ('hoy', 'rg'), (',', 'Fc'), ('jueves', 'W'), (',', 'Fc'), ('la', 'da0fs0'), ('compra', 'ncfs000'), ('del', 'spcms'), ('51_por_ciento', 'Zp'), ('de', 'sps00'), ('la', 'da0fs0'), ('empresa', 'ncfs000'), ('mexicana', 'aq0fs0'), ('Electricidad_Águila_de_Altamira', 'np00000'), ('-Fpa-', 'Fpa'), ('EAA', 'np00000'), ('-Fpt-', 'Fpt'), (',', 'Fc'), ('creada', 'aq0fsp'), ('por', 'sps00'), ('el', 'da0ms0'), ('japonés', 'aq0ms0'), ('Mitsubishi_Corporation', 'np00000'), ('para', 'sps00'), ('poner_en_marcha', 'vmn0000'), ('una', 'di0fs0'), ('central', 'ncfs000'), ('de', 'sps00'), ('gas', 'ncms000'), ('de', 'sps00'), ('495', 'Z'), ('megavatios', 'ncmp000'), ('.', 'Fp')]
print(floresta.tagged_sents()[0])
[('Um', '>N+art'), ('revivalismo', 'H+n'), ('refrescante', 'N<+adj')]
到目前为止一切顺利,但是当我使用选项 tagset='universal'
访问 PoS 标签的简化版本时,它仅适用于 Brown 语料库。
print(brown.tagged_sents(tagset='universal')[0])
[('The', 'DET'), ('Fulton', 'NOUN'), ('County', 'NOUN'), ('Grand', 'ADJ'), ('Jury', 'NOUN'), ('said', 'VERB'), ('Friday', 'NOUN'), ('an', 'DET'), ('investigation', 'NOUN'), ('of', 'ADP'), ("Atlanta's", 'NOUN'), ('recent', 'ADJ'), ('primary', 'NOUN'), ('election', 'NOUN'), ('produced', 'VERB'), ('``', '.'), ('no', 'DET'), ('evidence', 'NOUN'), ("''", '.'), ('that', 'ADP'), ('any', 'DET'), ('irregularities', 'NOUN'), ('took', 'VERB'), ('place', 'NOUN'), ('.', '.')]
访问西班牙语和葡萄牙语语料库时,出现一长串错误和 LookupError
异常。
print(cess_esp.tagged_sents(tagset='universal')[0])
---------------------------------------------------------------------------
LookupError Traceback (most recent call last)
<ipython-input-6-4e2e43e54e2d> in <module>()
----> 1 print(cess_esp.tagged_sents(tagset='universal')[0])
[...]
LookupError:
**********************************************************************
Resource 'taggers/universal_tagset/unknown.map' not found.
Please use the NLTK Downloader to obtain the resource: >>>
nltk.download()
Searched in:
- '/home/victor/nltk_data'
- '/usr/share/nltk_data'
- '/usr/local/share/nltk_data'
- '/usr/lib/nltk_data'
- '/usr/local/lib/nltk_data'
- ''
**********************************************************************
在我的 taggers/universal_tagset
目录中的映射中,我可以找到西班牙语 (es-cast3lb.map
) 和葡萄牙语 (pt-bosque.map
) 的映射,但我没有任何 unknown.map
文件。任何想法如何解决它?
提前致谢:-)
这是个有趣的问题。借助您在 nltk_data/taggers/universal_tagset/
中找到的固定映射,NLTK 仅针对固定的语料库集合实现到通用标签集的映射。除了少数特殊情况(包括将棕色语料库视为命名为 en-brown
)外,规则是查找与用于语料库的标签集同名的映射文件。在您的情况下,标签集设置为 "unknown",这就是您看到该消息的原因。
现在,您确定 "the mapping for Spanish",即地图 es-cast3lb.map
确实与您语料库的标签集匹配吗?我当然不会假设它确实如此,因为任何项目都可以创建自己的标签集和使用规则。 如果这与您的语料库使用的标签集相同,您的问题有一个简单的解决方案:
初始化语料库时 reader,例如
cess_esp
,在构造函数中添加选项tagset="es-cast3lb"
。如有必要,例如对于已经由 NLTK 使用tagset="unknown"
加载的语料库,您可以在初始化后覆盖标签集,如下所示:cess_esp._tagset = "es-cast3lb"
这告诉语料库 reader 语料库中使用了什么标签集。之后,指定 tagset="universal"
应该会导致应用选定的映射。
如果这个标签集实际上不适合您的语料库,您的第一项工作是研究语料库的标签集文档,并创建到通用标签集的适当映射;正如您可能已经看到的那样,格式非常简单。然后,您可以通过将映射放入 nltk_data/taggers/universal_tagset
来运行您的映射。将您自己的资源添加到 nltk_data
区域绝对是一种 hack,但如果您做到了这一点,我建议您将您的标签集映射贡献给 nltk... 这将在事后解决 hack。
编辑: 所以(根据评论)它是正确的标签集,但映射字典中只有 1-2 个字母的 POS 标签(标签的其余部分大概描述了词形变化的特征)。这是动态扩展映射字典的快速方法,以便您可以看到通用标签:
import nltk
from nltk.corpus import cess_esp
cess_esp._tagset = "es-cast3lb"
nltk.tag.mapping._load_universal_map("es-cast3lb") # initialize; normally loaded on demand
mapdict = nltk.tag.mapping._MAPPINGS["es-cast3lb"]["universal"] # shortcut to the map
alltags = set(t for w, t in cess_esp.tagged_words())
for tag in alltags:
if len(tag) <= 2: # These are complete
continue
mapdict[tag] = mapdict[tag[:2]]
这会丢弃协议信息。如果您想用它装饰 "universal" 标签,只需将 mapdict[tag]
设置为 mapdict[tag[:2]]+"-"+tag[2:]
。
我会将这个词典保存到如上所述的文件中,这样您就不必在每次加载语料库时都重新计算映射。