IshidaMotohiro / RMeCab

Interface to MeCab
29 stars 10 forks source link

RMeCabに複合語処理は実装されていますか? #16

Closed tsunodaissei closed 3 years ago

tsunodaissei commented 3 years ago

以下のページにも”ごんぎつね”を例に説明があるように、 本来、まとまった語が別々の語として認識されてしまう ことを防ぐ”複合語の処理”がKH Coderには実装されていますが、 RMeCabにも同様の機能が実装されていますか? https://www.oreilly.co.jp/pub/9784873118307/appa.html

重ねて質問があります。 KH-Coderには共起関係の強さが格納されたものを出力する機能はありますか? KH-Coderの共起ネットワーク図の描画データを出力としてほしいです。 RMeCabでいうところのcollocate()関数の値が欲しいという感じです。

IshidaMotohiro commented 3 years ago

最初の質問については、とりあえず思いつくのは3つの方法です。

  1. MeCab 用のオリジナル辞書を用意する
  2. RMeCab作成後に、データフレームの行を統合する
  3. Neologdn辞書を導入する

ということになります。

1 の方法については、環境依存なので 「MeCab ユーザー辞書」などで検索頂いて情報を得てください。

対象語が少ない場合は、2つ目の方法で、例えば以下などが考えられます。

library(RMeCab)
txt <- data.frame(S = c("鍛冶屋の新兵衛の家"))
df <- docDF(txt, column = 1, type=1)
df
library(tidyverse)
df <- df %>% mutate(TERM = str_replace_all(TERM,  "鍛冶屋|新兵衛" , "鍛冶屋の新兵衛"))
df
df %>% select(TERM,Row1) %>% group_by(TERM) %>% summarize(Row1 = sum(Row1) )

3の方法でも、ある程度対応できるかと思いますが、現状のMeCabですと Mac あるいは Linux でないと 導入が難しいかもしれません。 https://rmecab.jp/new/

KHコーダは使ったことがないので、わかりません。

tsunodaissei commented 3 years ago

ご返信くださりありがとうございます。 詳細に教えていただき恐縮です。 ありがとうございます。

辞書というものがあったのですか、勉強になります。 辞書を作成については、医学系専門用語があるものだと大変そうな予感がしてます。 バーチャルボックスなどにMeCabをインストールする必要もありそうだなと思いました。 KH Coderの件についてもご回答ありがとうございます。 ちなみに、私の実行環境だと添付頂いたコードでは変化がなかったので若干修正するとうまくいきました。 詳細なコードを書いていただきありがとうございます。

添付頂いたR言語のコードを私の環境で実行すると変化しませんでした。

> library(RMeCab)
> txt <- data.frame(S = c("鍛冶屋の新兵衛の家"))
> df <- docDF(txt, column = 1, type=1)
number of extracted terms = 6
now making a data frame. wait a while!

> df
  TERM   POS1     POS2 Row1
1   の   助詞   連体化    2
2   屋   名詞     接尾    1
3   家   名詞     一般    1
4   新 接頭詞 名詞接続    1
5 鍛冶   名詞 サ変接続    1
6 兵衛   名詞 固有名詞    1
> library(tidyverse)
> df <- df %>% mutate(TERM = str_replace_all(TERM,  "鍛冶屋|新兵衛" , "鍛冶屋の新兵衛"))
> df
  TERM   POS1     POS2 Row1
1   の   助詞   連体化    2
2   屋   名詞     接尾    1
3   家   名詞     一般    1
4   新 接頭詞 名詞接続    1
5 鍛冶   名詞 サ変接続    1
6 兵衛   名詞 固有名詞    1
> df %>% select(TERM,Row1) %>% group_by(TERM) %>% summarize(Row1 = sum(Row1) )
# A tibble: 6 x 2
  TERM   Row1
  <chr> <int>
1 の        2
2 屋        1
3 家        1
4 新        1
5 鍛冶      1
6 兵衛      1

少し修正を加えました。
鍛冶屋が鍛冶と屋に分離しているのを統合するRコード。

> df
  TERM   POS1     POS2 Row1
1   の   助詞   連体化    2
2   屋   名詞     接尾    1
3   家   名詞     一般    1
4   新 接頭詞 名詞接続    1
5 鍛冶   名詞 サ変接続    1
6 兵衛   名詞 固有名詞    1
> df <- df %>% mutate(TERM = str_replace_all(TERM,  "鍛冶|屋" , "鍛冶屋"))   <ーーーー若干修正しました。
> df
    TERM   POS1     POS2 Row1
1     の   助詞   連体化    2
2 鍛冶屋   名詞     接尾    1
3     家   名詞     一般    1
4     新 接頭詞 名詞接続    1
5 鍛冶屋   名詞 サ変接続    1
6   兵衛   名詞 固有名詞    1
> df %>% select(TERM,Row1) %>% group_by(TERM) %>% summarize(Row1 = sum(Row1) )
# A tibble: 5 x 2
  TERM    Row1
  <chr>  <int>
1 の         2
2 家         1
3 新         1
4 鍛冶屋     2   <ーーーーうまく統合されました。
5 兵衛       1

以上です。ご回答くださりありがとうございます。

IshidaMotohiro commented 3 years ago

うっかりしていました。私の環境では、Noelogdをデフォルト之辞書として設定にしていまして、MeCab標準のIPA辞書を使った場合と、解析結果が異なっています。念の為申し添えます。


ishida@:~$ cat .mecabrc 
;
; Configuration file of MeCab
;
; $Id: mecabrc.in,v 1.3 2006/05/29 15:36:08 taku-ku Exp $;
;
; dicdir =  /usr/local/lib/mecab/dic/ipadic
dicdir =  /usr/local/lib/mecab/dic/mecab-ipadic-neologd
; userdic = /home/foo/bar/user.dic

; output-format-type = wakati
; input-buffer-size = 8192

; node-format = %m\n
; bos-format = %S\n
; eos-format = EOS\n
IshidaMotohiro commented 3 years ago

ユーザー辞書について補足しますと、以下はLinuxでの例ですが、例えば私の名前は石田基広ですが、IPA辞書だと(Neologdでもそうですが) 「石田」「基」「広」となってしまいます。これを防ぐには以下のCSVを用意し ishida.csv

基広,-1,-1,1000,名詞,固有名詞,人名,名,*,*,基広,モトヒロ,モトヒロ

このファイルを

/usr/local/libexec/mecab/mecab-dict-index -d /usr/local/lib/mecab/dic/ipadic -u ishida.dic -f utf-8 -t utf-8 ishida.csv

とすると、ishida.dic が生成されるので、これを指定して解析します。Windowsでも(パスの指定は違いますが)、基本的に同じです。ただしcsvはShift-Jisで作成し、上の命令で utf-8 を shift-jis に変えます。( 他人の記事ですが http://blog.livedoor.jp/oyajieng_memo/archives/2908696.html

> library(RMeCab)
> unlist(RMeCabC("石田基広"))
  名詞   名詞 形容詞 
"石田"   "基"   "広" 
> unlist(RMeCabC("石田基広", dic="ishida.dic"))
  名詞   名詞 
"石田" "基広" 
tsunodaissei commented 3 years ago

すごく勉強になります。 一応努力はしてみたのですが、まだ、辞書をうまく作成できません(泣)。

以下のようなことをやってみましたが、文量が多いので、読まれないで大丈夫です。 ご返信ありがとうございます。

以下、やってみたこと。ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

1.MeCabの辞書が入ったディレクトリに新たなCSVファイルを保存する権限がなかったので、以下のサイト(https://ascii.jp/elem/000/001/461/1461932/) を参考にフルコントロールの権限を自分に与えた。 2.すると、C:\Program Files (x86)\MeCab\dic\ipadic のパス内にあるたくさんの辞書らしきCSVファイルがあったので、そこに新たに aaa.csv ファイルを作成した。 3.このaaa.csvファイルをMeCabの辞書に反映させるために、aaa.csvファイルがあるディレクトリ上でコマンドプロンプトを立ち上げ、そこで以下のコードを実行した。(参考:https://qiita.com/myaun/items/9f8fee924fdc3f7ef411) (以下のコードを実行するためには環境変数にMeCabへのPATH C:\Program Files (x86)\MeCab\bin を通す。

cd C:\Program Files (x86)\MeCab\dic\ipadic
mecab-dict-index -f utf-8 -t utf-8 -d "C:\Program Files (x86)\MeCab\dic\ipadic" -u aaa.dic aaa.csv

4.すると、例えば、以下のようなエラーがでた。 C:\Program Files (x86)\MeCab\dic\ipadic>mecab-dict-index -f utf-8 -t utf-8 -d "C:\Program Files (x86)\MeCab\dic\ipadic" -u ishida.dic ishida.csv reading ishida.csv ... contextid.cpp(96) [it != left.end()] cannot find LEFT-ID for 名刺,固有名詞,人名,名,,,*

5.試しに、C:\Program Files (x86)\MeCab\dic\ipadic内にある別の辞書を表すCSVファイルの一行をaaa.csvにコピーして同様に以下のコードを実行するとうまくいった。

PS C:\Program Files (x86)\MeCab\dic\ipadic> mecab-dict-index -f utf-8 -t utf-8 -d "C:\Program Files (x86)\MeCab\dic\ipadic" -u aaa.dic aaa.csv
reading aaa.csv ... 1
emitting double-array: 100% |###########################################|

done!

6.辞書を正確に作るためにもCSVファイルの意味を理解する必要があると感じた。

IshidaMotohiro commented 3 years ago

単純にCSVファイル内で「名詞」を、「名刺」としていませんか?

tsunodaissei commented 3 years ago

名刺はやりそうにはなったけどやってないです(笑)

下記のコードを実行しても、うまくいかず。

cd C:\Program Files (x86)\MeCab\dic\ipadic
mecab-dict-index -f utf-8 -t utf-8 -d "C:\Program Files (x86)\MeCab\dic\ipadic" -u aaa.dic aaa.csv
mecab-dict-index.exe -f shift-jis -t utf8

aaa.csvの中身は以下です。
鍛冶屋 1   1   1000    名詞  固有名詞    人名  名   *   *   かじや カジヤ カジヤ

辞書を残した形でMeCabをアンインストールして、再度インストールをすると インストールの際にaaa.csvが反映された辞書が新たに作られて、以下のようにうまくいきました。 ただし、私の指定した辞書をRMeCabは探せてなく、インストール時に私のCSVを取り込んで作られたデフォルトの辞書を参照してるようです。


> unlist(RMeCabC("鍛冶屋の新兵衛", dic="aaa.dic"))
specified dictionary file not found; result by default dictionary.  <ーーーーエラー
    名詞     助詞   接頭詞     名詞 
"鍛冶屋"     "の"     "新"   "兵
衛"    <ーーーーー 鍛冶 屋 と分離されていたものが辞書によって結合した出力を得た。
IshidaMotohiro commented 3 years ago

dic=引数に、辞書ファイルへのパス(絶対バスのほうが確実)を指定してください。

tsunodaissei commented 3 years ago

絶対パスも一度は試したことはあたのですが、その時はうまくいきませんでした。

unlist(RMeCabC("鍛冶屋の新兵衛", dic="C:\\Program Files (x86)\\MeCab\\dic\\ipadic\\aaa.dic"))