🌿

Rによる自然言語処理(tidymodels, BPE, fasttext, XGBoost)

commits29 min read

この記事について

以前に書いた記事を焼き直ししつつ、ばんくしさんの以下のブログ記事のまねをRでやってみます。

ばんくしさんの記事は「Pythonどこまで脱却できるのか見るのも兼ねて」ということで、Rustで自然言語処理を試しています。私はべつに自然言語処理を実務でやるエンジニアとかではないですが、PythonじゃなくてRustとかGoといった静的型付けで速い言語で安全に書けたらうれしい場面があるよね、みたいなモチベーションなのかなと想像しています。

実際のところ、自分でコードを書きながら自然言語処理の真似事をするなら依然としてPythonが便利です。Rと比べても、PythonにはSudachiPyjanomeといった選択肢がある一方で、RにはRコンソールからのみで導入が完了する形態素解析の手段が(少なくともCRANには)ありません。自然言語処理をやる言語としてPythonのほうがメジャーなことにはほかにもいくつかの理由というか経緯があるのでしょうが、Pythonを採用したほうがよいひとつのモチベーションとしては、テキストマイニングして得た特徴量を投入してディープラーニングをしたい場合は事実上Pythonを選択するしかないというのもある気がします。一応、{keras}{torch}というのもありますが、このあたりのパッケージを使うのはまだ趣味の領域な気がします。

そうはいっても、RMeCabは強力なツールです。なぜかRからテキストマイニングに入ってしまった人間にとって、比較的簡単に導入できてほとんど環境を問わずすぐ使えるRMeCabは欠かせないツールだったことでしょう。ただ、Rに慣れてきていろいろなことをやってみたくなると、RMeCabは「なんか使いにくいな」みたいになりがちです。Rでも自然言語処理をやるためのパッケージは以下に紹介されているようにたくさんあるのですが、そもそも日本語情報があまりないし、そこそこがんばらないと詰まります。

https://twitter.com/dataandme/status/1092509662384189441

でもまあRでもできなくはないんだよというのをしめす目的で、ここでは先の記事と同じようなことをRでやっていきます。

パッケージの選定にあたって

Tokenization

形態素解析などをやるパッケージとしては次に挙げるようなものがあります。知るかぎりではぜんぶ個人開発で、環境や使用する辞書、解析する文字列などによって上手く動いたり動かなかったりします。Neologd辞書を使うならRcppMeCabにすべきですが、メンテナの人が最近忙しいとかで、あまりアクティブに開発されていません。
(2021年9月補足:RMeCabはv1.06で半角スペースを含む語彙を正しく解析できるようになり、UNIX系の環境ではNeologd辞書も問題なく使えるようになった。一方で、歴史的経緯から、Windows環境ではRのデフォルトロケールであるCP932の解析結果が返されるため、UTF-8の辞書を扱うには依然として手間がかかる)

Universal Dependenciesなら次が使えます。udpipeはC++実装のラッパー、spacyrはPythonバックエンドです。

最近になってbnosacからBPE(Byte Pair Encoding)とsentencepieceのRラッパーがリリースされました。

Language Representations

アクティブに開発されていそうなものとして、このあたりのパッケージがあります。

セットアップ

suppressWarnings({
  library("tidymodels")
  library("textrecipes")
  library("tokenizers.bpe")
  library("zipangu") ## uribo/zipangu
  library("fastrtext") ## pommedeterresautee/fastrtext
  library("RcppMeCab") ## paithiov909/RcppMeCab
  library("ldccr") ## paithiov909/ldccr
  # 以下、その他に必要なやつ
  requireNamespace("text2vec")
  requireNamespace("xgboost")
})
#> Registered S3 method overwritten by 'tune':
#>   method                   from   
#>   required_pkgs.model_spec parsnip
#> ── Attaching packages ────────────────────────────────────── tidymodels 0.1.3 ──
#> ✔ broom        0.7.9      ✔ recipes      0.1.16
#> ✔ dials        0.0.9      ✔ rsample      0.1.0 
#> ✔ dplyr        1.0.7      ✔ tibble       3.1.4 
#> ✔ ggplot2      3.3.5      ✔ tidyr        1.1.3 
#> ✔ infer        1.0.0      ✔ tune         0.1.6 
#> ✔ modeldata    0.1.1      ✔ workflows    0.2.3 
#> ✔ parsnip      0.1.7      ✔ workflowsets 0.1.0 
#> ✔ purrr        0.3.4      ✔ yardstick    0.0.8
#> ── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
#> ✖ purrr::discard() masks scales::discard()
#> ✖ dplyr::filter()  masks stats::filter()
#> ✖ dplyr::lag()     masks stats::lag()
#> ✖ recipes::step()  masks stats::step()
#> • Use tidymodels_prefer() to resolve common conflicts.
#> 
#> Attaching package: 'RcppMeCab'
#> The following object is masked from 'package:tidyr':
#> 
#>     pack
#> Loading required namespace: text2vec
#> Loading required namespace: xgboost

データの準備

livedoorニュースコーパスを使います。以下の9カテゴリです。

  • トピックニュース
  • Sports Watch
  • ITライフハック
  • 家電チャンネル
  • MOVIE ENTER
  • 独女通信
  • エスマックス
  • livedoor HOMME
  • Peachy

パーサを書いたので、それでデータフレームにします。

data <- ldccr::read_ldnws()
#> Parsing dokujo-tsushin...
#> Parsing it-life-hack...
#> Parsing kaden-channel...
#> Parsing livedoor-homme...
#> Parsing movie-enter...
#> Parsing peachy...
#> Parsing smax...
#> Parsing sports-watch...
#> Parsing topic-news...
#> Done.

この記事を書いた当初はRcppMeCab + Neologdでの形態素解析を試そうとして上手くいかず、rjavacmecabという自作パッケージで代用していました(動くけど非常に遅い)。以下のような感じです。

corpus_mecab <- data %>%
  dplyr::sample_frac(.01) %>%
  dplyr::mutate(category = as.factor(category)) %>%
  dplyr::mutate(body = normalize(body)) %>%
  tibble::rowid_to_column()

corpus_mecab <- corpus_mecab %>%
  dplyr::group_by(rowid) %>%
  dplyr::group_map(~
  .x$body %>%
    rjavacmecab::cmecab(sep = "\t") %>%
    rjavacmecab::prettify(sep = "\t") %>%
    dplyr::pull(Original) %>%
    paste(collapse = " ")) %>%
  purrr::map_dfr(~ tibble::tibble(tokens = .)) %>%
  dplyr::bind_cols(corpus_mecab)

その後、RcppMeCabを使う場合には次のような感じでできるのを確認しました。ただし、2021年1月現在CRANにあるバージョン(0.0.1.2)は未知語の処理にバグがあるようなので、ここではソースを修正したものを使っています。

corpus_mecab <- data %>%
  dplyr::select(-file_path) %>%
  dplyr::mutate(category = as.factor(category)) %>%
  dplyr::mutate(body = zipangu::str_jnormalize(body)) %>%
  tibble::rowid_to_column()

corpus_mecab <- corpus_mecab %>%
  dplyr::pull(body) %>%
  RcppMeCab::posParallel(format = "data.frame") %>%
  RcppMeCab::pack() %>%
  dplyr::left_join(corpus_mecab, by = c("doc_id" = "rowid"))

tokenizer.bpeでサブワード分割する場合。

corpus_bpe <- data %>%
  dplyr::select(-file_path) %>%
  dplyr::mutate(category = as.factor(category)) %>%
  dplyr::mutate(body = zipangu::str_jnormalize(body)) %>%
  tibble::rowid_to_column()

token_model <- data %>%
  dplyr::pull(body) %>%
  tokenizers.bpe::bpe(vocab_size = 5000) ## equal to default

corpus_bpe <- corpus_bpe %>%
  dplyr::pull(body) %>%
  purrr::map(
    ~ tokenizers.bpe::bpe_encode(token_model, x = ., type = "subword")
  ) %>%
  purrr::flatten() %>%
  purrr::map_dfr(~ tibble(text = paste(., collapse = " "))) %>%
  dplyr::bind_cols(corpus_bpe)

こういうデータになります。

corpus <- list(mecab = corpus_mecab, bpe = corpus_bpe) %>%
  purrr::walk(~ dplyr::glimpse(.)) %>%
  purrr::map(~ rsample::initial_split(., prop = .8))
#> Rows: 7,367
#> Columns: 6
#> $ doc_id     <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
#> $ text       <chr> "友人 代表 の スピーチ 、 独女 は どう こなし て いる ? も…
#> $ category   <fct> dokujo-tsushin, dokujo-tsushin, dokujo-tsushin, dokujo-tsus…
#> $ source     <chr> "http://news.livedoor.com/article/detail/4778030/", "http:/…
#> $ time_stamp <chr> "2010-05-22T14:30:00+0900", "2010-05-21T14:30:00+0900", "20…
#> $ body       <chr> "友人代表のスピーチ、独女はどうこなしている?もうすぐジュー…
#> Rows: 7,367
#> Columns: 6
#> $ text       <chr> "▁ 友 人 代表 の スピ ー チ 、 独女 はどう こ な している ?…
#> $ rowid      <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
#> $ category   <fct> dokujo-tsushin, dokujo-tsushin, dokujo-tsushin, dokujo-tsus…
#> $ source     <chr> "http://news.livedoor.com/article/detail/4778030/", "http:/…
#> $ time_stamp <chr> "2010-05-22T14:30:00+0900", "2010-05-21T14:30:00+0900", "20…
#> $ body       <chr> "友人代表のスピーチ、独女はどうこなしている?もうすぐジュー…

モデルの学習1(FeatureHashing)

次のような関数でデータを分割します。

prep_corpus <- function(corpus, recipe) {
  train <- recipe %>%
    recipes::juice()
  test <- recipe %>%
    recipes::bake(rsample::testing(corpus))

  return(list(train = train, test = test))
}

以下のレシピとモデルで学習します。ハッシュトリックを使っています。デフォルトだとパラメータはここに書いている感じになります。

model <- parsnip::boost_tree() %>%
  parsnip::set_engine("xgboost") %>%
  parsnip::set_mode("classification") %>%
  parsnip::translate()

fit_corpus <- function(corpus, model) {
  recipe <- recipes::recipe(
    category ~ text,
    data = rsample::training(corpus)
  ) %>%
    textrecipes::step_tokenize(text) %>%
    textrecipes::step_texthash(text) %>%
    recipes::prep()

  split <- prep_corpus(corpus, recipe)

  fitted <- model %>%
    parsnip::fit(category ~ ., data = split$train)

  fitted %>%
    predict(split$test) %>%
    dplyr::bind_cols(split$test) %>%
    yardstick::metrics(truth = category, estimate = .pred_class) %>%
    print()
}

print(model)
#> Boosted Tree Model Specification (classification)
#> 
#> Computational engine: xgboost 
#> 
#> Model fit template:
#> parsnip::xgb_train(x = missing_arg(), y = missing_arg(), nthread = 1, 
#>     verbose = 0)

fitして、精度をみてみます。

purrr::walk(corpus, ~ fit_corpus(., model))
#> [11:11:00] WARNING: amalgamation/../src/learner.cc:1095: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'multi:softprob' was changed from 'merror' to 'mlogloss'. Explicitly set eval_metric if you'd like to restore the old behavior.
#> # A tibble: 2 × 3
#>   .metric  .estimator .estimate
#>   <chr>    <chr>          <dbl>
#> 1 accuracy multiclass     0.897
#> 2 kap      multiclass     0.884
#> [11:11:36] WARNING: amalgamation/../src/learner.cc:1095: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'multi:softprob' was changed from 'merror' to 'mlogloss'. Explicitly set eval_metric if you'd like to restore the old behavior.
#> # A tibble: 2 × 3
#>   .metric  .estimator .estimate
#>   <chr>    <chr>          <dbl>
#> 1 accuracy multiclass     0.895
#> 2 kap      multiclass     0.881

モデルの学習2(fasttext)

BPEでサブワード分割した文書について、fasttextで埋め込みを得てから学習してみます。あくまで試してみる目的のため、ここでは50次元のベクトルにします。

temp <- tempfile(fileext = ".txt")
readr::write_lines(
  corpus_bpe$text,
  file = temp
)
fastrtext::execute(c("skipgram", "-input", temp, "-output", "model", "-dim", 50L))
#> 
Read 1M words
Read 2M words
Read 3M words
Read 4M words
Read 5M words
Read 5M words
#> Number of words:  4686
#> Number of labels: 0
#> 
#### とくにsuppressしないかぎり、ここから下に学習状況がずらーっとプリントされる ####

モデルの読み込み。

ft_model <- fastrtext::load_model("model.bin")

データフレームに整形します。

vocab <- fastrtext::get_dictionary(ft_model)
Encoding(vocab) <- "UTF-8" ## For Windows machine
embeddings <- ft_model %>%
  fastrtext::get_word_vectors(vocab) %>%
  as.data.frame() %>%
  dplyr::bind_cols(tibble::tibble(vocab = vocab)) %>%
  dplyr::select(vocab, everything())

remove(ft_model)

今度は次のようなレシピで学習します。上でやったのと同じように素直にやろうとすると手元の環境ではメモリが足りなかったので、ここではtextrecipes::step_tokenfilterで語彙を削っています。

fit_corpus_b <- function(corpus, model) {
  recipe <- recipes::recipe(
    category ~ text,
    data = rsample::training(corpus)
  ) %>%
    textrecipes::step_tokenize(text) %>%
    textrecipes::step_tokenfilter(text, min_times = 3L, max_tokens = 50L) %>%
    textrecipes::step_word_embeddings(
      text,
      embeddings = tibble::as_tibble(embeddings)
    ) %>%
    recipes::prep()

  split <- prep_corpus(corpus, recipe)

  fitted <- model %>%
    parsnip::fit(category ~ ., data = split$train)

  fitted %>%
    predict(split$test) %>%
    dplyr::bind_cols(split$test) %>%
    yardstick::metrics(truth = category, estimate = .pred_class) %>%
    print()
}

fitします(なんか思ったほど精度がよくないのでどこか間違っているのかもしれない)。

fit_corpus_b(corpus$bpe, model)
#> [11:14:22] WARNING: amalgamation/../src/learner.cc:1095: Starting in XGBoost 1.3.0, the default evaluation metric used with the objective 'multi:softprob' was changed from 'merror' to 'mlogloss'. Explicitly set eval_metric if you'd like to restore the old behavior.
#> # A tibble: 2 × 3
#>   .metric  .estimator .estimate
#>   <chr>    <chr>          <dbl>
#> 1 accuracy multiclass     0.599
#> 2 kap      multiclass     0.547

所感

livedoorニュースコーパスはそんなに大きなコーパスじゃないのでサクッとできてほしいのですが、textrecipesで埋め込みを扱うには手元の環境では不足なようでした(たぶん私が使っているPCが古いだけですが)。

このコーパスのカテゴリ分類はかなり易しいタスクであることが知られている(というか、一部のカテゴリではそのカテゴリを同定できる単語が本文に含まれてしまっている)ので相性もあるのでしょうが、ハッシュトリックしてXGBoostに投入するだけで簡単によい精度の予測ができる点は気持ちよいです。bnosac/sentencepieceもtokenizer.bpeと同じノリで使えるようなので、サブワード分割でよければRでも簡単にできるとわかりました。

一方で、RcppMeCabは使えるようにするまでが依然としてめんどくさいということもあり、分かち書きするだけならほかの手段のほうが簡単な気がします。

セッション情報

sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 4.1.1 (2021-08-10)
#>  os       Ubuntu 20.04.2 LTS          
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language (EN)                        
#>  collate  C.UTF-8                     
#>  ctype    C.UTF-8                     
#>  tz       UTC                         
#>  date     2021-08-31                  
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  ! package        * version     date       lib
#>  P assertthat       0.2.1       2019-03-21 [?]
#>  P backports        1.2.1       2020-12-09 [?]
#>  P bit              4.0.4       2020-08-04 [?]
#>  P bit64            4.0.5       2020-08-30 [?]
#>  P broom          * 0.7.9       2021-07-27 [?]
#>  P cachem           1.0.6       2021-08-19 [?]
#>  P class            7.3-19      2021-05-03 [?]
#>  P cli              3.0.1       2021-07-17 [?]
#>  P codetools        0.2-16      2018-12-24 [?]
#>  P colorspace       2.0-2       2021-06-24 [?]
#>  P crayon           1.4.1       2021-02-08 [?]
#>  P data.table       1.14.0      2021-02-21 [?]
#>  P dials          * 0.0.9       2020-09-16 [?]
#>  P DiceDesign       1.9         2021-02-13 [?]
#>  P digest           0.6.27      2020-10-24 [?]
#>  P dplyr          * 1.0.7       2021-06-18 [?]
#>  P ellipsis         0.3.2       2021-04-29 [?]
#>  P evaluate         0.14        2019-05-28 [?]
#>  P fansi            0.5.0       2021-05-25 [?]
#>  P fastmap          1.1.0       2021-01-25 [?]
#>  P fastrtext      * 0.3.4       2021-08-31 [?]
#>  P float            0.2-4       2020-04-22 [?]
#>  P foreach          1.5.1       2020-10-15 [?]
#>  P furrr            0.2.3       2021-06-25 [?]
#>  P future           1.22.1      2021-08-25 [?]
#>  P generics         0.1.0       2020-10-31 [?]
#>  P ggplot2        * 3.3.5       2021-06-25 [?]
#>  P globals          0.14.0      2020-11-22 [?]
#>  P glue             1.4.2       2020-08-27 [?]
#>  P gower            0.2.2       2020-06-23 [?]
#>  P GPfit            1.0-8       2019-02-08 [?]
#>  P gtable           0.3.0       2019-03-25 [?]
#>  P hardhat          0.1.6       2021-07-14 [?]
#>  P hms              1.1.0       2021-05-17 [?]
#>  P htmltools        0.5.2       2021-08-25 [?]
#>  P infer          * 1.0.0       2021-08-13 [?]
#>  P ipred            0.9-11      2021-03-12 [?]
#>  P iterators        1.0.13      2020-10-15 [?]
#>  P jsonlite         1.7.2       2020-12-09 [?]
#>  P knitr            1.33        2021-04-24 [?]
#>  P lattice          0.20-44     2021-05-02 [?]
#>  P lava             1.6.9       2021-03-11 [?]
#>  P ldccr          * 0.0.6       2021-08-31 [?]
#>  P lgr              0.4.2       2021-01-10 [?]
#>  P lhs              1.1.1       2020-10-05 [?]
#>  P lifecycle        1.0.0       2021-02-15 [?]
#>  P listenv          0.8.0       2019-12-05 [?]
#>  P lubridate        1.7.10      2021-02-26 [?]
#>  P magrittr         2.0.1       2020-11-17 [?]
#>  P MASS             7.3-54      2021-05-03 [?]
#>  P Matrix           1.3-4       2021-06-01 [?]
#>  P memoise          2.0.0       2021-01-26 [?]
#>  P mlapi            0.1.0       2017-12-17 [?]
#>  P modeldata      * 0.1.1       2021-07-14 [?]
#>  P munsell          0.5.0       2018-06-12 [?]
#>  P nnet             7.3-16      2021-05-03 [?]
#>  P parallelly       1.27.0      2021-07-19 [?]
#>  P parsnip        * 0.1.7       2021-07-21 [?]
#>  P pillar           1.6.2       2021-07-29 [?]
#>  P pkgconfig        2.0.3       2019-09-22 [?]
#>  P plyr             1.8.6       2020-03-03 [?]
#>  P pROC             1.17.0.1    2021-01-13 [?]
#>  P prodlim          2019.11.13  2019-11-17 [?]
#>  P purrr          * 0.3.4       2020-04-17 [?]
#>  P R.cache          0.15.0      2021-04-30 [?]
#>  P R.methodsS3      1.8.1       2020-08-26 [?]
#>  P R.oo             1.24.0      2020-08-26 [?]
#>  P R.utils          2.10.1      2020-08-26 [?]
#>  P R6               2.5.1       2021-08-19 [?]
#>  P Rcpp             1.0.7       2021-07-07 [?]
#>  P RcppMeCab      * 0.0.1.3.900 2021-08-31 [?]
#>  P RcppParallel     5.1.4       2021-05-04 [?]
#>  P readr            2.0.1       2021-08-10 [?]
#>  P recipes        * 0.1.16      2021-04-16 [?]
#>  P rematch2         2.1.2       2020-05-01 [?]
#>  P renv             0.14.0      2021-07-21 [?]
#>  P RhpcBLASctl      0.20-137    2020-05-17 [?]
#>  P rlang            0.4.11      2021-04-30 [?]
#>  P rmarkdown        2.10        2021-08-06 [?]
#>  P rpart            4.1-15      2019-04-12 [?]
#>  P rsample        * 0.1.0       2021-05-08 [?]
#>  P rsparse          0.4.0       2020-04-01 [?]
#>  P rstudioapi       0.13        2020-11-12 [?]
#>  P scales         * 1.1.1       2020-05-11 [?]
#>  P sessioninfo      1.1.1       2018-11-05 [?]
#>  P SnowballC        0.7.0       2020-04-01 [?]
#>  P stringi          1.7.4       2021-08-25 [?]
#>  P stringr          1.4.0       2019-02-10 [?]
#>  P styler           1.5.1       2021-07-13 [?]
#>  P survival         3.2-13      2021-08-24 [?]
#>  P text2vec         0.6         2020-02-18 [?]
#>  P textrecipes    * 0.4.1       2021-07-11 [?]
#>  P tibble         * 3.1.4       2021-08-25 [?]
#>  P tidymodels     * 0.1.3       2021-04-19 [?]
#>  P tidyr          * 1.1.3       2021-03-03 [?]
#>  P tidyselect       1.1.1       2021-04-30 [?]
#>  P timeDate         3043.102    2018-02-21 [?]
#>  P tokenizers       0.2.1       2018-03-29 [?]
#>  P tokenizers.bpe * 0.1.0       2019-08-02 [?]
#>  P tune           * 0.1.6       2021-07-21 [?]
#>  P tzdb             0.1.2       2021-07-20 [?]
#>  P utf8             1.2.2       2021-07-24 [?]
#>  P vctrs            0.3.8       2021-04-29 [?]
#>  P vroom            1.5.4       2021-08-05 [?]
#>  P withr            2.4.2       2021-04-18 [?]
#>  P workflows      * 0.2.3       2021-07-16 [?]
#>  P workflowsets   * 0.1.0       2021-07-22 [?]
#>  P xfun             0.25        2021-08-06 [?]
#>  P xgboost          1.4.1.1     2021-04-22 [?]
#>  P yaml             2.2.1       2020-02-01 [?]
#>  P yardstick      * 0.0.8       2021-03-28 [?]
#>  P zipangu        * 0.2.3.9000  2021-08-31 [?]
#>  source                                       
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  Github (pommedeterresautee/fastrtext@b63c5de)
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  Github (paithiov909/ldccr@5907848)           
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  Github (paithiov909/RcppMeCab@208f1de)       
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  CRAN (R 4.1.1)                               
#>  Github (uribo/zipangu@316afb3)               
#> 
#> [1] /home/runner/work/nlp-using-r/nlp-using-r/renv/library/R-4.1/x86_64-pc-linux-gnu
#> [2] /tmp/RtmpeC5aar/renv-system-library
#> 
#>  P ── Loaded and on-disk path mismatch.
GitHubで編集を提案

Discussion

ログインするとコメントできます