はじめに
英文(多言語)形態素解析器TreeTagger
をR言語で利用するためのパッケージkoRpus
の出力を、RMeCab::docDF()
の出力の仕様に加工します。
ファイル単位の出力をdocDF()仕様に変換
・設定
## 利用パッケージ # TreeTagger library(koRpus) library(koRpus.lang.en) # MeCab library(RMeCab) # その他処理 library(dplyr) library(readr)
利用するパッケージを読み込みます。
# TreeTaggerを利用するための設定 set.kRp.env(TT.cmd = "C:\\TreeTagger\\bin\\tag-english.bat", lang = "en")
TreeTaggerを使うための設定です。
・英文形態素解析
英語テキストを単語に分解して、各単語の品詞情報を取得します。
# フォルダ名を指定 folder_name <- "text_data" # ファイル名を指定 file_name <- "wonderful_world.txt"
ファイルパス用に、ディレクトリ名とテキストファイル名を指定します。テキスト名は後でも使うので、ここでは分けて指定しています。
# TreeTaggerによる英文形態素解析 res_tt <- taggedText(treetag(paste(folder_name, file_name, sep = "/"))) %>% as_tibble()
ファイルパスを指定して、英文形態素解析を行います。
tail(res_tt)
## # A tibble: 6 x 11 ## doc_id token tag lemma lttr wclass desc stop stem idx sntc ## <fct> <chr> <fct> <chr> <dbl> <fct> <lgl> <lgl> <lgl> <int> <lgl> ## 1 <NA> A DT a 1 determiner NA NA NA 282 NA ## 2 <NA> world NN world 5 noun NA NA NA 283 NA ## 3 <NA> for IN for 3 preposition NA NA NA 284 NA ## 4 <NA> you PP you 3 pronoun NA NA NA 285 NA ## 5 <NA> and CC and 3 conjunction NA NA NA 286 NA ## 6 <NA> me PP me 2 pronoun NA NA NA 287 NA
出力はこんな感じです。
ここから必要な列を取り出します。
# 必要なデータを抽出 tt_data <- res_tt %>% select(lemma, wclass, tag) %>% # 必要な列を取り出す count(lemma, wclass, tag) %>% # 単語の出現頻度を集計 rename(TERM = lemma, !!file_name := n) %>% # RMeCab仕様に列名を変更 arrange(TERM) # 昇順に並べ替え
この例では、lemma
(単語の原型)、wclass
(品詞)、tag
(品詞コード)を用います。
count()
で頻度列を作ります。列名はn
になります。
列名をRMeCab::docDF()
仕様にするために、単語列をTERM
、頻度列をファイル名にrename()
で変更します。
tail(tt_data)
## # A tibble: 6 x 4 ## TERM wclass tag wonderful_world.txt ## <chr> <fct> <fct> <int> ## 1 what pronoun WP 1 ## 2 with preposition IN 2 ## 3 wonderful adjective JJ 4 ## 4 world noun NN 4 ## 5 you pronoun PP 18 ## 6 your pronoun PP$ 5
こんな感じになります。
・品詞情報の対応表の準備
形態素解析の結果は当然英語の品詞情報なので、日本語の品詞情報に変更する必要があります。そのための対応表(未完成)を読み込みます。対応表のデータは私のGitHubレポジトリから取得してください。
# 対応表を読み込む pos_data <- read_csv( "table_data/PoS_data_utf8.csv", col_types = cols( tag = col_factor(), wclass = col_factor() ) )
対応表データのファイルパスを指定して、readr::read_csv()
で読み込みます。(一応品詞情報を因子型に変更していますが、特に意味があるのかないのか…?)
head(pos_data)
## # A tibble: 6 x 7 ## tag wclass POS1 POS2 Description 品詞 Example ## <fct> <fct> <chr> <chr> <chr> <chr> <chr> ## 1 CC conjunct~ 接続詞 <NA> Coordinating conju~ 等位接続詞 and, but, or, & ## 2 CD number 名詞 数 Cardinal number 基数 1, three ## 3 DT determin~ <NA> <NA> Determiner 限定詞 the ## 4 EX existent~ <NA> <NA> existential there 存在文のThere there is ## 5 FW foreign <NA> <NA> foreign word 外国語 d'<U+0153>uvre ## 6 IN preposit~ <NA> <NA> preposition/subord~ 前置詞または従属接続詞~ in,of,like,aft~
ちなみに対応表は完成していません、、、(とりあえず名詞・動詞・形容詞分かればそれで。。)
# 品詞大分類の対応表 wclass_data <- pos_data %>% select(wclass, POS1) %>% # 品詞(大分類)の列を取り出す filter(!is.na(wclass)) %>% # NAの行を除外 distinct(wclass, .keep_all = TRUE) # 重複を除外 # 品詞細分類の対応表 tag_data <- pos_data %>% select(tag, POS2) %>% # 品詞(細分類)の列を取り出す filter(!is.na(tag)) # NAの行を除外
品詞wclass
を品詞大分類POS1
、品詞コードtag
を品詞細分類POS2
として用います。それぞれ取り出してデータフレームにします。
・docDF()仕様に変換
では、解析結果のデータフレームをdocDF()
仕様に変換します。
# RMeCab風に変換 mc_data <- tt_data %>% left_join(wclass_data, by = "wclass") %>% # 品詞(大分類)情報を結合 left_join(tag_data, by = "tag") %>% # 品詞(細分類)情報を結合 select(TERM, POS1, POS2, all_of(file_name)) # 必要な列を取り出す
left_join()
で品詞情報列を結合することで、日本語品詞情報を与えます。(foctors
のレベルが違うという警告メッセージが出ます。)
tail(mc_data)
## # A tibble: 6 x 4 ## TERM POS1 POS2 wonderful_world.txt ## <chr> <chr> <chr> <int> ## 1 what 名詞 Wh 1 ## 2 with <NA> <NA> 2 ## 3 wonderful 形容詞 <NA> 4 ## 4 world 名詞 <NA> 4 ## 5 you 名詞 代名詞 18 ## 6 your 名詞 代名詞 5
これで完成です(NA
なのは、対応表を埋め切れていないためです)。
一応直接docDF()
で処理した場合の出力も確認しておきます。
# (確認用)MeCabによる形態素解析 res_mc <- docDF(paste(folder_name, file_name, sep = "/"), type = 1) %>% as_tibble() tail(res_mc)
## # A tibble: 6 x 4 ## TERM POS1 POS2 wonderful_world.txt ## <chr> <chr> <chr> <int> ## 1 with 名詞 一般 2 ## 2 wonderful 名詞 一般 4 ## 3 world 名詞 一般 4 ## 4 you 名詞 一般 12 ## 5 your 名詞 一般 5 ## 6 … 記号 一般 1
品詞が全て名詞になってしまいます。
フォルダ単位の出力をdocDF()仕様に変換
続いて、フォルダを丸ごと処理する場合です。
# フォルダ名を指定 folder_name <- "text_data/lyrics_avr" # ファイル名を取得 file_name_list <- list.files(path = folder_name, pattern = "txt")
ディレクトリを指定して、その中のファイル名を取得します。
形態素解析を行います。
# TreeTaggerによる英文形態素解析 tt_data <- tibble( TERM = character(), wclass = factor(), tag = factor() ) for(i in seq_along(file_name_list)) { # ファイル名を抽出 file_name <- file_name_list[i] # 形態素解析 res_tt <- taggedText(treetag(paste(folder_name, file_name, sep = "/"))) %>% as_tibble() # 必要なデータを抽出 tmp_tt_data <- res_tt %>% select(lemma, wclass, tag) %>% # 必要な列を取り出す count(lemma, wclass, tag) %>% # 単語の出現頻度を集計 rename(TERM = lemma, !!file_name := n) %>% # RMeCab仕様に列名を変更 arrange(TERM) # 昇順に並べ替え # 結果を結合 tt_data <- full_join(tt_data, tmp_tt_data, by = c("TERM", "wclass", "tag")) } # NAを0に置換 tt_data[is.na.data.frame(tt_data)] <- 0
1つずつ処理して、結果を結合していきます。
テキストに含まれない単語の頻度がNA
となるので、0に置換します。
head(tt_data[, 1:8], 10)
## # A tibble: 10 x 8 ## TERM wclass tag avr_001.txt avr_002.txt avr_003.txt avr_004.txt ## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> ## 1 ' posse~ POS 8 0 0 0 ## 2 ' punct~ '' 4 2 0 0 ## 3 - punct~ : 1 1 0 1 ## 4 ( punct~ ( 11 1 0 0 ## 5 ) punct~ ) 11 1 0 0 ## 6 @car~ number CD 1 11 0 0 ## 7 and conju~ CC 6 7 0 5 ## 8 arou~ adverb RB 1 0 0 3 ## 9 arou~ prepo~ IN 1 0 0 1 ## 10 Avril name NP 1 1 0 1 ## # ... with 1 more variable: avr_005.txt <dbl>
こんな感じになるはずです。
RMeCab::docDF
仕様に変換します。
# RMeCab風に変換 mc_data <- tt_data %>% left_join(wclass_data, by = "wclass") %>% # 品詞(大分類)情報を結合 left_join(tag_data, by = "tag") %>% # 品詞(細分類)情報を結合 select(TERM, POS1, POS2, all_of(file_name_list)) # 必要な列を取り出す
頻度列がテキストファイル数分になるので、file_name_list
を指定する点が異なります。
head(mc_data[, 1:8], 10)
## # A tibble: 10 x 8 ## TERM POS1 POS2 avr_001.txt avr_002.txt avr_003.txt avr_004.txt avr_005.txt ## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 ' <NA> <NA> 8 0 0 0 0 ## 2 ' 記号 <NA> 4 2 0 0 0 ## 3 - 記号 一般結合~ 1 1 0 1 0 ## 4 ( 記号 <NA> 11 1 0 0 0 ## 5 ) 記号 <NA> 11 1 0 0 0 ## 6 @car~ 名詞 数 1 11 0 0 0 ## 7 and 接続詞~ <NA> 6 7 0 5 0 ## 8 arou~ 副詞 <NA> 1 0 0 3 0 ## 9 arou~ <NA> <NA> 1 0 0 1 0 ## 10 Avril <NA> <NA> 1 1 0 1 0
これで完成です。
# (確認用)MeCabによる形態素解析 res_mc <- docDF(folder_name, type = 1) %>% as_tibble() head(res_mc[, 1:8], 10)
## # A tibble: 10 x 8 ## TERM POS1 POS2 avr_001.txt avr_002.txt avr_003.txt avr_004.txt avr_005.txt ## <chr> <chr> <chr> <int> <int> <int> <int> <int> ## 1 "!" 名詞 サ変接続~ 0 4 0 0 0 ## 2 "!)" 名詞 サ変接続~ 0 0 0 0 0 ## 3 "!," 名詞 サ変接続~ 0 0 0 0 0 ## 4 "\"" 名詞 サ変接続~ 0 0 0 0 0 ## 5 "\"," 名詞 サ変接続~ 0 0 0 0 0 ## 6 "&" 名詞 サ変接続~ 0 0 0 0 0 ## 7 "'" 名詞 サ変接続~ 45 3 0 20 0 ## 8 "'," 名詞 サ変接続~ 0 0 0 0 0 ## 9 "'..~ 名詞 サ変接続~ 0 0 0 0 0 ## 10 "(" 名詞 サ変接続~ 11 1 0 0 0
直接処理するとこのように出力されます。
以上!
参考文献
品詞の情報については一部こちらのページのものを使わせていただきました。
computer-technology.hateblo.jp
おわりに
私は歌詞を分析したいんです!J-POPの歌詞って英文が混じってるんですよね。それでMeCabだけじゃダメじゃんとなって、こういうことが必要になりました。
対応表はいつか完成させます。いつかね。
そろそろホントにfor()
使いを卒業したい。
2020年07月17日!元こぶしファクトリー現Juice=Juice井上玲音さん19歳のお誕生日!れいれいおめでとおおお!!