以前の記事
で、SudachiPyをRで使う方法を書きました。その続きです。
文字列の分割
for()
ではなく、sapply()
関数を使ったコードで考えていきます。
txt <- "吾輩は猫である"
morphemes <- tokenizer$tokenize(txt)
it_morphemes <- iterate(morphemes)
sapply(it_morphemes, function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'
文字列ベクトルの分割
上のコードのtxt
の代わりに文字列ベクトルvec_txt
で実行するとエラーになります。
vec_txt <- c("吾輩は猫である", "名前はまだない")
morphemes <- tokenizer$tokenize(vec_txt)
it_morphemes <- iterate(morphemes)
sapply(it_morphemes, function(m) m$surface())
# Error in py_call_impl(callable, dots$args, dots$keywords): TypeError: argument 'text': 'list' object cannot be converted to 'PyString'
最初に文字列ベクトルをpaste()
関数で結合してから、形態素に分割する方法を考えました。
vec_txt <- c("吾輩は猫である", "名前はまだない")
txt <- paste(vec_txt, collapse="")
morphemes <- tokenizer$tokenize(txt)
it_morphemes <- iterate(morphemes)
sapply(it_morphemes, function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'・'名前'・'は'・'まだ'・'ない'
しかし、これでは次のような間違いが起こる可能性があります。
vec_txt <- c("ここで", "はきものを脱いでください")
txt <- paste(vec_txt, collapse="")
morphemes <- tokenizer$tokenize(txt)
it_morphemes <- iterate(morphemes)
sapply(it_morphemes, function(m) m$surface())
# 'ここ'・'で'・'は'・'きもの'・'を'・'脱い'・'で'・'ください'
そこで、lapply()
関数を使いました。
vec_txt <- c("吾輩は猫である", "名前はまだない")
morphemes <- lapply(vec_txt, function(t) tokenizer$tokenize(t))
it_morphemes <- lapply(morphemes, function(m) iterate(m))
vec_morphemes <- unlist(it_morphemes)
sapply(vec_morphemes, function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'・'名前'・'は'・'まだ'・'ない'
省略可能(もともと書く必要がない)な部分をなくすと次のようになります。
vec_txt <- c("吾輩は猫である", "名前はまだない")
morphemes <- lapply(vec_txt, tokenizer$tokenize)
it_morphemes <- lapply(morphemes, iterate)
vec_morphemes <- unlist(it_morphemes)
sapply(vec_morphemes, function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'・'名前'・'は'・'まだ'・'ない'
すっきり書くために、R 4.1.0より導入されたパイプ演算子|>
を使ってみました。
c("吾輩は猫である", "名前はまだない") |>
lapply(tokenizer$tokenize) |>
lapply(iterate) |>
unlist() |>
sapply(function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'・'名前'・'は'・'まだ'・'ない'
先程間違いが起こった例も正しく分割されました。
c("ここで", "はきものを脱いでください") |>
lapply(tokenizer$tokenize) |> lapply(iterate) |> unlist() |>
sapply(function(m) m$surface())
# 'ここ'・'で'・'はきもの'・'を'・'脱い'・'で'・'ください'
品詞の表示
形態素に分割するとともに、品詞も表示するようにしてみました。
"吾輩は猫である" |>
lapply(tokenizer$tokenize) |> sapply(iterate) |> unlist() |>
sapply(function(m) c(m$surface(), unlist(m$part_of_speech())[1]))
# A matrix: 2 × 5 of type chr
# 吾輩 は 猫 で ある
# 代名詞 助詞 名詞 助動詞 動詞
指定した品詞だけを取り出すことができます。
c("吾輩は猫である", "名前はまだない") |>
lapply(tokenizer$tokenize) |> sapply(iterate) |> unlist() |>
sapply(function(m) c(m$surface(), unlist(m$part_of_speech())[1])) ->
words
pos <- c("名詞","代名詞")
is_select <- TRUE
words[1, words[2,] %in% pos == is_select]
# '吾輩'・'猫'・'名前'
逆に、同じコードでis_select <- FALSE
とするだけで、指定した品詞以外を取り出すこともできます。
c("吾輩は猫である", "名前はまだない") |>
lapply(tokenizer$tokenize) |> sapply(iterate) |> unlist() |>
sapply(function(m) c(m$surface(), unlist(m$part_of_speech())[1])) ->
words
pos <- c("名詞","代名詞")
is_select <- FALSE
words[1, words[2,] %in% pos == is_select]
# 'は'・'で'・'ある'・'は'・'まだ'・'ない'
今回はここまで、
それではRでも、良いSudachi Lifeを