FrameNet语料库是一个人读和机读的英语词汇数据库,它基于对实际文本中单词用法的注释示例。FrameNet基于一种叫做框架语义学的意义理论,该理论来源于Charles J. Fillmore及其同事的工作。其基本思想很简单:大多数单词的含义都可以通过语义框架(对事件、关系或实体及其参与者的描述)得到最佳理解。例如,烹饪的概念通常涉及到一个人做饭(Cook),即将被烹饪的食物(food),做饭时用来盛食物的东西(容器)和热源(加热设备)。在FrameNet项目中,这被表示为一个名为Apply heat的框架,而Cook、Food、Heating instrument和Container被称为frame elements (FEs)。链接这种框架的单词,如fry、bake、boil和broil,称为Apply_heat框架的词汇单元(LUs)。FrameNet的工作是定义框架,并对句子进行注释,以显示FEs如何与链接框架的单词在语法上匹配。
在框架中的框架元素正式列出了他们在框架中功能的英文描述。框架是在一个网络中组织的,包括一个继承层次结构和其他类型的框架关系。在一个框架中列出的词汇条目被称为词汇单元(逻辑单元,lexicalunits ,LUs)。FrameNet的逻辑单元的详细目录包括内容和功能词。在形式上,一个逻辑单元LU连接一个框架的词元(词元的名字包含了一个语音标签。词元可能由一个单词如词组成如surrender.v,或多个单词,例如give up.v组成)。
框架是类似脚本的概念结构,描述特定类型的场景、对象或事件,以及该框架所需的参与者和道具。例如,“Apply heat”框架描述了涉及厨师、一些食物和加热设备的常见情况,并由单词bake、blanch、boil、roast、brown、simmer、steam等引起。
我们将框架的角色称为“框架元素”(FEs),而引发框架的单词称为“词汇单元”(LUs)。
FrameNet包括了框架之间的关系。FrameNet定义了几种类型的关系,其中最重要的是:
词汇单位(LU)是一个单词与单词意思的配对。例如,“Apply heat”框架描述了涉及厨师、一些食物和加热设备的常见情况,并由单词bake、blanch、boil、roast、brown、simmer、steam等引起。这些让人联想起框架的词是“Apply heat”框架中的逻辑单元。一个多义词的每一个词义都是不同的LU。
我们用“word”这个词来谈论LUs。实际上关系很复杂。当我们说“bake”是一个多义词时,意思是词条“bake.v”(bake词有很多词形如:“bake”, “bakes”, “baked”, and “baking”)链接到三种不同的框架:
它们构成了三个不同的逻辑单元,具有不同的定义。
多字短语,如“given name”和像“shut-eye”这样带连字符的词,也可以是LUs。在适当的框架中,像“middel of mowhere”和“give the slip(to)”的熟语也定义为LUs,它们分别在“Isolated_places”和“evading”中,而且他们的内部结构是不可分析的。
Framenet提供了一个单词的每个意义的多个注释示例.此外,这组示例(大约每个LU20个)说明了词汇单元的所有组合可能性。
在最简单的情况下,让人联想起框架的单词是动词,例如“fried”在“Matilde fried the catfish In a heavy iron skillet.”句中。
有时,事件名词可以联想起一个框架。例如,“reduction”联想起“Cause_change_of_scalar_position”,在“…the reduction of debt levels to $665 million from $2.6 billion.”句中。
形容词也可以联想起一个框架。例如,“asleep”可以唤起“Sleep”框架,例如:“They were asleep for hours.”
许多常见的名词,如像“帽子”或“塔”这样的人工制品,通常是作为从属关系而不是清晰地联想起它们自己的框架。
该方法需要网速,有时即使有网速也不一定顺利下载完,需要多尝试几次。
import nltk nltk.download('framenet_v17')
还可以直接运行一下命令:
import nltk nltk.download()
不填加数据集,在nltk的下载器中选择要下载的数据集,手动点击下载
在NLTK Corpus网站下载所需的数据集,下载后放到nltk_data文件夹下解压即可。
要获得FrameNet中所有frame的列表,可以使用**frames()**函数。如果向frames()函数提供一个正则表达式模式,将得到一个包含所有名称与该模式匹配的框架的列表。
"""导入Framenet库"""
from pprint import pprint
from nltk.corpus import framenet as fn
"""列出framenet中所有的框架"""
len(fn.frames())
1221
"""列出通过正则表达式匹配出的所有框架及框架信息"""
pprint(fn.frames(r'(?i)medical'))
pprint(len(fn.frames(r'(?i)medical')))
# pprint(fn.frames(r'(?i)medical')[0])
[, , ...]
6
要获取特定frame的详细信息,可以使用**frame()**函数传入框架的ID号
"""通过ID号,得到框架对象"""
f = fn.frame(253)
"""框架的ID号"""
f.ID
253
"""框架的名称"""
f.name
'Social_connection'
"""框架的描述信息"""
f.definition
"A mutual social and personal relationship that keeps people involved in each other's lives comprises a Connection of Individual1 to Individual2 or between Individuals. 'They wanted to strengthen their family ties.' "
"""该框架的词汇集大小"""
len(f.lexUnit)
10
"""列出框架的元素单词FEs"""
words = [x for x in f.FE]
pprint(words)
pprint(sorted([x for x in f.FE])) # 排序后的列表
['Individual_2', 'Individuals', 'Connection', 'Individual_1', 'Degree', 'Type']
['Connection', 'Degree', 'Individual_1', 'Individual_2', 'Individuals', 'Type']
"""列出框架的关系组列表(一组关系像是一个三元组)"""
pprint(f.frameRelations)
[ Child=Social_connection>]
上面显示的frame()函数返回一个dict对象,其中包含关于该框架的详细信息。有关详细信息,请参阅关于frame()函数的文档。
还可以根据frame的词汇单位(LUs)搜索frame。frames_by_lemma() 函数的作用是:返回包含逻辑单元的所有框架的列表,其中逻辑单元的“name”属性与给定的正则表达式匹配。注意,LU名称由“lemma.POS”组成,其中“frame”部分可以由单个词素(如run)或多个词汇(如‘a little’)组成,。
"""列出符合正则表达式的框架"""
fn.frames_by_lemma(r'(?i)a little')
[, ]
可以使用该类的 lus() 函数获得特定词汇单元的详细信息,该函数采用一个可选的正则表达式模式,该模式将与词汇单元的名称匹配。
"""列出所有的词汇单元"""
LUs = fn.lus()
pprint(LUs)
pprint(len(LUs))
[, , ...]
13572
"""正则匹配相应的LU"""
LUs = fn.lus(r'(?i)a little')
pprint(LUs)
pprint(len(LUs))
# pprint(LUs[0])
[, , ...]
3
可以通过调用 lu() 函数并传入LU的“ID”号来获得关于特定LU的详细信息
"""实例化LU对象"""
lu = fn.lu(256)
print(lu)
# pprint(lu)
lexical unit (256): foresee.v
[definition]
COD: be aware of beforehand; predict.
[frame] Expectation(26)
[POS] V
[status] FN1_Sent
[lexemes] foresee/V
[semTypes] 0 semantic types
[URL] https://framenet2.icsi.berkeley.edu/fnReports/data/lu/lu256.xml
[subCorpus] 25 subcorpora
V-420-that-sfin, V-430-sfin, V-480-swh, V-570-np-ppfor,
V-570-np-ppfrom, V-570-np-ppin, V-570-np-ppon, V-570-np-
ppwith, V-620-np-ppother, V-650-np-pother, V-660-trans-
simple, V-670-pass-by, V-680-pass, V-690-trans-other,
V-730-ppat, V-730-ppfor, V-730-ppfrom, V-730-ppin,
V-730-ppon, V-730-ppwith, V-780-ppother, V-810-pother,
V-890-intrans-adverb, V-900-other, manually-added
[exemplars] 45 sentences across all subcorpora
"""获得lu的name"""
fn.lu(233).name
'surmise.v'
"""获得lu的definition"""
fn.lu(233).definition
'COD: suppose without having evidence.'
"""获得lu的对应框架的name"""
fn.lu(233).frame.name
'Coming_to_believe'
"""获取lu的含义"""
pprint(fn.lu(233).lexemes)
pprint(fn.lu(233).lexemes[0].name)
[{'POS': 'V', 'breakBefore': 'false', 'headword': 'false', 'name': 'surmise', 'order': 1}]
'surmise'
注意,LU名称采用点字符串的形式(例如"run.v",其中lemma词汇在“.”前面,词性部分在“.”后面。
LUs中使用的POSs列表是:
FrameNet文集包含一小部分带注释的文档。可以通过调用docs()函数获得这些文档的列表.
"""获取Framenet中注释文档"""
docs = fn.docs()
print(len(docs))
# print(docs[0])
107
frame()和lu()方法是用它的名字或ID来检索一个已知的条目。
试图检索一个不存在的条目会触发一个类型为FramenetError的异常。
"""frame() lu()"""
f = fn.frame(253)
print(f.name)
f2 = fn.lu(253)
print(f2.frame.name)
print(f2.name)
Social_connection
Expectation
anticipate.v
"""检索不存在的条目"""
try:
f = fn.frame(23242423)
print(f)
except:
print('a FramenetError')
a FramenetError
框架查找有两种附加的方法: frame_ids_and_names(名称)是得到框架ID到名称的映射,frames_by_lemma(名称)是得到与给定名称模式匹配词汇单元所属的所有框架
f = fn.frame_ids_and_names(r'(?i)medical')
print(f)
f2 = fn.frames_by_lemma(r'(?i)medical')
print(f2)
{256: 'Medical_specialties', 257: 'Medical_instruments', 2708: 'Medical_interaction_scenario', 2741: 'Medical_intervention', 239: 'Medical_conditions', 255: 'Medical_professionals'}
[, ]
数据库框架中的所有结构化对象——框架、词汇单元、框架元素等等——都被加载为AttrDict数据结构。每个AttrDict实例都是一个从字符串键到值的映射,它可以是字符串、数字或结构化对象。之所以这么叫,是因为AttrDict允许以属性的方式访问键:
f = fn.frame('Revenge')
f.keys()
dict_keys(['FEcoreSets', 'frameRelations', 'cBy', 'definitionMarkup', '_type', 'URL', 'FE', 'name', 'ID', 'semTypes', 'lexUnit', 'definition', 'cDate'])
print(f.name)
print(f.ID)
# print(f.lexUnit['revenge.n'])
Revenge
347
对于最重要的结构化对象,该API规定了以人类可读的方式组织对象内容的进行文本显示。图1显示了复仇REVENGE框架的显示,在交互式提示符中输入fn.frame(“复仇”)即可得到。属性名在方括号中显示,如lexUnit,它是一个从词汇单元LU名称到对象的映射。因此,在上一段代码清单之后,f.lexUnit[‘revenge.n’]将访问框架中的一个词汇单元LU对象,而该框架又有其自身的属性和文本显示。
名字模式的检索:
r'(?i)medical'
带特定后缀的检索:
r'.+en\.v'
"""检索所有的动词"""
f = fn.lus(r'.+en\.v')
print(f)
print(len(f))
[, , ...]
55
FrameNet
NLTK框架API: 丰富语言资源的可发现性设计