【问题标题】:How to remove stopwords in multiple languages?如何删除多种语言的停用词?
【发布时间】:2019-11-01 17:49:08
【问题描述】:

我有一个包含两种语言的语料库(语言信息保存在 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")))

ifelse(., docvars(field = "country_iso") == "AUT", tokens_remove(stopwords("de")), 中的错误: 未使用的参数 (tokens_remove(stopwords("en")))

我怎样才能最好地在一个语料库中实现这一目标?

【问题讨论】:

    标签: r quanteda


    【解决方案1】:

    这是一个有趣的问题!目前在 quanteda (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。可以扩展下面的语言分配功能,或者您可以为语言创建单独的国家表并通过某些合并功能创建语言文档。确切的方法不是解决方案的核心,但您确实需要一个与ISO-639-1 language codes 匹配的语言变量,stopwords::stopwords() 将其作为输入。

    # 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 是否为第一种语言,因为(目前)我们无法返回带有 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
    }
    

    现在我们可能希望将它们放回原来的顺序,然后当我们检查它时,我们可以看到与语言相关的停用词已被删除。出于本示例的目的,“垫”已被保留,因此我们可以看到这一点,但您可能不想保留它们,因此只需在上面的 tokens_remove() 调用中设置 padding = FALSE(默认值)。

    # 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"
    

    【讨论】:

    • 谢谢 - 这很好用。但是,我在下游遇到了我怀疑是由于这种操纵引起的问题 - 可能是这种情况吗?我正在尝试创建一个 dfm() 并通过 docvar 应用 dfm_group()。错误Error in generate_groups(x, groups) : groups must name docvars or provide data matching the documents in x 可能是由此引起的吗?有没有办法解决这个问题?我的直觉是,操作会删除 docvar 信息(作为同一语料库上的常规 dfm_group(),没有操作不会引发错误),尽管我不是 100% 确定。
    猜你喜欢
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    相关资源
    最近更新 更多