【问题标题】:Stemming function for text2vectext2vec 的词干提取功能
【发布时间】:2017-04-04 18:22:56
【问题描述】:

我在 R 中使用 text2vec 并且难以编写与 text2vec 包中的 itoken 函数一起使用的词干函数。 text2vec 文档建议使用此词干提取功能:

stem_tokenizer1 =function(x) {
  word_tokenizer(x) %>% lapply(SnowballC::wordStem(language='en'))
 }

但是,此功能不起作用。这是我运行的代码(借用以前的 stackoverflow 答案):

library(text2vec)
library(data.table)
library(SnowballC)
data("movie_review")
train_rows = 1:1000
prepr = tolower
stem_tokenizer1 =function(x) {
  word_tokenizer(x) %>% lapply(SnowballC::wordStem(language='en'))
 }
tok = stem_tokenizer1
it <- itoken(movie_review$review[train_rows], prepr, tok, ids = movie_review$id[train_rows])

这是它产生的错误:

{ 中的错误:缺少参数“words”,没有默认值

我认为问题在于 wordStem 需要一个字符向量,但 word_tokenizer 会生成一个字符向量列表。

mr<-movie_review$review[1]
stem_mr1<-stem_tokenizer1(mr)

SnowballC::wordStem(language = "en") 中的错误: 缺少参数“words”,没有默认值

为了解决这个问题,我写了这个词干函数:

stem_tokenizer2 = function(x)  {
  list(unlist(word_tokenizer(x)) %>% SnowballC::wordStem(language='en') )
}

但是,此函数不适用于 create_vocabulary 函数。

data("movie_review")
train_rows = 1:1000
prepr = tolower
stem_tokenizer2 = function(x)  {
  list(unlist(word_tokenizer(x)) %>% SnowballC::wordStem(language='en') )
}
tok = stem_tokenizer2
it <- itoken(movie_review$review[train_rows], prepr, tok, ids = movie_review$id[train_rows])
v <- create_vocabulary(it) %>% prune_vocabulary(term_count_min = 5)

没有错误,但是当您查看文档计数时,文档的数量与数据中的 1000 不同,因此您无法创建文档术语矩阵或运行 LDA。

v$document_count

[1] 10

这段代码:

dtm_train <- create_dtm(it, vectorizer)
dtm_train

产生这个错误:

“dgCMatrix”类的 10 x 3809 稀疏矩阵 有效对象(x)中的错误: 无效类“dgCMatrix”对象:长度(Dimnames[1])与 Dim[1] 不同,即 10

我的问题是:我写的函数有问题吗?为什么我写的函数会在 create_vocabulary 中产生这个错误?我怀疑这是我的函数输出格式的问题,但它看起来与 word_tokenizer 函数的输出格式相同,并且适用于 itoken 和 create_vocabulary:

mr<-movie_review$review[1]
word_mr<-word_tokenizer(mr)
stem_mr<-stem_tokenizer2(mr)
str(word_mr)
str(stem_mr)

【问题讨论】:

    标签: r text2vec


    【解决方案1】:

    感谢您使用text2vec 并报告问题。 文档中有一个错误(你能指出我把这个例子放在哪里,所以我可以修复它吗?)。 词干分词器应如下所示:

    stem_tokenizer1 =function(x) {
      word_tokenizer(x) %>% lapply( function(x) SnowballC::wordStem(x, language="en"))
     }
    

    逻辑如下:

    1. 它采用字符向量并对其进行标记。输出是列表 字符向量(列表的每个元素 = 字符向量都是一个文档)。
    2. 然后我们对列表的每个元素应用词干提取(wordStem 可以应用于字符向量)

    因此,在您遵循的示例中,lapply 存在语法错误。 Mb 如果我们在没有%&gt;% 运算符的情况下用纯 R 重写它会更清楚,所以它看起来像:

    stem_tokenizer1 =function(x) {
      tokens = word_tokenizer(x)
      lapply(tokens, SnowballC::wordStem, language="en")
    }
    

    我还将解释为什么您收到 10 个文档而不是 1000 个。默认情况下 text2vec::itoken 将数据拆分为 10 个块(可以在 itoken 函数中调整)并逐块处理它。 因此,当您在每个块上应用 unlist 时,实际上是递归地取消列出 100 个文档并创建 1 个字符向量。

    【讨论】:

    • 感谢您的快速回复。我运行了代码,它的文档数为 30,这与您在创建 1 个字符向量时提到的问题相同吗?代码:data("movie_review") train_rows = 1:1000 prepr = tolower stem_tokenizer1 =function(x) { word_tokenizer %&gt;% lapply( function(x) SnowballC::wordStem(x, language="en")) } tok = stem_tokenizer1 it &lt;- itoken(movie_review$review[train_rows], prepr, tok, ids = movie_review$id[train_rows]) v &lt;- create_vocabulary(it) %&gt;% prune_vocabulary(term_count_min = 5) v$document_count
    • 我的错。 word_tokenizer(x) 中遗漏了 x,请参阅更新后的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多