概要
RからMeCabを呼ぶときに辞書を変えるときのメモ。公式ページに{RMeCab}を利用する例がありますが、今回は{Rcpp}でラッパーを作ってNEologdを使います。
-
MeCab: Yet Another Part-of-Speech and Morphological Analyzer
- Neologism dictionary based on the language resources on the Web for mecab-ipadic
事前準備
NEologdのインストールは、公開先のREADMEに記載してあるコードを実行しました。
Neologdインストール
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
$ ./bin/install-mecab-ipadic-neologd -n
# 自分のMac環境だとインストール先は下記
$ echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
/usr/local/Cellar/mecab/0.996/lib/mecab/dic/mecab-ipadic-neologd
定義・設定
{Rcpp}でラッパーを作成し、入出力用にRの関数を定義。
パッケージ読み込みと関数定義
library(Rcpp)
library(dplyr)
library(tidyr)
# ラッパー作成
Sys.setenv("PKG_LIBS" = "-lmecab")
callRcppMecab <- Rcpp::cppFunction(
code = '
Rcpp::DataFrame executeMecab(std::string str, std::string tagger_opt) {
using namespace Rcpp;
using namespace MeCab;
std::vector<std::string> surface, feature;
MeCab::Tagger *tagger = MeCab::createTagger(tagger_opt.c_str());
const MeCab::Node *node(tagger->parseToNode(str.c_str()));
for (; node; node = node->next) {
if (node->stat != MECAB_BOS_NODE & node->stat != MECAB_EOS_NODE) {
surface.push_back(std::string(node->surface, node->length));
feature.push_back(std::string(node->feature));
}
}
delete tagger;
return Rcpp::wrap(
Rcpp::DataFrame::create(
Rcpp::Named("surface") = surface,
Rcpp::Named("feature") = feature
)
);
}',
includes = c("#include <mecab.h>")
)
# 整形用関数
# 素性レベル(l)と辞書のパス(d)のみを指定
callMecab <- function (string, tagger_param = list(l = 2, d = NULL)) {
if (length(x = tagger_param) > 0) {
tagger_opt_str <- lapply(
X = names(x = tagger_param),
FUN = function (tg) {
if (!is.null(x = tagger_param[[tg]]) & is.element(el = tg, set = c("l", "d"))) {
return(
stringr::str_c(stringr::str_c("-", tg), tagger_param[tg], sep = " ")
)
}
}
) %>%
unlist %>%
stringr::str_c(collapse = " ")
} else {
tagger_opt_str <- ""
}
return(
callRcppMecab(str = as.character(x = string), tagger_opt = tagger_opt_str) %>%
tidyr::separate(
col = feature,
into = c("pos", "pos1", "pos2", "pos3", "ctype", "cform", "baseform", "orth", "pron"),
sep = ",", fill = "right"
)
)
}
実行例
# タガー用の引数を与えないときはデフォルト呼び出し
> callMecab(
string = "すもももももももものうち",
tagger_param = list()
)
surface pos pos1 pos2 pos3 ctype cform baseform orth pron
1 すもも 名詞 一般 * * * * すもも スモモ スモモ
2 も 助詞 係助詞 * * * * も モ モ
3 もも 名詞 一般 * * * * もも モモ モモ
4 も 助詞 係助詞 * * * * も モ モ
5 もも 名詞 一般 * * * * もも モモ モモ
6 の 助詞 連体化 * * * * の ノ ノ
7 うち 名詞 非自立 副詞可能 * * * うち ウチ ウチ
# NEologdのインストールパスを指定
> callMecab(
string = "すもももももももものうち",
tagger_param = list(
d ="/usr/local/Cellar/mecab/0.996/lib/mecab/dic/mecab-ipadic-neologd"
)
)
surface pos pos1 pos2 pos3 ctype cform baseform orth pron
1 すもももももももものうち 名詞 固有名詞 一般 * * * すもももももももものうち スモモモモモモモモノウチ スモモモモモモモモノウチ
辞書を変えた結果が反映されています。
まとめ
{Rcpp}でラッパーを作り、引数の切り替えによってNEologdを用いた形態素解析も実行できるようにしました。これにより、Rでのテキスト分析を様々な入力で試したくなるかと思います。
長らく放置しているRでいろいろな形態素解析器を呼び出すライブラリの更新をそろそろしたいですが、Window対応からは逃げたいところです。
参考
実行環境
実行環境
> devtools::session_info()
Session info ----------------------------------------------------------------------------------------------------------------------------------
setting value
version R version 3.3.1 (2016-06-21)
system x86_64, darwin13.4.0
ui RStudio (1.0.44)
language (EN)
collate ja_JP.UTF-8
tz Asia/Tokyo
date 2016-11-04
Packages --------------------------------------------------------------------------------------------------------------------------------------
package * version date source
assertthat 0.1 2013-12-06 CRAN (R 3.3.1)
DBI 0.5 2016-08-11 cran (@0.5)
devtools 1.12.0 2016-06-24 CRAN (R 3.3.0)
digest 0.6.9 2016-01-08 CRAN (R 3.3.0)
dplyr * 0.5.0 2016-06-24 CRAN (R 3.3.1)
magrittr 1.5 2014-11-22 CRAN (R 3.3.1)
memoise 1.0.0 2016-01-29 CRAN (R 3.3.0)
R6 2.1.3 2016-08-19 cran (@2.1.3)
Rcpp * 0.12.7 2016-09-05 cran (@0.12.7)
stringi 1.1.1 2016-05-27 CRAN (R 3.3.1)
stringr 1.1.0 2016-08-19 cran (@1.1.0)
tibble 1.2 2016-08-26 cran (@1.2)
tidyr * 0.6.0 2016-08-12 cran (@0.6.0)
withr 1.0.2 2016-06-20 CRAN (R 3.3.0)