【问题标题】:step_mutate with textrecipes tokenlistsstep_mutate 与 textrecipes 标记列表
【发布时间】:2021-12-28 13:49:18
【问题描述】:

我正在使用 tidymodels 框架进行 NLP,利用 textrecipes 包,其中包含用于文本预处理的配方步骤。这里,step_tokenize 将字符向量作为输入并返回一个tokenlist 对象。现在,我想使用 hunspell 包中的函数使用自定义函数对新的标记化变量执行拼写检查,以确保正确拼写,但出现以下错误 (link to the spell check blog post):

Error: Problem with `mutate()` column `desc`.
i `desc = correct_spelling(desc)`.
x is.character(words) is not TRUE

显然,tokenlists 不容易解析为字符向量。我注意到step_untokenize 的存在,但只是通过粘贴和折叠来解散令牌列表,这不是我需要的。

REPREX

library(tidyverse)
library(tidymodels)
library(textrecipes)
library(hunspell)

product_descriptions <- tibble(
  desc = c("goood product", "not sou good", "vad produkt"),
  price = c(1000, 700, 250)
)

correct_spelling <- function(input) {
  output <- case_when(
    # check and (if required) correct spelling
    !hunspell_check(input, dictionary('en_US')) ~
      hunspell_suggest(input, dictionary('en_US')) %>%
      # get first suggestion, or NA if suggestions list is empty
      map(1, .default = NA) %>%
      unlist(),
    TRUE ~ input # if word is correct
  )
  # if input incorrectly spelled but no suggestions, return input word
  ifelse(is.na(output), input, output)
}

product_recipe <- recipe(desc ~ price, data = product_descriptions) %>% 
  step_tokenize(desc) %>% 
  step_mutate(desc = correct_spelling(desc))

product_recipe %>% prep()

我想要什么,但没有食谱

product_descriptions %>% 
  unnest_tokens(word, desc) %>% 
  mutate(word = correct_spelling(word))

【问题讨论】:

    标签: r nlp spell-checking r-recipes


    【解决方案1】:

    目前还没有使用 {textrecipes} 的规范方法。我们需要两件事,一个接受标记向量并返回经过拼写检查的标记(您提供)的函数,以及将该函数应用于tokenlist 的每个元素的方法。目前,没有一个通用的步骤可以让你这样做,但你可以通过将函数传递给step_stem() 中的custom_stemmer 来欺骗它。给你想要的结果

    library(tidyverse)
    library(tidymodels)
    #> Registered S3 method overwritten by 'tune':
    #>   method                   from   
    #>   required_pkgs.model_spec parsnip
    library(textrecipes)
    library(hunspell)
    
    product_descriptions <- tibble(
      desc = c("goood product", "not sou good", "vad produkt"),
      price = c(1000, 700, 250)
    )
    
    correct_spelling <- function(input) {
      output <- case_when(
        # check and (if required) correct spelling
        !hunspell_check(input, dictionary('en_US')) ~
          hunspell_suggest(input, dictionary('en_US')) %>%
          # get first suggestion, or NA if suggestions list is empty
          map(1, .default = NA) %>%
          unlist(),
        TRUE ~ input # if word is correct
      )
      # if input incorrectly spelled but no suggestions, return input word
      ifelse(is.na(output), input, output)
    }
    
    product_recipe <- recipe(desc ~ price, data = product_descriptions) %>% 
      step_tokenize(desc) %>% 
      step_stem(desc, custom_stemmer = correct_spelling) %>%
      step_tf(desc)
    
    product_recipe %>% 
      prep() %>%
      bake(new_data = NULL)
    #> # A tibble: 3 × 6
    #>   price tf_desc_cad tf_desc_good tf_desc_not tf_desc_product tf_desc_sou
    #>   <dbl>       <dbl>        <dbl>       <dbl>           <dbl>       <dbl>
    #> 1  1000           0            1           0               1           0
    #> 2   700           0            1           1               0           1
    #> 3   250           1            0           0               1           0
    

    【讨论】:

    • custom_stemmer 方法似乎在 step_lemma 之后不起作用(spaCy on tokenization),因为前者返回一个字符向量。如何克服这个问题?
    • 没错。您尝试做的事情不会起作用,因为 step_tokenize(engine = "spacyr") 提取令牌和引理,而 step_lemma() 只是将它们拉出。因此,如果您在创建引理之前尝试进行拼写检查,则必须在 step_tokenize() 之前进行。
    • 在拼写检查之前我想删除一些停用词。您知道一种无需标记即可删除停用词的方法吗?
    • 我还没有看到这样做的方法。标记化后无法删除停用词是否有原因?
    • 我可以,但不能在标记化之后进行拼写检查,我想在拼写检查之前删除停用词。原因是我有很多我不想拼写检查的首字母缩略词,所以我宁愿删除它们。
    猜你喜欢
    • 2018-07-18
    • 1970-01-01
    • 2010-12-31
    • 2020-03-31
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    相关资源
    最近更新 更多