8

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

次のエラーが発生します。

10 x 3809 クラス "dgCMatrix" のスパース行列 validObject(x) のエラー: 無効なクラス "dgCMatrix" オブジェクト: 長さ (Dimnames[1]) は 10 である Dim[1] とは異なります

私の質問は次のとおりです: 私が書いた関数に何か問題がありますか? また、なぜ私が書いた関数が 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)
4

1 に答える 1

8

text2vec使用して問題を報告していただきありがとうございます。ドキュメントに間違いがあります (この例をどこに置いたか教えていただけますか?)。Stem トークナイザーは次のようになります。

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

ロジックは次のとおりです。

  1. 文字ベクトルを取得してトークン化します。出力は文字ベクトルのリストです (リストの各要素 = 文字ベクトルはドキュメントです)。
  2. 次に、リストの各要素にステミングを適用します (wordStem文字ベクトルに適用できます)。

lapplyしたがって、あなたが従った例には私の構文ミスがありました。Mb 単純な R で演算子なしで書き直すと、より明確に%>%なるため、次のようになります。

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

また、1000 ではなく 10 のドキュメントを受け取っている理由についても説明します。デフォルトでは、text2vec::itokenデータを 10 のチャンクに分割し (これはitoken関数で調整できます)、チャンクごとに処理します。したがって、unlist各チャンクに適用する場合、実際には再帰的に 100 個のドキュメントをリストから外し、1 つの文字ベクトルを作成します。

于 2016-11-21T12:21:40.717 に答える