バイアスと戯れる

Rと言語処理と(Rによる言語処理100本ノック終了)

Japan.R 2015にてLT発表しました

概要

 記事を書くのが遅くなりましたが、12月5日に開催されたJapan.RのLTセッションにて、『Rと形態素解析』というタイトルで形態素解析の説明と、Rで形態素解析ならびにわかち書きする方法を紹介しました。総ページ数80オーバーでしたが、なんとか無事に終えることができました。運営の方々、参加者の皆さん、お疲れさまでした。
 今回は参照しやすいように資料内に書いたRコードを、ブログに記述しました。

Japan.R 2015 : ATND

speakerdeck.com



発表について

 LT発表スライドの概要は次の通りです。

  • 形態素解析について
  • Rで形態素解析器を呼び出す方法について
  • 辞書なしでわかち書きするTinySegmenterをRパッケージ化したので、これを紹介

 以上のような発表をさせていただきました。

 形態素解析についての説明は勉強を兼ねた資料になっており、LT時には時間の関係上、飛ばさせていただきました。
 形態素解析の仕組みや辞書引きの話、コスト設定などから、点推定による形態素解析や未知語処理、教師なし形態素解析やRNN-LSTMを用いた形態素解析など最近の話題についてもまとめてみました。言語モデルとスムージング、隠れマルコフモデルとCRFについては省略してしまいましたが、ご興味のある方はお読みください。




Rコードについて

 資料内で記載した、Rから形態素解析器を呼び出すコードを下記に掲載しました。試してみたいと思った方はお使いください。

RからMeCabを使う{Rcpp}編

library(Rcpp)
# MeCabのC++ APIのRcppコード
# MeCabタガー生成の索性レベルは2
# 表層文字列と素性のみを形態素解析結果として受け取る
# http://taku910.github.io/mecab/bindings.html
rcpp_src <- '
Rcpp::DataFrame executeMecab(SEXP str) {
  using namespace Rcpp;
  using namespace MeCab;

  std::string input = Rcpp::as<std::string>(str);
  std::vector<std::string> surface, feature;

  MeCab::Tagger *tagger = MeCab::createTagger("-l 2");
  const MeCab::Node *node(tagger->parseToNode(input.c_str()));
  for (; node; node = node->next) {
      if (node->stat != MECAB_BOS_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
    )
  );

}
'

Sys.setenv("PKG_LIBS" = "-lmecab")
executeMecab <- Rcpp::cppFunction(
  code = rcpp_src,
  includes = c("#include <mecab.h>")
)

SET_INPUT_STRING <- c("この先生きのこれるか")
> executeMecab(str = SET_INPUT_STRING)
   surface                                              feature
1     この                      連体詞,*,*,*,*,*,この,コノ,コノ
2       先                       名詞,一般,*,*,*,*,,サキ,サキ
3     生き           動詞,自立,*,*,一段,連用形,生きる,イキ,イキ
4 のこれる 動詞,自立,*,*,一段,基本形,のこれる,ノコレル,ノコレル
5       か       助詞,副助詞/並立助詞/終助詞,*,*,*,*,,,6                                       BOS/EOS,*,*,*,*,*,*,*,*

RMeCabを使う

# install.packages ("RMeCab", repos = “http://rmecab.jp/R”)
library(RMeCab)
> RMeCab::RMeCabC(str = SET_INPUT_STRING) %>%
+     unlist(use.names = TRUE)
    連体詞       名詞       動詞       動詞       助詞 
    "この"       "先"     "生き" "のこれる"       "か" 

 やはり、{RMeCab}を使いましょう。

RからKyTeaを使う{Rcpp}編

rcpp_kytea_src <- '
Rcpp::List executeKytea(SEXP str) {

  using namespace Rcpp;
  using namespace std;
  using namespace kytea;

  std::string input = Rcpp::as<std::string>(str);
  std::vector<std::string> surface;
  std::vector<std::vector<std::map<std::string, double>>> feature;
  
  kytea::Kytea kytea;
  KyteaConfig* config = kytea.getConfig();
  kytea.readModel(config->getModelFile().c_str());
  StringUtil* util = kytea.getStringUtil(); 
  
  // 一文を表すオブジェクトを作る
  KyteaString surface_string = util->mapString(input.c_str());
  KyteaSentence sentence(surface_string, util->normalize(surface_string));
  
  kytea.calculateWS(sentence);
  const KyteaSentence::Words & words =  sentence.words;
  // 各タグ種類に対してタグ付与を行う
  for (auto i : boost::irange(0, int(config->getNumTags()))) {
    kytea.calculateTags(sentence, i);    
  }
  
  for (auto i : boost::irange(0, (int)words.size())) {
    surface.push_back(util->showString(words[i].surface));
    
    // 各タグ種に対して
    std::vector<std::map<std::string, double>> tag_vec;
    for (auto j : boost::irange(0, (int)words[i].tags.size())) {
      std::map<std::string, double> tag_pairs;
      for (auto k : boost::irange(0, (int)words[i].tags[j].size())) {
        tag_pairs[util->showString(words[i].tags[j][k].first)] = words[i].tags[j][k].second;
      }
      tag_vec.push_back(tag_pairs);
    }
    feature.push_back(tag_vec);
  }
  
  return 
    Rcpp::List::create(
      Rcpp::Named("surface") = surface,
      Rcpp::Named("feature") = feature
    );
}
'

Sys.setenv("PKG_LIBS" = "-lkytea")
executeKytea <- Rcpp::cppFunction(
  code = rcpp_kytea_src,
  includes = c(
    "#include <boost/range/irange.hpp>",
    "#include <kytea/kytea.h>", "#include <kytea/kytea-struct.h>", "#include <kytea/string-util.h>"
  ),
  plugins = "cpp11"
)


SET_INPUT_STRING <- c("今日もしないとね")
> kytea_result <- executeKytea(str = SET_INPUT_STRING) %>% 
+   print
$surface
[1] "今日" "も"   "し"   "な"   "い"   "と"   "ね"  

$feature
$feature[[1]]
$feature[[1]][[1]]
 ローマ字文      代名詞        名詞 
 0.00000000 -0.01478629  3.46305162 

$feature[[1]][[2]]
  きょう こんにち 
1.124308 0.000000 


$feature[[2]]
$feature[[2]][[1]]
ローマ字文       助詞 言いよどみ 
 0.0000000  2.9044017 -0.4293123 

$feature[[2]][[2]]100 


$feature[[3]]
$feature[[3]][[1]]
ローマ字文     代名詞       動詞 
 0.0000000 -0.6963154  2.5347444 

$feature[[3]][[2]]
       し      たし 
0.9999615 0.0000000 


$feature[[4]]
$feature[[4]][[1]]
ローマ字文     助動詞     形容詞 
  0.000000   2.311590  -0.171657 

$feature[[4]][[2]]
       な      らな 
0.9999511 0.0000000 


$feature[[5]]
$feature[[5]][[1]]
ローマ字文       動詞       語尾 
 0.0000000 -0.4927065  2.8994729 

$feature[[5]][[2]]100 


$feature[[6]]
$feature[[6]][[1]]
ローマ字文       助詞     形状詞 
 0.0000000  4.0511042 -0.3718668 

$feature[[6]][[2]]100 


$feature[[7]]
$feature[[7]][[1]]
ローマ字文       助詞       空白 
  0.000000   2.512480  -0.354871 

$feature[[7]][[2]]100 


# スコアが高いタグに限定
> dplyr::bind_cols(
  dplyr::data_frame(surface = kytea_result$surface),
  dplyr::bind_rows(
    lapply(
      X = kytea_result$feature, 
      FUN = function (features) {
        return(
          dplyr::data_frame(
            pos = names(x = which.max(features[[1]])),
            org = names(x = which.max(features[[2]]))
          )
        )
      }
    )
  )
)
Source: local data frame [7 x 3]

  surface    pos    org
1    今日   名詞 きょう
2      も   助詞     も
3      し   動詞     し
4      な 助動詞     な
5      い   語尾     い
6      と   助詞     と
7      ね   助詞     ね

RからKuromojiを使う

library(rJava)

# jarファイルをあらかじめ用意しておく
SET_KUROMOJI <- list(
  CLASS_JAR_PATH = stringr::str_c(getwd(), "/resource/kuromoji-0.7.7.jar")
)
SET_INPUT_STRING <- c("関西国際空港から出発した")

executeKuromoji <- function (str, set_mode = NULL, jar_path) {
  if (is.null(str) || str == "") {
    return (NULL)
  }
  
  rJava::.jinit(classpath = "", force.init = FALSE)
  rJava::.jaddClassPath(path = jar_path)

  mode <- rJava::J(class = "org.atilika.kuromoji.Tokenizer$Mode")
  builder <- rJava::J(class = "org.atilika.kuromoji.Tokenizer", method = "builder")
  if (!is.null(set_mode)) {
    if (set_mode == "SEARCH") {
      builder <- builder$mode(mode$SEARCH)
    } else if (set_mode == "EXTENDED") {
      builder <- builder$mode(mode$EXTENDED)      
    } else {
      set_mode <- "NORMAL"
    }
  } else {
    set_mode <- "NORMAL"
  }
  
  tokenizer <- builder$build()
  tokened <- tokenizer$tokenize(str)
    
  return (
    dplyr::bind_rows(
      lapply(X = as.list(tokened), FUN = function (token) {
        return(
          dplyr::data_frame(
            surface = token$getSurfaceForm(), feature = token$getAllFeatures(),
            is_know = token$isKnown(), is_unk = token$isUnknown(), is_user = token$isUser(),
            mode = set_mode
          )
        )
      })
    )
  )
}


# モードを変えて実行する
# NORMAL
> executeKuromoji(
+   str = SET_INPUT_STRING, 
+   set_mode = NULL,
+   jar_path = SET_KUROMOJI$CLASS_JAR_PATH
+ )
Source: local data frame [5 x 6]

       surface                                                                                 feature is_know is_unk is_user   mode
1 関西国際空港 名詞,固有名詞,組織,*,*,*,関西国際空港,カンサイコクサイクウコウ,カンサイコクサイクーコー    TRUE  FALSE   FALSE NORMAL
2         から                                                   助詞,格助詞,一般,*,*,*,から,カラ,カラ    TRUE  FALSE   FALSE NORMAL
3         出発                                        名詞,サ変接続,*,*,*,*,出発,シュッパツ,シュッパツ    TRUE  FALSE   FALSE NORMAL
4           し                                              動詞,自立,*,*,サ変・スル,連用形,する,,TRUE  FALSE   FALSE NORMAL
5           た                                                   助動詞,*,*,*,特殊・タ,基本形,,,TRUE  FALSE   FALSE NORMAL

# SEARCH
> executeKuromoji(
+   str = SET_INPUT_STRING, 
+   set_mode = "SEARCH",
+   jar_path = SET_KUROMOJI$CLASS_JAR_PATH
+ )
Source: local data frame [7 x 6]

  surface                                            feature is_know is_unk is_user   mode
1    関西 名詞,固有名詞,地域,一般,*,*,関西,カンサイ,カンサイ    TRUE  FALSE   FALSE SEARCH
2    国際           名詞,一般,*,*,*,*,国際,コクサイ,コクサイ    TRUE  FALSE   FALSE SEARCH
3    空港           名詞,一般,*,*,*,*,空港,クウコウ,クーコー    TRUE  FALSE   FALSE SEARCH
4    から              助詞,格助詞,一般,*,*,*,から,カラ,カラ    TRUE  FALSE   FALSE SEARCH
5    出発   名詞,サ変接続,*,*,*,*,出発,シュッパツ,シュッパツ    TRUE  FALSE   FALSE SEARCH
6      し         動詞,自立,*,*,サ変・スル,連用形,する,,TRUE  FALSE   FALSE SEARCH
7      た              助動詞,*,*,*,特殊・タ,基本形,,,TRUE  FALSE   FALSE SEARCH

# EXTENDED
> executeKuromoji(
+   str = SET_INPUT_STRING, 
+   set_mode = "EXTENDED",
+   jar_path = SET_KUROMOJI$CLASS_JAR_PATH
+ )
Source: local data frame [7 x 6]

  surface                                            feature is_know is_unk is_user     mode
1    関西 名詞,固有名詞,地域,一般,*,*,関西,カンサイ,カンサイ    TRUE  FALSE   FALSE EXTENDED
2    国際           名詞,一般,*,*,*,*,国際,コクサイ,コクサイ    TRUE  FALSE   FALSE EXTENDED
3    空港           名詞,一般,*,*,*,*,空港,クウコウ,クーコー    TRUE  FALSE   FALSE EXTENDED
4    から              助詞,格助詞,一般,*,*,*,から,カラ,カラ    TRUE  FALSE   FALSE EXTENDED
5    出発   名詞,サ変接続,*,*,*,*,出発,シュッパツ,シュッパツ    TRUE  FALSE   FALSE EXTENDED
6      し         動詞,自立,*,*,サ変・スル,連用形,する,,TRUE  FALSE   FALSE EXTENDED
7      た              助動詞,*,*,*,特殊・タ,基本形,,,TRUE  FALSE   FALSE EXTENDED

{rTinySegmenter}の紹介

 TinySegmenterはJavaScriptだけで書かれたコンパクトな「分かち書きツール(品詞推定はない)。これをRで実装したのが{rTinySegmenter}です。

 yamano357/rTinySegmenter · GitHub

library(dplyr)
library(rTinySegmenter)

# Original Model 
segmentr <- tiny_segmenter$new(text = "私の名前は中野です")
> segmentr$tokenize()
[1] "私 | の | 名前 | は | 中野 | です"

> names(x = segmentr$model$TEMPLATE)
 [1] "BC1" "BC2" "BC3" "BP1" "BP2" "BQ1" "BQ2" "BQ3" "BQ4" "BW1" "BW2" "BW3" "TC1" "TC2" "TC3" "TC4" "TQ1" "TQ2" "TQ3" "TQ4" "TW1" "TW2" "TW3"
[24] "TW4" "UC1" "UC2" "UC3" "UC4" "UC5" "UC6" "UP1" "UP2" "UP3" "UQ1" "UQ2" "UQ3" "UW1" "UW2" "UW3" "UW4" "UW5" "UW6"

> segmentr$model$TEMPLATE[[names(x = segmentr$model$TEMPLATE)[1]]]
$PATTERN
$PATTERN$P
[1] ""

$PATTERN$W
[1] ""

$PATTERN$C
[1] 2 3


$SCORE
$SCORE$HH
[1] 6

$SCORE$II
[1] 2461

$SCORE$KH
[1] 406

$SCORE$OH
[1] -1378


# feature
> segmentr$model_attr$unit %>% 
+   as.data.frame()
  BC1 BC2 BC3 BP1 BP2 BQ1 BQ2 BQ3 BQ4  BW1  BW2  BW3 TC1 TC2 TC3 TC4  TQ1  TQ2  TQ3
1  OH  HI  IH  UU  UU UOH UHI UOH UHI B1私 私の の名 OOH OHI HIH IHH UOOH UOHI UOOH
2  HI  IH  HH  UU  UB UHI UIH BHI BIH 私の の名 名前 OHI HIH IHH HHI UOHI UHIH BOHI
3  IH  HH  HI  UB  BB BIH BHH BIH BHH の名 名前 前は HIH IHH HHI HIH BHIH BIHH BHIH
4  HH  HI  IH  BB  BO BHH BHI OHH OHI 名前 前は は中 IHH HHI HIH IHH BIHH BHHI OIHH
5  HI  IH  HH  BO  OB OHI OIH BHI BIH 前は は中 中野 HHI HIH IHH HHI OHHI OHIH BHHI
6  IH  HH  HI  OB  BB BIH BHH BIH BHH は中 中野 野で HIH IHH HHI HII BHIH BIHH BHIH
7  HH  HI  II  BB  BO BHH BHI OHH OHI 中野 野で です IHH HHI HII IIO BIHH BHHI OIHH
8  HI  II  IO  BO  OB OHI OII BHI BII 野で です すE1 HHI HII IIO IOO OHHI OHII BHHI
   TQ4    TW1    TW2    TW3    TW4 UC1 UC2 UC3 UC4 UC5 UC6 UP1 UP2 UP3 UQ1 UQ2 UQ3
1 UOHI B2B1私 B1私の 私の名 の名前   O   O   H   I   H   H   U   U   U  UO  UO  UH
2 BHIH B1私の 私の名 の名前 名前は   O   H   I   H   H   I   U   U   B  UO  UH  BI
3 BIHH 私の名 の名前 名前は 前は中   H   I   H   H   I   H   U   B   B  UH  BI  BH
4 OHHI の名前 名前は 前は中 は中野   I   H   H   I   H   H   B   B   O  BI  BH  OH
5 BHIH 名前は 前は中 は中野 中野で   H   H   I   H   H   I   B   O   B  BH  OH  BI
6 BIHH 前は中 は中野 中野で 野です   H   I   H   H   I   I   O   B   B  OH  BI  BH
7 OHHI は中野 中野で 野です ですE1   I   H   H   I   I   O   B   B   O  BI  BH  OH
8 BHII 中野で 野です ですE1 すE1E2   H   H   I   I   O   O   B   O   B  BH  OH  BI
  UW1 UW2 UW3 UW4 UW5 UW6
1  B2  B1  私  の  名  前
2  B1  私  の  名  前  は
3  私  の  名  前  は  中
4  の  名  前  は  中  野
5  名  前  は  中  野  で
6  前  は  中  野  で  す
7  は  中  野  で  す  E1
8  中  野  で  す  E1  E2

# feature valus
> segmentr$model_attr$score %>% 
+   as.data.frame()
    BC1   BC2  BC3 BP1 BP2  BQ1   BQ2  BQ3   BQ4 BW1   BW2  BW3 TC1   TC2   TC3
1 -1378     0 -301   0   0    0 -1146    0     0   0     0    0   0     0     0
2     0 -1184  996   0   0    0     0 2664  3761   0     0    0   0     0   128
3     0 -4070  626 352   0    0   118    0 -3895   0     0    0   0     0  -341
4     6     0 -301 295  60 1150 -1159 2174     0   0     0    0   0     0     0
5     0 -1184  996   0   0  451   153 2664  3761   0     0    0   0     0   128
6     0 -4070  626 304   0    0   118    0 -3895   0     0    0   0     0  -341
7     6     0    0 295  60 1150 -1159 2174     0   0     0 1437   0     0 -1088
8     0 -1332    0   0   0  451     0 2664 -4654   0 -4761    0   0 -1023     0
   TC4  TQ1   TQ2 TQ3  TQ4 TW1 TW2 TW3 TW4  UC1  UC2  UC3   UC4   UC5  UC6  UP1 UP2
1  695    0     0   0    0   0   0   0   0 -505  646    0 -1032   313 -506    0   0
2 1344    0     0   0    0   0   0   0   0 -505 1059 2311  1809   313 -253    0   0
3  804 -132 -1401 222    0   0   0   0   0    0  409    0  1809 -1238 -506    0  69
4  695   60     0 623 2446   0   0   0   0    0 1059    0 -1032   313 -506    0  69
5 1344    0     0   0    0   0   0   0   0    0 1059 2311  1809   313 -253    0 935
6  679 -132 -1401 222    0   0   0   0   0    0  409    0  1809 -1238 -253 -214  69
7  656   60     0 623 2446   0   0   0   0    0 1059    0 -1032 -1238 -387    0  69
8   54    0     0   0 -966   0   0   0   0    0 1059 2311 -1032  -831 -387    0 935
  UP3 UQ1 UQ2  UQ3  UW1  UW2  UW3   UW4  UW5  UW6
1   0   0   0    0    0    0 4231  7396    0  302
2 189   0   0 1913    0    0 4056     0    0 -236
3 189   0 113   42    0  130    0  1623 -578  201
4   0 -12 216    0 -185    0 2286  8578 -871    0
5 189  21   0 1913    0    0 4555  2210    0  101
6 189 -95 113   42    0 -409  653 -1100 -850  383
7   0 -12 216    0 -847 -968    0  7410 -852  306
8 189  21   0 1913    0    0 2318  -731    0    0


# Custom Model
small_segmentr <- tiny_segmenter$new(
  text = "私の名前は中野です", 
  model_file = system.file(package = "rTinySegmenter", "extdata", "small-model.json")
)
> small_segmentr$tokenize()
[1] "私 | の | 名前 | は | 中野 | で | す"

> names(x = small_segmentr$model$TEMPLATE)
 [1] "BC1" "BC2" "BP1" "BP2" "BQ1" "BQ2" "BQ3" "BW1" "BW2" "TC1" "TC2" "TC3" "TQ1" "TQ2" "TQ3" "TW1" "TW2" "TW3"
[19] "UC1" "UC2" "UC3" "UP1" "UP2" "UP3" "UQ1" "UQ2" "UQ3" "UW1" "UW2" "UW3"

# feature
> small_segmentr$model_attr$unit %>% 
+   as.data.frame()
  BC1 BC2 BP1 BP2 BQ1 BQ2 BQ3  BW1  BW2 TC1 TC2 TC3  TQ1  TQ2  TQ3    TW1    TW2    TW3 UC1
1  OH  HI  UU  UU UOH UHI UOH B1私 私の OOH OHI HIH UOOH UOHI UOOH B2B1私 B1私の 私の名   O
2  HI  IH  UU  UB UHI UIH BHI 私の の名 OHI HIH IHH UOHI UHIH BOHI B1私の 私の名 の名前   O
3  IH  HH  UB  BB BIH BHH BIH の名 名前 HIH IHH HHI BHIH BIHH BHIH 私の名 の名前 名前は   H
4  HH  HI  BB  BO BHH BHI OHH 名前 前は IHH HHI HIH BIHH BHHI OIHH の名前 名前は 前は中   I
5  HI  IH  BO  OB OHI OIH BHI 前は は中 HHI HIH IHH OHHI OHIH BHHI 名前は 前は中 は中野   H
6  IH  HH  OB  BB BIH BHH BIH は中 中野 HIH IHH HHI BHIH BIHH BHIH 前は中 は中野 中野で   H
7  HH  HI  BB  BO BHH BHI OHH 中野 野で IHH HHI HII BIHH BHHI OIHH は中野 中野で 野です   I
8  HI  II  BO  OB OHI OII BHI 野で です HHI HII IIO OHHI OHII BHHI 中野で 野です ですE1   H
  UC2 UC3 UP1 UP2 UP3 UQ1 UQ2 UQ3 UW1 UW2 UW3
1   O   H   U   U   U  UO  UO  UH  B2  B1  私
2   H   I   U   U   B  UO  UH  BI  B1  私  の
3   I   H   U   B   B  UH  BI  BH  私  の  名
4   H   H   B   B   O  BI  BH  OH  の  名  前
5   H   I   B   O   B  BH  OH  BI  名  前  は
6   I   H   O   B   B  OH  BI  BH  前  は  中
7   H   H   B   B   O  BI  BH  OH  は  中  野
8   H   I   B   O   B  BH  OH  BI  中  野  で


まとめ

 Japan.R 2015にて発表した資料から、各種言語で実装された形態素解析器をRから呼び出すコードと、TinySegmenterのR実装である{rTinySegmenter}を紹介したときのコードを記載しました。以前に作った日本語言語処理パッケージではMeCabを呼び出すとメモリーアロケーションを引き起こさせてしまっていたので、修正に合わせてKyTeaも追加したいと思います。
 なお、{rTinySegmenter}はJSON形式のファイルとテンプレートに従った命名とパターン作りによってスコア定義で可能ですが、一部バグ(テンプレートが反映できないケースがある)が残っているので修正します。また、処理速度が遅すぎて使い物にならないので、資料に出てきたようなデータ構造を用いるように改良してきます。



参考



その他

 LT資料の近況に記載がありますが、Japan.Rが開催された日が前職最終出社翌日でした。欲しいものリストを公開したところ、 皆さんからお祝いをいただきました。ありがとうございます。
 いただいた書籍については、また後日記事に書かせていただきます。繰り返しになりますが、ありがとうございました。



実行環境

> devtools::session_info()
Session info ----------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.2.2 (2015-08-14)
 system   x86_64, darwin13.4.0        
 ui       RStudio (0.99.486)          
 language (EN)                        
 collate  ja_JP.UTF-8                 
 tz       Asia/Tokyo                  

Packages --------------------------------------------------------------------------------------
 package        * version    date       source                         
 assertthat       0.1        2013-12-06 CRAN (R 3.2.0)                 
 codetools        0.2-14     2015-07-15 CRAN (R 3.2.2)                 
 curl             0.9.3      2015-08-25 CRAN (R 3.2.0)                 
 DBI              0.3.1      2014-09-24 CRAN (R 3.2.0)                 
 devtools         1.8.0      2015-05-09 CRAN (R 3.2.0)                 
 digest           0.6.8      2014-12-31 CRAN (R 3.2.0)                 
 dplyr          * 0.4.2.9002 2015-07-25 Github (hadley/dplyr@75e8303)  
 foreach          1.4.2      2014-04-11 CRAN (R 3.2.0)                 
 git2r            0.10.1     2015-05-07 CRAN (R 3.2.0)                 
 iterators        1.0.7      2014-04-11 CRAN (R 3.2.0)                 
 jsonlite         0.9.16     2015-04-11 CRAN (R 3.2.0)                 
 magrittr         1.5        2014-11-22 CRAN (R 3.2.0)                 
 memoise          0.2.1      2014-04-22 CRAN (R 3.2.0)                 
 R6               2.1.1      2015-08-19 CRAN (R 3.2.0)                 
 Rcpp           * 0.12.0     2015-07-26 Github (RcppCore/Rcpp@6ae91cc) 
 rJava          * 0.9-7      2015-07-25 local                          
 RMeCab         * 0.99991    2015-08-20 local                          
 rstudioapi       0.3.1      2015-04-07 CRAN (R 3.2.0)                 
 rTinySegmenter * 0.1        2015-11-29 local                          
 rversions        1.0.1      2015-06-06 CRAN (R 3.2.0)                 
 stringi          0.5-5      2015-06-29 CRAN (R 3.2.0)                 
 stringr          1.0.0.9000 2015-07-25 Github (hadley/stringr@380c88f)
 tidyr            0.2.0.9000 2015-07-25 Github (hadley/tidyr@0dc87b2)  
 xml2             0.1.1      2015-06-02 CRAN (R 3.2.0)