如何删除多种语言的停用词?

How to remove stopwords in multiple languages?

我有一个包含两种语言的语料库(语言信息保存在 docvar lang 中)并且想根据 docvar 值删除停用词。

我正在使用一个实质上毫无意义的例子来说明这一点(因为在示例语料库中,所有演讲都是英文的):

library(quanteda)
library(quanteda.corpora)

corp <- corpus(data_corpus_ungd2017) %>%
  corpus_subset(country %in% c("Austria", "Australia"))

corp 现在包含奥地利和比利时的发言;让我们假设它们是用德语和法语给出的:如何根据 country_iso 的值有选择地删除停用词?我试过类似的东西但没有成功。

toks <- corp %>%
  tokens() %>%
  ifelse(docvars(field = "country_iso") == "AUT",
     tokens_remove(stopwords("de")),
     tokens_remove(stopwords("en")))

Error in ifelse(., docvars(field = "country_iso") == "AUT", tokens_remove(stopwords("de")), : unused argument (tokens_remove(stopwords("en")))

如何在一个语料库中最好地实现这一目标?

这是一个有趣的问题!当前在 quanteda (<= v1.5.1) 类列表 tokens 对象不允许分配文档级标记元素,因此基于 lapply() 的解决方案不能使用。最有效的方法是将令牌对象分割成相同语言的块,然后对每个块应用停用词删除。

在您的问题中选择作为示例的 UNDG(联合国一般性辩论)语料库不太适合此示例,因为它完全是英文的,因此我在下面创建了一个双语示例来说明解决方案。

library("quanteda")
## Package version: 1.5.1

txt <- c(
  Austria = "Dies ist ein Beispieltext in deutscher Sprache.",
  Australia = "This is a sample English text.",
  Germany = "Dies ist ein Beispieltext in deutscher Sprache.",
  "United Kingdom" = "This is s sample English text."
)

corp <- corpus(txt,
  docvars = data.frame(country = names(txt), stringsAsFactors = FALSE)
)

现在我们需要创建并设置语言 docvar。可以扩展下面的语言分配功能,或者您可以为语言创建一个单独的 table 国家,并通过一些合并功能创建语言文档。确切的方法不是解决方案的核心,但您确实需要一个语言变量来匹配 stopwords::stopwords() 作为输入的 ISO-639-1 language codes

# language assignemnt function
setlang <- Vectorize(
  vectorize.args = "country",
  FUN = function(country) {
    switch(country,
      "Austria" = "de",
      "Germany" = "de",
      "Australia" = "en",
      "United States" = "en",
      "United Kingdom" = "en"
    )
  }
)

# set a language docvar
docvars(corp, "lang") <- setlang(docvars(corp, "country"))

# inspect
summary(corp)
## Corpus consisting of 4 documents:
## 
##            Text Types Tokens Sentences        country lang
##         Austria     8      8         1        Austria   de
##       Australia     7      7         1      Australia   en
##         Germany     8      8         1        Germany   de
##  United Kingdom     7      7         1 United Kingdom   en
## 
## Source: /private/var/folders/1v/ps2x_tvd0yg0lypdlshg_vwc0000gp/T/RtmpflhaMi/reprex933852cb0380/* on x86_64 by kbenoit
## Created: Sat Nov  2 10:19:59 2019
## Notes:

现在我们可以遍历标记对象并删除每个语言段的停用词。下面我们需要 if 来检查第一种语言的 NULL,因为(目前)我们不能 return 带有 c(NULL, tokensobject) 的标记对象,就像我们可以使用 c() 实现的那样其他对象。

toks <- tokens(corp)

tokslist <- NULL
for (l in unique(docvars(toks, "lang"))) {
  toksthislang <- tokens_subset(toks, lang == l) %>%
    tokens_remove(stopwords(language = l), padding = TRUE)
  tokslist <- if (!is.null(tokslist)) c(tokslist, toksthislang) else toksthislang
}

现在我们可能想把它们按原来的顺序放回去,然后当我们检查它时,我们可以看到适合语言的停用词已被删除。 "pads" 已被保留,以便我们可以看到这一点,出于本示例的目的,但您可能不想保留它们,因此只需在 [=] 中设置 padding = FALSE(默认值) 21=] 在上面调用。

# put back into original order
toks <- tokslist[docnames(toks)]

lapply(toks, head)
## $Austria
## [1] ""             ""             ""             "Beispieltext"
## [5] ""             "deutscher"   
## 
## $Australia
## [1] ""        ""        ""        "sample"  "English" "text"   
## 
## $Germany
## [1] ""             ""             ""             "Beispieltext"
## [5] ""             "deutscher"   
## 
## $`United Kingdom`
## [1] ""        ""        "s"       "sample"  "English" "text"