Code
<-
dat_txt ::tibble(
tibbledoc_id = seq_along(audubon::polano) |> as.character(),
text = audubon::polano
|>
) ::mutate(text = audubon::strj_normalize(text))
dplyr<- gibasa::tokenize(dat_txt, text, doc_id) dat
<-
dat_txt ::tibble(
tibbledoc_id = seq_along(audubon::polano) |> as.character(),
text = audubon::polano
|>
) ::mutate(text = audubon::strj_normalize(text))
dplyr<- gibasa::tokenize(dat_txt, text, doc_id) dat
dplyrを使って簡単にやる場合、次のようにすると2-gramを集計できます。
<- gibasa::ngram_tokenizer(2)
bigram
<- dat |>
dat_ngram ::prettify(col_select = "Original") |>
gibasa::mutate(
dplyrtoken = dplyr::if_else(is.na(Original), token, Original)
|>
) ::reframe(token = bigram(token, sep = "-"), .by = doc_id) |>
dplyr::count(doc_id, token)
dplyr
str(dat_ngram)
#> tibble [24,398 × 3] (S3: tbl_df/tbl/data.frame)
#> $ doc_id: Factor w/ 899 levels "1","2","3","4",..: 1 1 2 3 3 3 3 3 3 4 ...
#> $ token : chr [1:24398] "の-広場" "ポラーノ-の" "宮沢-賢治" "レオーノ・キュースト-誌" ...
#> $ n : int [1:24398] 1 1 1 1 1 1 1 1 1 1 ...
なお、RMeCabでできるような「名詞-名詞」の2-gramだけを抽出したいといったケースでは、2-gramをつくる前に品詞でフィルタしてしまうと元の文書内におけるトークンの隣接関係を破壊してしまい、正しい2-gramを抽出することができません。そのようなことをしたい場合には、あらかじめ品詞のNgramもつくったうえで、後から品詞のNgramでフィルタします。
<- dat |>
dat_ngram ::prettify(col_select = c("POS1", "Original")) |>
gibasa::mutate(
dplyrtoken = dplyr::if_else(is.na(Original), token, Original)
|>
) ::reframe(
dplyrtoken = bigram(token, sep = "-"),
pos = bigram(POS1, sep = "-"), # 品詞のNgramをつくる
.by = doc_id
|>
) ::filter(pos %in% c("名詞-名詞")) |> # 品詞のNgramでフィルタする
dplyr::count(doc_id, token)
dplyr
str(dat_ngram)
#> tibble [890 × 3] (S3: tbl_df/tbl/data.frame)
#> $ doc_id: Factor w/ 899 levels "1","2","3","4",..: 2 3 3 3 3 3 4 4 5 5 ...
#> $ token : chr [1:890] "宮沢-賢治" "レオーノ・キュースト-誌" "七-等" "十-七" ...
#> $ n : int [1:890] 1 1 1 1 1 1 1 1 1 1 ...
gibasa::pack
を使ってNgramの分かち書きをつくることもできます。この場合、次のようにquantedaの枠組みの中でNgramをトークンとして数えることで集計することができます。
<- dat |>
dat_ngram ::prettify(col_select = "Original") |>
gibasa::mutate(token = dplyr::if_else(is.na(Original), token, Original)) |>
dplyr::pack(n = 2)
gibasa
str(dat_ngram)
#> tibble [899 × 2] (S3: tbl_df/tbl/data.frame)
#> $ doc_id: Factor w/ 899 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
#> $ text : chr [1:899] "ポラーノ-の の-広場" "宮沢-賢治" "前-十 十-七 七-等 等-官 官-レオーノ・キュースト レオーノ・キュースト-誌" "宮沢-賢治 賢治-訳述" ...
|>
dat_ngram ::corpus() |>
quanteda::tokens(what = "fastestword") |>
quanteda::dfm()
quanteda#> Document-feature matrix of: 899 documents, 10,890 features (99.75% sparse) and 0 docvars.
#> features
#> docs ポラーノ-の の-広場 宮沢-賢治 前-十 十-七 七-等 等-官
#> 1 1 1 0 0 0 0 0
#> 2 0 0 1 0 0 0 0
#> 3 0 0 0 1 1 1 1
#> 4 0 0 1 0 0 0 0
#> 5 0 0 0 0 0 0 0
#> 6 0 0 0 0 0 0 1
#> features
#> docs 官-レオーノ・キュースト レオーノ・キュースト-誌 賢治-訳述
#> 1 0 0 0
#> 2 0 0 0
#> 3 1 1 0
#> 4 0 0 1
#> 5 0 0 0
#> 6 0 0 0
#> [ reached max_ndoc ... 893 more documents, reached max_nfeat ... 10,880 more features ]
また、quantedaの枠組みの中でNgramをつくりながら数えて集計することもできます。
<- dat |>
dat_ngram ::prettify(col_select = "Original") |>
gibasa::mutate(token = dplyr::if_else(is.na(Original), token, Original)) |>
dplyr::pack()
gibasa
str(dat_ngram)
#> tibble [899 × 2] (S3: tbl_df/tbl/data.frame)
#> $ doc_id: Factor w/ 899 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
#> $ text : chr [1:899] "ポラーノ の 広場" "宮沢 賢治" "前 十 七 等 官 レオーノ・キュースト 誌" "宮沢 賢治 訳述" ...
|>
dat_ngram ::corpus() |>
quanteda::tokens(what = "fastestword") |>
quanteda::tokens_ngrams(n = 2) |>
quanteda::dfm()
quanteda#> Document-feature matrix of: 899 documents, 10,890 features (99.75% sparse) and 0 docvars.
#> features
#> docs ポラーノ_の の_広場 宮沢_賢治 前_十 十_七 七_等 等_官
#> 1 1 1 0 0 0 0 0
#> 2 0 0 1 0 0 0 0
#> 3 0 0 0 1 1 1 1
#> 4 0 0 1 0 0 0 0
#> 5 0 0 0 0 0 0 0
#> 6 0 0 0 0 0 0 1
#> features
#> docs 官_レオーノ・キュースト レオーノ・キュースト_誌 賢治_訳述
#> 1 0 0 0
#> 2 0 0 0
#> 3 1 1 0
#> 4 0 0 1
#> 5 0 0 0
#> 6 0 0 0
#> [ reached max_ndoc ... 893 more documents, reached max_nfeat ... 10,880 more features ]