R - 通过 Reticulate 解析 Python NLTK 树
R - Parsing Python NLTK Trees via Reticulate
我正在尝试使用 Reticulate 包从 R 中使用 Python 的 NLTK 包。在大多数情况下,我已经成功了。
现在,我想使用 NLTK 的 ne_chunk()
函数执行命名实体识别(即确定哪些标记代表命名实体以及它们代表什么类型的命名实体。)。我的问题是函数 return 是 class nltk.tree.Tree
的对象,我不知道如何在 R 中解析它。
如果 ne_chunk()
最多输入 10 个标记-标签对,它将 return 一个可以使用 as.character()
转换为字符的结果,可以通过常规解析表达式函数(这只是一个 hack,我对此并不满意)。然而,超过十对,它将 return 树的 shorthand 表示,使用 R 方法无法从中提取有意义的数据。
这是一个可重现性最低的示例:
library(reticulate)
nltk <- import("nltk")
sent_tokenize <- function(text, language = "english") {
nltk$tokenize$sent_tokenize(text, language)
}
word_tokenize <- function(text, language = "english", preserve_line = FALSE) {
nltk$tokenize$word_tokenize(text, language, preserve_line)
}
pos_tag <- function(tokens, tagset = NULL, language = "eng") {
nltk$pos_tag(tokens, tagset, language)
}
ne_chunk <- function(tagged_tokens, binary = FALSE) {
nltk$ne_chunk(tagged_tokens, binary)
}
text <- "Christopher is having a difficult time parsing NLTK Trees in R."
tokens <- word_tokenize(text)
tagged_tokens <- pos_tag(tokens)
ne_tagged_tokens <- ne_chunk(tagged_tokens)
这是在处理上一个示例中的文本时 return 编辑的 shorthand:
> ne_tagged_tokens
List (11 items)
这里是 ne_tagged_tokens
所属的 classes:
> class(ne_tagged_tokens)
[1] "nltk.tree.Tree" "python.builtin.list" "python.builtin.object"
我对使用替代的、预先存在的 R 包的建议不感兴趣。
我想问题出在 reticulate
无法读取自定义的 Python 对象,这很常见,因此您必须尽可能接近地传递 Python 对象 Python R 和 Python 接口之间的类型。
有一种方法可以将 ne_chunks
的输出格式更改为字符串 (),使用 Tree.pformat()
:
>>> from nltk import word_tokenize, pos_tag, ne_chunk
>>> sent = "Christopher is having a difficult time parsing NLTK Trees in R."
>>> ne_chunk(pos_tag(word_tokenize(sent)))
Tree('S', [Tree('GPE', [('Christopher', 'NNP')]), ('is', 'VBZ'), ('having', 'VBG'), ('a', 'DT'), ('difficult', 'JJ'), ('time', 'NN'), ('parsing', 'VBG'), Tree('ORGANIZATION', [('NLTK', 'NNP'), ('Trees', 'NNP')]), ('in', 'IN'), Tree('GPE', [('R', 'NNP')]), ('.', '.')])
>>> ne_chunk(pos_tag(word_tokenize(sent))).pformat()
'(S\n (GPE Christopher/NNP)\n is/VBZ\n having/VBG\n a/DT\n difficult/JJ\n time/NN\n parsing/VBG\n (ORGANIZATION NLTK/NNP Trees/NNP)\n in/IN\n (GPE R/NNP)\n ./.)'
要读回,请使用 Tree.fromstring()
:
>>> tree_str = ne_chunk(pos_tag(word_tokenize(sent))).pformat()
>>> from nltk import Tree
>>> Tree.fromstring(tree_str)
Tree('S', [Tree('GPE', ['Christopher/NNP']), 'is/VBZ', 'having/VBG', 'a/DT', 'difficult/JJ', 'time/NN', 'parsing/VBG', Tree('ORGANIZATION', ['NLTK/NNP', 'Trees/NNP']), 'in/IN', Tree('GPE', ['R/NNP']), './.'])
所以我猜想在 R 中这样做可能有效:
text <- "Christopher is having a difficult time parsing NLTK Trees in R."
ne_tagged_tokens <- ne_chunk(pos_tag(word_tokenize(tagged_tokens)))$pformat()
print(ne_tagged_tokens)
但是将字符串读回 R 对象应该是不可能的,因为它无法处理非本地 Python Tree 对象,因此 some_func <- function(...{nltk$some_func(...)})
无法与 [=18= 一起使用] 因为它不是函数。
如果你想将 ne_chunk
树对象的输出操作成一个命名实体列表,那么你必须在 Python 中做这样的事情:
再说一遍,如果您需要 Python 中的函数太多,您真的不想重新编码或使用其他 R 库,为什么不写 Python 而不是坚持 R.
我正在尝试使用 Reticulate 包从 R 中使用 Python 的 NLTK 包。在大多数情况下,我已经成功了。
现在,我想使用 NLTK 的 ne_chunk()
函数执行命名实体识别(即确定哪些标记代表命名实体以及它们代表什么类型的命名实体。)。我的问题是函数 return 是 class nltk.tree.Tree
的对象,我不知道如何在 R 中解析它。
如果 ne_chunk()
最多输入 10 个标记-标签对,它将 return 一个可以使用 as.character()
转换为字符的结果,可以通过常规解析表达式函数(这只是一个 hack,我对此并不满意)。然而,超过十对,它将 return 树的 shorthand 表示,使用 R 方法无法从中提取有意义的数据。
这是一个可重现性最低的示例:
library(reticulate)
nltk <- import("nltk")
sent_tokenize <- function(text, language = "english") {
nltk$tokenize$sent_tokenize(text, language)
}
word_tokenize <- function(text, language = "english", preserve_line = FALSE) {
nltk$tokenize$word_tokenize(text, language, preserve_line)
}
pos_tag <- function(tokens, tagset = NULL, language = "eng") {
nltk$pos_tag(tokens, tagset, language)
}
ne_chunk <- function(tagged_tokens, binary = FALSE) {
nltk$ne_chunk(tagged_tokens, binary)
}
text <- "Christopher is having a difficult time parsing NLTK Trees in R."
tokens <- word_tokenize(text)
tagged_tokens <- pos_tag(tokens)
ne_tagged_tokens <- ne_chunk(tagged_tokens)
这是在处理上一个示例中的文本时 return 编辑的 shorthand:
> ne_tagged_tokens
List (11 items)
这里是 ne_tagged_tokens
所属的 classes:
> class(ne_tagged_tokens)
[1] "nltk.tree.Tree" "python.builtin.list" "python.builtin.object"
我对使用替代的、预先存在的 R 包的建议不感兴趣。
我想问题出在 reticulate
无法读取自定义的 Python 对象,这很常见,因此您必须尽可能接近地传递 Python 对象 Python R 和 Python 接口之间的类型。
有一种方法可以将 ne_chunks
的输出格式更改为字符串 (Tree.pformat()
:
>>> from nltk import word_tokenize, pos_tag, ne_chunk
>>> sent = "Christopher is having a difficult time parsing NLTK Trees in R."
>>> ne_chunk(pos_tag(word_tokenize(sent)))
Tree('S', [Tree('GPE', [('Christopher', 'NNP')]), ('is', 'VBZ'), ('having', 'VBG'), ('a', 'DT'), ('difficult', 'JJ'), ('time', 'NN'), ('parsing', 'VBG'), Tree('ORGANIZATION', [('NLTK', 'NNP'), ('Trees', 'NNP')]), ('in', 'IN'), Tree('GPE', [('R', 'NNP')]), ('.', '.')])
>>> ne_chunk(pos_tag(word_tokenize(sent))).pformat()
'(S\n (GPE Christopher/NNP)\n is/VBZ\n having/VBG\n a/DT\n difficult/JJ\n time/NN\n parsing/VBG\n (ORGANIZATION NLTK/NNP Trees/NNP)\n in/IN\n (GPE R/NNP)\n ./.)'
要读回,请使用 Tree.fromstring()
:
>>> tree_str = ne_chunk(pos_tag(word_tokenize(sent))).pformat()
>>> from nltk import Tree
>>> Tree.fromstring(tree_str)
Tree('S', [Tree('GPE', ['Christopher/NNP']), 'is/VBZ', 'having/VBG', 'a/DT', 'difficult/JJ', 'time/NN', 'parsing/VBG', Tree('ORGANIZATION', ['NLTK/NNP', 'Trees/NNP']), 'in/IN', Tree('GPE', ['R/NNP']), './.'])
所以我猜想在 R 中这样做可能有效:
text <- "Christopher is having a difficult time parsing NLTK Trees in R."
ne_tagged_tokens <- ne_chunk(pos_tag(word_tokenize(tagged_tokens)))$pformat()
print(ne_tagged_tokens)
但是将字符串读回 R 对象应该是不可能的,因为它无法处理非本地 Python Tree 对象,因此 some_func <- function(...{nltk$some_func(...)})
无法与 [=18= 一起使用] 因为它不是函数。
如果你想将 ne_chunk
树对象的输出操作成一个命名实体列表,那么你必须在 Python 中做这样的事情:
再说一遍,如果您需要 Python 中的函数太多,您真的不想重新编码或使用其他 R 库,为什么不写 Python 而不是坚持 R.