質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Mecab

Mecabは、オープンソースの形態素解析エンジンです。 言語、辞書、コーパスに依存しない汎用的な設計を基本方針としています。 Mecabの由来は、開発者の好物である和布蕪(めかぶ)から名づけられました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

自然言語処理

自然言語処理は、日常的に使用される自然言語をコンピューターに処理させる技術やソフトウェアの総称です。

Q&A

解決済

3回答

1848閲覧

(Python)MeCabでUnidicを用いて語種(漢語,和語)などの出現回数を求めたい

退会済みユーザー

退会済みユーザー

総合スコア0

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Mecab

Mecabは、オープンソースの形態素解析エンジンです。 言語、辞書、コーパスに依存しない汎用的な設計を基本方針としています。 Mecabの由来は、開発者の好物である和布蕪(めかぶ)から名づけられました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

自然言語処理

自然言語処理は、日常的に使用される自然言語をコンピューターに処理させる技術やソフトウェアの総称です。

0グッド

0クリップ

投稿2021/10/25 11:50

環境

Mac BidSur Anaconda Jupyter

やりたいこと

MeCabの辞書にUnidicを指定して,文章中の語種をカウントしたい

# 内容
以下のコードで,品詞(動詞,助詞)に関してはカウントできるのですが,語種(漢語,和語)に関して,カウントができません。

parseで確認したところ,各単語に語種が割り当てられていることが確認できました(調べた限りでは語種に関しては自ら追加する必要がありそうでしたが,自分が確認した限りではデフォルトで語種が付与されていたと思います。)。
インデックスを見ると,品詞のインデックスが0なのに対して,語種のインデックスは12であると確認しました。
しかし,node.feature.split(",")に対して12を指定するとlist index out of rangeが出てしまいます。

試したこと

品詞を示すインデックス0から順番にインデックスを試したところ, 以下のようになりました。
0~5:実行はでき,語種以外のものと一致するかどうかを見ているようで和語と漢語のカウントはそれぞれ0となる
6以降:error:list index out of rangeが出る

#コード
unidic_tagg = MeCab.Tagger("-d /usr/local/lib/mecab/dic/unidic-cwj-3.1.0-full")
node = unidic_tagg.parseToNode(text)

total_count = 0
kango_count = 0
wago_count = 0
doushi_count = 0
joshi_count = 0

while node:
total_count = total_count + 1

if node.feature.split(",")[12] == "漢": kango_count = kango_count + 1 elif node.feature.split(",")[12] == "和": wago_count = wago_count + 1 if node.feature.split(",")[0] == "動詞": doushi_count = doushi_count + 1 elif node.feature.split(",")[0] == "助詞": joshi_count = joshi_count + 1 node = node.next

print(total_count)
print(kango_count)
print(wago_count)
print(doushi_count)
print(joshi_count)

質問

どのように指定すれば語種情報が得られるでしょうか?
また,上記のコードに限らず,語種ごとの出現頻度をカウントする良い方法がありましたら,ご教授いただけると幸いです。
質問の不備などのご指摘も含め,よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

この件について詳しいわけではありませんが、簡単にはできないように思います。

MeCabの標準的な辞書はcsvファイルで最低4個のフィールドを持っている必要があります。
MeCab の辞書構造と汎用テキスト変換ツールとしての利用
MeCab辞書について

一方、UniDicは29個のフィールドを持っています。
UniDic 辞書のフィールド

MeCabが解析時の単語データとしてどれだけのフィールドを保持しているかはわかりませんが、メモリ消費を考えると29個のフィールド全てを保持していないのでしょう。
これが正しければ、多少の変更で語種を取得することはできないでしょう。

取得するためには二つの方法があります。

方法1 辞書の全てのフィールドを保持するように MeCabのソースに機能追加をする。難易度は高いです。

方法2 解析結果を得た後に、個々の単語についてUnidicを引きなおして語種を取得する。Unidicもcsvですので、方法1よりはずっと現実的でしょう。

ということで方法2をお勧めします。

投稿2021/10/25 12:56

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/10/25 16:21

ご回答ありがとうございます。 そうだったのですね,,エラーの出るインデックスの範囲から推測するに6つのフィールドのみ保持しているのだと思います。 回答者様のご回答を踏まえて語種を追加している記事を見ると,その記事では語種を取得するための設定がか書かれていることがわかったので,ひとまずその記事を参考にして,無理そうであれば,回答者様の方法2で対処しようと思います。 ご回答のおかげで作業の進みそうです。ありがとうございました!
quickquip

2021/10/26 00:07 編集

さすがにこれは正しくないでしょう。 全フィールド入っている(辞書も配布されている)と思いますよ。 % mecab -d unidic-cwj-3.1.0-full/ メウキハイユは架空の単語です。 メウキハイユ 名詞,普通名詞,一般,,, は 助詞,係助詞,,,,,ハ,は,は,ワ,は,ワ,和,"","","","","","",係助,ハ,ハ,ハ,ハ,"","動詞%F2@0,名詞%F1,形容詞%F2@-1","",8059703733133824,29321 架空 名詞,普通名詞,形状詞可能,,,,カクウ,架空,架空,カクー,架空,カクー,漢,"","","","","","",体,カクウ,カクウ,カクウ,カクウ,"0","C2","",1686109704823296,6134 の 助詞,格助詞,,,,,ノ,の,の,ノ,の,ノ,和,"","","","","","",格助,ノ,ノ,ノ,ノ,"","名詞%F1","",7968444268028416,28989 単語 名詞,普通名詞,一般,,,,タンゴ,単語,単語,タンゴ,単語,タンゴ,漢,"","","","","","",体,タンゴ,タンゴ,タンゴ,タンゴ,"0","C2","",6268874169393664,22806 です 助動詞,,,,助動詞-デス,終止形-一般,デス,です,です,デス,です,デス,和,"","","","","","",助動,デス,デス,デス,デス,"","形容詞%F2@-1,動詞%F2@0,名詞%F2@1","",7051468750332587,25653 。 補助記号,句点,,,,,,。,。,,。,,記号,"","","","","","",補助,,,,,"","","",6880571302400,25 EOS となりますから。
退会済みユーザー

退会済みユーザー

2021/10/26 04:16

dicrcの中身を確認したら,一部のフィールドしか出力されておらず,そこを編集したらうまく表示されました。 保持という部分が正しくなく,出力という表現が正しかったかもしれません。 お手数をおかけしました。
quickquip

2021/10/29 22:21 編集

これ、インストールした辞書が何なのかも含めて、自分で回答を書いてそちらをベストアンサーにした方がいいかと思います > Nashidaさん
退会済みユーザー

退会済みユーザー

2021/10/31 14:42

ご指摘ありがとうございます。 おっしゃる通り,本質的な解決部分は自己解決だったので,自己回答を理解の及ぶ限り書いておきました。
guest

0

ベストアンサー

https://qiita.com/Hiroyuki1993/items/0bcc535b39abdf646828

上の記事を参考に,設定ファイルであるmecabrcを編集して,output_formatを語種を含んだものに指定することで,語種情報を取得できました。

なお,上の記事とは異なり,unidic最新版のデフォルトは(おそらく)全てのフィールドを出力するようになっており,自分の環境では実行時にクラッシュを避けるためのエラーが出てしまったので,unidicを使用する際は,欲しいフィールドを指定しておくことが必要かもしれません。

また,indexのエラーに関してはいただいた回答にある通り,未知語に関してlistの長さが足りていないことが原因だったので,未知語を省けば,無事回りました。

ご回答いただいた皆様,ありがとうございました。

投稿2021/10/31 14:37

編集2021/10/31 14:40
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

未知語(辞書にない語)を考慮していないだけじゃないでしょうか?
辞書にある語は全エントリが入っているけれど、辞書にない語は(前後文脈から)6個分のエントリが推測されているということかと。
単純にsplit(',')したリストの長さを確認すればいいと思いますが。


(追記)

python

1unidic_tagg = MeCab.Tagger("-d /path/to/unidic-cwj-3.1.0-full") 2node = unidic_tagg.parseToNode(text) 3while node: 4 print(node.feature) 5 node = node.next

として実際のデータを目視しましたか?

投稿2021/10/25 16:19

編集2021/10/25 23:16
quickquip

総合スコア11072

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/10/26 04:14

おっしゃる通り,中身を確認した上でやっていたのですが,一部長さが短いものがあるせいでエラーが出ていただけでした,, 無事,実装したいことが実現できました。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問