RMeCab_Tips の変更点 - RとLinuxと...

RとLinuxと...


RMeCab_Tips の変更点


#contents


* [[RMeCab]] の出力に [[topicmodels:http://cran.md.tsukuba.ac.jp/web/packages/topicmodels/index.html]] の  LDA を適用 [#u97160a7]

 > test <- docMatrix2( "data/morikita")
 library (RMeCab)
 
 > install.packages("slam")
 > library(slam)
 > test.sparse <-  as.simple_triplet_matrix( t(test) )
 test <- docMatrix2( "morikita") # フォルダを指定
 
 > install.packages("topicmodels")
 > library(topicmodels)
 install.packages("slam")
 
 library(slam)
 test.sparse <-  as.simple_triplet_matrix( t(test) ) #スパースな行列に変換
 
 library (tm) # この2行で重みを設定
 test.sparse2 <-  as.DocumentTermMatrix ( test.sparse, weighting = weightTf ) #
 
  ## sudo apt-get install libgsl0-dev # Ubuntuの場合,これが必要
 install.packages("topicmodels")
 
 library(topicmodels)
 # # class(test.sparsea) <- "DocumentTermMatrix" # 不要
 topic.mod <- LDA(test.sparse2, control = list(alpha = 0.1), k = 5)

 > class(test.sparse) <- "DocumentTermMatrix"
 > topic.mod <- LDA(test.sparse, control = list(alpha = 0.1), k = 5)


LDA関数はinputのクラスが,sparse な行列であり,
かつ tm パッケージ独自の DocumentTermMatrix クラスで
あることを前提にしてます.
そこで RMeCab の出力を as.simple_triplet_matrix 関数で
sparse な triplet_matrix に変え,そのクラス属性を
 "DocumentTermMatrix"
に変更すると, LDA 関数への input になると思われます.


* 語彙の統合 [#rfc958e8]

「Rによるテキストマイニング入門」には
記載されていませんが,&color(red){&size(18){docDF()};};という関数があります. &ref(SoftArchive/manual100831.pdf); に少し記載があります.

 > res <- docDF("doc", type=1, N=1)
 file_name =  doc/doc1.txt opened
 file_name =  doc/doc2.txt opened
 file_name =  doc/doc3.txt opened
 number of extracted terms = 18
 now making a data frame. wait a while!
 
 > res
     TERM   POS1      POS2     doc1.txt doc2.txt doc3.txt
 1      。      記号         句点           1        1        1
 2    いる     動詞         非自立        0        0        1
 3      だ      助動詞            *          1        0        0
 4      で      助詞         接続助詞      0        0        1
 5    です     助動詞            *           1        1        0
 ...

デフォルトでは全品詞を抽出しますが,品詞情報から選り分けて
"*","格助詞", "係助詞", "句点","非自立") を省く場合は %in% 演算子
を使って以下のようにします.

 > res2 <- res[ !(res$POS2 %in% c("*","格助詞", "係助詞", "句 点","非自立")), ]

 > res2
     TERM   POS1      POS2    doc1.txt doc2.txt doc3.txt
 4      で     助詞     接続助詞        0        0        1
 10   学ぶ   動詞         自立           0        0        1
 11   学生   名詞         一般          1        1        0
 12   彼女   名詞       代名詞          0        1        1
 ...

あるいは名詞は抽出するが,ただし細分類が"*","数詞", "接尾", "代名詞"を
除く場合は

 > res4 <- res[ res$POS1 %in% c("名詞","形容詞") & !(res$POS2 %in%  
 c("*","数詞", "接尾", "代名詞")), ]

 > res4
     TERM   POS1         POS2      doc1.txt doc2.txt doc3.txt
 11   学生   名詞         一般              1        1        0
 13   数学   名詞         一般               0        1        1
 14 真面目   名詞     形容動詞語幹    1        0        0
 16     科     名詞         接尾             0        1        0
 17   良い   形容詞       自立            0        1        0
 18 難しい  形容詞       自立            0        0        1 


ただし,これはデータフレームですので,操作する
場合には行列に変える必要があるかもしれません

 > res3 <- as.matrix(res2[, -(1:3)])
 > rownames(res3) <- res2[,1]
 > res3
       doc1.txt doc2.txt doc3.txt
 で            0        0        1
 学ぶ          0        0        1
 学生          1        1        0
 彼女          0        1        1
 数学          0        1        1
 ...

* 日本語の stopwords [#gfd88518]

MeCabの品詞情報が以下
にあります. MeCabの品詞情報は IPA 素性辞書に
そっています

http://chasen.aist-nara.ac.jp/snapshot/ipadic/ipadic/doc/ipadic-ja.pdf

IPA辞書については以下に解説があります.

http://parame.mwj.jp/blog/0209

特に以下のページの下にある ChaSen 品詞体系 (IPA品詞体系)

http://www.unixuser.org/~euske/doc/postag/index.html

に,MeCab の標準辞書は準拠しています.
ここを参考に docDF() の出力から,POS1 列と  POS2 列の内容を
%in% 演算子で選り分けて,独自にstopwordを
定義されるがのベストではないかと思います.

私自身は独自にstopword を用意していません.日本語テキスト
マイニングに関わる仲間たちも,テキストごと,あるいジャンル
ごとに stopwordsを定義しているのが現状のようです.

IPA品詞体系 から判断するに,たとえば ,&color(red){&size(18){docDF()};}; 出力の POS1 が名詞
や動詞,形容詞でも,POS2 が 「接尾」,「非自立」などのタームは,
内容語というよりは機能語に近いので,削除対象になると思います.


* 言葉の「正規化」 [#taa22ba7]

表記の統一については,有料ソフトでは,ある程度
自動的にこれを行なってくれる場合があるようですが
(ただし完全ではありません),いずれにせよ
最後は分析者自身による確認が必要です.

これは残念ながら手作業しかありません.あとは
この作業をできるだけ効率的に行なうだけです.

手作業で行なう場合,以下の二つが考えらえるでしょうか.

- 1) ひらがな,あるいはカタカナで始まる単語は,漢字に
統一できる可能性がある(いぬ,イヌ -> 犬)
そこで,データから,ひらがな,あるいはカタカナで始まる単語
を探してチェックする.

 > res <- docDF("data/doc", pos = c("名詞","形容詞","動詞"), type = 1)

 # 以下とりあえず力技でカタカナとひらがなを用意してしまいます

 > kana <- c("\\<あ|\\<ア|\\<か|\\<カ|\\<さ|\\<サ|\\<た|\\<タ|
 \\<な|\\<ナ|\\<は|\\<ハ|\\<ま|\\<マ|\\<や|\\<ヤ|\\<ら|\\<ラ|
 \\<わ|\\<ワ|\\<ん|\\<ン|\\<が|\\<ガ|\\<ざ|\\<ザ|\\<だ|\\<ダ|
 \\<ば|\\<バ|\\<ぱ|\\<パ|\\<ゃ|\\<い|\\<イ|\\<き|\\<キ|\\<し|
 \\<シ|\\<ち|\\<チ|\\<に|\\<ニ|\\<ひ|\\<ヒ|\\<み|\\<ミ|\\<り|
 \\<リ|\\<ゐ|\\<ヰ|\\<ぎ|\\<ギ|\\<じ|\\<ジ|\\<ぢ|\\<ヂ|\\<び|
 \\<ビ|\\<ぴ|\\<ピ|\\<ゅ|\\<ュ|\\<う|\\<ウ|\\<く|\\<ク|\\<す|
 \\<ス|\\<つ|\\<ツ|\\<ぬ|\\<ヌ|\\<ふ|\\<フ|\\<む|\\<ム|\\<ゆ|
 \\<ユ|\\<る|\\<ル|\\<ぐ|\\<グ|\\<ず|\\<ズ|\\<づ|\\<ヅ|\\<ぶ|
 \\<ブ|\\<ぷ|\\<プ|\\<ょ|\\<ョ|\\<え|\\<エ|\\<け|\\<ケ|\\<せ|
 \\<セ|\\<て|\\<テ|\\<ね|\\<ネ|\\<へ|\\<ヘ|\\<め|\\<メ|\\<れ|
 \\<レ|\\<ゑ|\\<ヱ|\\<げ|\\<ゲ|\\<ぜ|\\<ゼ|\\<で|\\<デ|\\<べ|
 \\<ベ|\\<ぺ|\\<ペ|\\<っ|\\<ッ|\\<お|\\<オ|\\<こ|\\<コ|\\<そ|
 \\<ソ|\\<と|\\<ト|\\<の|\\<ノ|\\<ほ|\\<ホ|\\<も|\\<モ|\\<よ|
 \\<ヨ|\\<ろ|\\<ロ|\\<を|\\<ヲ|\\<ご|\\<ゴ|\\<ぞ|\\<ゾ|\\<ど|
 \\<ド|\\<ぼ|\\<ボ|\\<ぽ|\\<ポ")
 
 > res$TERM[grep(kana, res$TERM)]

この出力が,それほど多くなければ,手作業で表記のずれを
統一していけるのではないでしょうか.

アルファベットや数字を含む単語なら

 > res$TERM[grep("[[:alnum:]]", res$TERM, perl = T)]

でしょうか.

- 2) 同義語を統一する

まず同義語のリストがあるとすれば,たとえば  docDF() の
出力は以下のように整理できます.

 > res <- docDF("data/doc", pos = c("名詞","形容詞","動詞"), type = 1)
 res
     TERM   POS1         POS2 doc1.txt doc2.txt doc3.txt
 1    いる   動詞       非自立        0        0        1
 2    学ぶ   動詞         自立        0        0        1
 3    学生   名詞         一般        1        1        0
 4    彼女   名詞       代名詞        0        1        1
 5    数学   名詞         一般        0        1        1
 6  真面目   名詞 形容動詞語幹        1        0        0
 7      私   名詞       代名詞        1        0        0
 8      科   名詞         接尾        0        1        0
 9    良い 形容詞         自立        0        1        0
 10 難しい 形容詞         自立        0        0        1

 > wordlist <- list(c("*", "動詞と形容詞の", "自立", "良い", 
  "難しい", "学ぶ" ),
 c("**", "名詞", "代名詞", "彼女","私") )

#  "良い", "難しい", "学ぶ"  を ”*”  "動詞と形容詞の", "自立"にまとめてしまう
# "彼女","私" を "**" 名詞", "代名詞", にまとめてしまう

 > res2 <- res
 > dummy <- res[1,]
 > dummy[,1:3] <- ""
 > dummy[,4:ncol(dummy)] <- 0
 
 > for(i in 1:length(wordlist)){
   idx0 <- any( res2$TERM %in% wordlist[[i]][1])
   if(!idx0){
     dummy[, 1:3] <- wordlist[[i]][1:3]
     res2 <- rbind(res2, dummy)
   }
   idx <- which(res2$TERM %in% wordlist[[i]][-(1:3)]  )
   if(length (idx) > 0){
     res2[res2$TERM == wordlist[[i]][1]  ,4:ncol(dummy)] 
       <- colSums(res2[idx, 4:ncol(dummy)])
     res2 <- res2[-idx,]
   }
  }
 
 > res2
     TERM           POS1         POS2 doc1.txt doc2.txt doc3.txt
 1    いる           動詞       非自立        0        0         1
 3    学生           名詞         一般        1        1        0
 5    数学           名詞         一般        0        1        1
 6  真面目           名詞 形容動詞語幹        1        0        0
 8      科           名詞         接尾        0        1        0
 11      * 動詞と形容詞の         自立        0        1        2
 12     **           名詞       代名詞        1        1        1


問題は同義語リストをどうやって作るかですが,次のような
データベースがあります.

http://nlpwww.nict.go.jp/wn-ja/

SQLite3 データベースが使えることが前提となりますが
以下のようにすると,同義語のリストを作成できます.

 ## install.packages("DBI")
 ## install.packages("RSQLite")
  > library(RSQLite)
  > drv <- dbDriver("SQLite")
  > con <- dbConnect(drv, dbname="wnjpn.db")
  > test.table <- dbGetQuery(con, ".tables")

 > test.table1 <- dbGetQuery(con,  "select DISTINCT lemma from  word
 where wordid in (select wordid from sense where synset in
  (  select synset from sense where wordid in (select wordid
   from word where lemma=\"犬\")))")
 
 > test.table2 <- dbGetQuery(con,  "select DISTINCT lemma from word
 where wordid in (select wordid from sense where synset in
 (  select synset from sense where wordid in (select wordid
   from word where lemma=\"日本\")))")
  
# 以上,面倒でしょうから,日本語wordnetから抽出するためのパッケージを用意しています.

 > wordlist <- list( test.table1$lemma , test.table2$lemma)
 
 > wordlist
 [[1]]
    [1] "canis_familiaris" "dog"              "domestic_dog"     "spy" 
  [5] "undercover_agent" "いぬ"             "まわし者"         "イヌ"
 [9] "スパイ"           "ドッグ"           "回し者"           "回者"
 [13] "密偵"             "工作員"           "廻し者"           "廻者"
 [17] "探"               "探り"             "洋犬"             "犬"
 [21] "秘密捜査員"       "諜報員"           "諜者"             "間者"
 [25] "間諜"             "隠密"             "飼い犬"           "飼犬"
 
 [[2]]
 [1] "japan"  "nihon"  "nippon" "日本"



ただ完全ではありません.上の出力にあるように,”日本”を
検索しても,にほん、にっぽん、ニッポン、ニッポンは出て
きませんので,手作業で加えるしかありません.


とりあえず,ひらがな,あるいはカタカナ,アルファベットで表記
された単語を調べ,統一することから始めてはどうでしょうか.