使用正则表达式构建多词短语的特征向量,以在 R 中使用 quanteda 构建 dfm
Construct a character vector of multi-word phrases using regex for building dfm using quanteda in R
我非常满意 quanteda 的 textstat_collocation() 用于提取 MWE。现在我正在尝试提取所有匹配特定模式的匹配项,而不管它们的频率如何。
我的 objective 是通过从使用正则表达式模式构建的 dfm() 中提取特征名称来创建字符向量。然后,我将在 "select" 参数中使用此字符向量来构建 dfm。我可能还想使用此字符向量添加到我用作 ontology 的字典中,以便在管道的后期构建 dfms。
模式是:"aged xx-xx" 其中 x 是一个数字。
我使用正则表达式模式 "aged\s([0-9]{2}-[0-9]{2})" here 并获得了所需的匹配项。但是当我在 R 中尝试它时(在“\s”之前添加一个额外的“\”),我没有得到任何匹配项。
当我这样做时:
txt <- c("In India, male smokers aged 20-45 perceive brandX positively.",
"In Spain, female buyers aged 30-39 don't purchase brandY.")
ageGroups <- dfm(txt, select = "aged\s([0-9]{2}-[0-9]{2})", valuetype = "regex")
featnames(ageGroups)
我得到:
character(0)
然而,当我尝试时:
ageGroups <- dfm(txt, select = "([0-9]{2}-[0-9]{2})", valuetype = "regex")
featnames(ageGroups)
我得到:
[1] "20-45" "30-39"
看来我无法捕捉正则表达式中的白色 space。我在 SO 中经历了许多类似的问题,也许 this 是最相关的,但仍然无法使我的特定 objective 起作用。
我也试过:
tokens <- tokens(txt, remove_punct = FALSE, remove_numbers = FALSE, remove_symbols = FALSE)
tokensCompunded <- tokens_compound(tokens, pattern = "aged\s([0-9]{2}-[0-9]{2})", valuetype = "regex")
attr(tokensCompunded, "types")
但是我拿回了所有代币:
[1] "In" " " "India" "," "male" "smokers" "aged" "20-45" "perceive"
[10] "brandX" "positively" "." "Spain" "female" "buyers" "30-39" "don't" "purchase"
[19] "brandY"
我认为可能还有其他几种更有效的方法可以使用带有 quanteda 的正则表达式(或 glob)来提取字符向量,我很高兴学习如何使用这个令人惊叹的 R 包的新方法。
感谢您的帮助!
编辑原问题:
SO中的other question也有类似的要求,即使用kwic对象检测多词短语,可以进一步扩展以实现上述objectives添加以下内容:
kwicObject <- kwic(corpus, pattern = phrase("aged ([0-9]{2}-[0-9]{2})"), valuetype = "regex")
unique(kwicObject$keyword)
您可以更改正则表达式模式:
select = "aged.*([0-9]{2}-[0-9]{2})"
这里的问题是目标文本和多词 pattern
(其中包含白色 space)没有以相同的方式进行标记化。在您的示例中,您已经为多个标记应用了正则表达式(其中包括白色 space 分隔符),但搜索目标已被拆分为单个标记。
我们为此设计了一个解决方案,一个名为 phrase()
的函数。来自 ?pattern
:
Whitespace is not privileged, so that in a character vector, white
space is interpreted literally. If you wish to consider
whitespace-separated elements as sequences of tokens, wrap the
argument in phrase()
.
所以在这种情况下:
pat <- "aged [0-9]{2}-[0-9]{2}"
toks2 <- tokens_select(toks, pattern = phrase(pat), valuetype = "regex")
toks2
# tokens from 2 documents.
# text1 :
# [1] "aged" "20-45"
#
# text2 :
# [1] "aged" "30-39"
在这里,我们看到选择有效,因为 phrase()
包装器将模式转换为匹配序列。
如果你想让它们成为一个单一的标记,你可以将相同的 pattern
参数发送到 tokens_compound()
:
toks3 <- tokens_compound(toks2, pattern = phrase(pat),
valuetype = "regex", concatenator = " ")
toks3
# tokens from 2 documents.
# text1 :
# [1] "aged 20-45"
#
# text2 :
# [1] "aged 30-39"
最后,您可以使用它来构建 dfm,其中每个多词匹配都是一个特征。除非您首先在标记阶段执行了连接,否则这是行不通的,因为根据定义,dfm 在其特征中没有顺序。
dfm(toks3)
# Document-feature matrix of: 2 documents, 2 features (50% sparse).
# 2 x 2 sparse Matrix of class "dfm"
# features
# docs aged 20-45 aged 30-39
# text1 1 0
# text2 0 1
我非常满意 quanteda 的 textstat_collocation() 用于提取 MWE。现在我正在尝试提取所有匹配特定模式的匹配项,而不管它们的频率如何。
我的 objective 是通过从使用正则表达式模式构建的 dfm() 中提取特征名称来创建字符向量。然后,我将在 "select" 参数中使用此字符向量来构建 dfm。我可能还想使用此字符向量添加到我用作 ontology 的字典中,以便在管道的后期构建 dfms。
模式是:"aged xx-xx" 其中 x 是一个数字。
我使用正则表达式模式 "aged\s([0-9]{2}-[0-9]{2})" here 并获得了所需的匹配项。但是当我在 R 中尝试它时(在“\s”之前添加一个额外的“\”),我没有得到任何匹配项。
当我这样做时:
txt <- c("In India, male smokers aged 20-45 perceive brandX positively.",
"In Spain, female buyers aged 30-39 don't purchase brandY.")
ageGroups <- dfm(txt, select = "aged\s([0-9]{2}-[0-9]{2})", valuetype = "regex")
featnames(ageGroups)
我得到:
character(0)
然而,当我尝试时:
ageGroups <- dfm(txt, select = "([0-9]{2}-[0-9]{2})", valuetype = "regex")
featnames(ageGroups)
我得到:
[1] "20-45" "30-39"
看来我无法捕捉正则表达式中的白色 space。我在 SO 中经历了许多类似的问题,也许 this 是最相关的,但仍然无法使我的特定 objective 起作用。
我也试过:
tokens <- tokens(txt, remove_punct = FALSE, remove_numbers = FALSE, remove_symbols = FALSE)
tokensCompunded <- tokens_compound(tokens, pattern = "aged\s([0-9]{2}-[0-9]{2})", valuetype = "regex")
attr(tokensCompunded, "types")
但是我拿回了所有代币:
[1] "In" " " "India" "," "male" "smokers" "aged" "20-45" "perceive"
[10] "brandX" "positively" "." "Spain" "female" "buyers" "30-39" "don't" "purchase"
[19] "brandY"
我认为可能还有其他几种更有效的方法可以使用带有 quanteda 的正则表达式(或 glob)来提取字符向量,我很高兴学习如何使用这个令人惊叹的 R 包的新方法。
感谢您的帮助!
编辑原问题:
kwicObject <- kwic(corpus, pattern = phrase("aged ([0-9]{2}-[0-9]{2})"), valuetype = "regex")
unique(kwicObject$keyword)
您可以更改正则表达式模式:
select = "aged.*([0-9]{2}-[0-9]{2})"
这里的问题是目标文本和多词 pattern
(其中包含白色 space)没有以相同的方式进行标记化。在您的示例中,您已经为多个标记应用了正则表达式(其中包括白色 space 分隔符),但搜索目标已被拆分为单个标记。
我们为此设计了一个解决方案,一个名为 phrase()
的函数。来自 ?pattern
:
Whitespace is not privileged, so that in a character vector, white space is interpreted literally. If you wish to consider whitespace-separated elements as sequences of tokens, wrap the argument in
phrase()
.
所以在这种情况下:
pat <- "aged [0-9]{2}-[0-9]{2}"
toks2 <- tokens_select(toks, pattern = phrase(pat), valuetype = "regex")
toks2
# tokens from 2 documents.
# text1 :
# [1] "aged" "20-45"
#
# text2 :
# [1] "aged" "30-39"
在这里,我们看到选择有效,因为 phrase()
包装器将模式转换为匹配序列。
如果你想让它们成为一个单一的标记,你可以将相同的 pattern
参数发送到 tokens_compound()
:
toks3 <- tokens_compound(toks2, pattern = phrase(pat),
valuetype = "regex", concatenator = " ")
toks3
# tokens from 2 documents.
# text1 :
# [1] "aged 20-45"
#
# text2 :
# [1] "aged 30-39"
最后,您可以使用它来构建 dfm,其中每个多词匹配都是一个特征。除非您首先在标记阶段执行了连接,否则这是行不通的,因为根据定义,dfm 在其特征中没有顺序。
dfm(toks3)
# Document-feature matrix of: 2 documents, 2 features (50% sparse).
# 2 x 2 sparse Matrix of class "dfm"
# features
# docs aged 20-45 aged 30-39
# text1 1 0
# text2 0 1