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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Mecab

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

Python

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

自然言語処理

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

Q&A

解決済

1回答

3572閲覧

形態素解析の結果の一部のみを抽出するコードに関してその2

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Mecab

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

Python

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

自然言語処理

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

0グッド

0クリップ

投稿2018/08/07 04:03

編集2018/09/01 01:40

前提・実現したいこと

前回の質問とほとんど同じ内容ですが、一部異なるため、別の質問として質問いたします。
Mecabで形態素解析をしたあと、名詞・形容詞・動詞に該当する単語のみを抽出しようとしています。

具体的には以下のような出力が得たいです。

text = "日本・東京" ['日本', '東京'] text = "ドライ・アムネシア・バラ(切花)" ['ドライ', 'アムネシア', 'バラ', '切花']

発生している問題・エラーメッセージ

textが「日本・東京」の場合、出力が

text = "日本・東京" ['日本', '東京']

となるのですが、textが以下のような場合、

text = "ドライ・アムネシア・バラ(切花)" ['切花']

であったり、何も出力されないという問題が起こっています。

該当のソースコード

Python

1import Mecab 2def extractKeyword(text): 3 tagger = MeCab.Tagger('-Ochasen') 4 tagger.parse('') 5 node = tagger.parseToNode(text) 6 keywords = [] 7 while node: 8 if node.stat != 0: 9 node = node.next 10 continue 11 if node.feature.split(",")[0] == u"名詞": 12 keywords.append(node.surface) 13 elif node.feature.split(",")[0] == u"形容詞": 14 keywords.append(node.surface) 15 elif node.feature.split(",")[0] == u"動詞": 16 keywords.append(node.surface) 17 node = node.next 18 return keywords 19text = "日本・東京" 20extractKeyword(text)

試したこと

MeCabを使った場合は、カタカナが問題なのかと考え、
以下の入力も試しましたが、問題なく出力されたため、
起こっている問題の改善方法の検討がつかずに困っています。

text = "クリスマス・ローズ" ['クリスマス', 'ローズ']

###ご回答いただいたコードを完成させ実行した結果
ご回答いただいたコード

python

1import sys 2import MeCab 3import mojimoji 4 5STOP_POS = { 6 ('名詞', '副詞可能', '*'), 7 ('名詞', '非自立', '副詞可能'), 8 ('名詞', '非自立', '一般'), 9 ('名詞', '接尾', '副詞可能'), 10 ('名詞', '接尾', '助数詞'), 11 ('名詞', '数', '*'), 12} 13 14def han2zen(text): 15 text = mojimoji.han_to_zen(text) 16 return text 17 18def extractKeyword(text): 19 tagger = MeCab.Tagger('-Ochasen') 20 tagger.parse('') 21 node = tagger.parseToNode(han2zen(text)) 22 keywords = [] 23 while node: 24 features = tuple(node.feature.split(",")) 25 if features[0] == u"名詞" and features[:3] not in STOP_POS: 26 keywords.append(node.surface) 27 elif features[0] == u"形容詞" and features[1] == u"自立": 28 keywords.append(node.surface) 29 elif features[0] == u"動詞" and features[1] == u"自立": 30 keywords.append(node.surface) 31 node = node.next 32 return keywords 33 34text = "ドライ・アムネシア・バラ(切り花)" 35extractKeyword(text)

結果

['ドライ・アムネシア・バラ', '切り花']

補足情報(FW/ツールのバージョンなど)

Python3.6

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

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

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

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

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

guest

回答1

0

ベストアンサー

if node.stat != 0:

として、未知語を取り除く処理をいれて、自分でわざわざ取り除いてますよね。


入力が半角なのがまずいので、適当なコード(Web検索で拾ってくればいいでしょう)で全角にしましょう。
ipadicには半角記号が辞書に含まれていないため、名詞扱いになるのです。

shell

1% echo "ドライ・アムネシア・バラ(切花)" | mecab 2ドライ・アムネシア・バラ 名詞,一般,*,*,*,*,* 3( 記号,括弧開,*,*,*,*,(,(,( 4切花 名詞,一般,*,*,*,*,切花,キリバナ,キリバナ 5) 記号,括弧閉,*,*,*,*,),),) 6EOS 7% echo "ドライ・アムネシア・バラ(切花)" | mecab 8ドライ・アムネシア・バラ 名詞,一般,*,*,*,*,* 9( 名詞,サ変接続,*,*,*,*,* 10切花 名詞,一般,*,*,*,*,切花,キリバナ,キリバナ 11) 名詞,サ変接続,*,*,*,*,* 12EOS

その上で、node.statを見ないで、品詞が名詞のものを拾えばいいかと思います。
あと用途によるでしょうが、私ならもうちょっと品詞細目を絞りますね。

Python

1STOP_POS = { 2 ('名詞', '副詞可能', '*'), # これは微妙? 3 ('名詞', '非自立', '副詞可能'), 4 ('名詞', '非自立', '一般'), 5 ('名詞', '接尾', '副詞可能'), 6 ('名詞', '接尾', '助数詞'), 7 ('名詞', '数', '*'), 8} 9 10 11def han2zen(text): 12 # なんかてきとうな全角化関数にしてください 13 return text 14 15 16def extractKeyword(text): 17 tagger = MeCab.Tagger('-Ochasen') 18 tagger.parse('') 19 node = tagger.parseToNode(han2zen(text)) 20 keywords = [] 21 while node: 22 features = tuple(node.feature.split(",")) 23 if features[0] == u"名詞" and features[:3] not in STOP_POS: 24 keywords.append(node.surface) 25 elif features[0] == u"形容詞" and features[1] == u"自立": 26 keywords.append(node.surface) 27 elif features[0] == u"動詞" and features[1] == u"自立": 28 keywords.append(node.surface) 29 node = node.next 30 return keywords

投稿2018/08/07 04:33

編集2018/08/07 07:54
quickquip

総合スコア11038

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

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

退会済みユーザー

退会済みユーザー

2018/08/07 04:40

ご回答いただきましてありがとうございます。 未知語を取り除く処理をしないと、記号まで含まれてしまうので、単語と記号の区別をつけた上で形態素解析を行う方法が知りたいです、
退会済みユーザー

退会済みユーザー

2018/08/07 05:20

追記いただきましてありがとうございます。 品詞細目を絞った方がいい理由とhan2zenの全角化関数が必要な理由についてもう少し詳しく教えていただけますと幸いです。
quickquip

2018/08/07 06:03 編集

後者は書きました。前者は用途によるので特に気にしなくても。品詞細目をコントロールするコードは早いうちに入れる事が多かったという経験からです。必要になるかどうかわからないけど先回りしただけなので。
退会済みユーザー

退会済みユーザー

2018/08/07 12:59

ありがとうございました。
退会済みユーザー

退会済みユーザー

2018/08/31 23:10

回答済みですが、こちらでご回答いただいたコードに関しまして追加でお聞きしたいことがある場合、再度質問した方がよろしいでしょうか。
quickquip

2018/08/31 23:47

関係しているならここでいいんじゃないかと
退会済みユーザー

退会済みユーザー

2018/09/01 01:42

ご回答いただいたコードを完成させ実行した結果に関して質問に追記させていただきました。実行結果より、未知語の排除は無くなっていたのですが、今回の場合、'ドライ・アムネシア・バラ'を1単語ではなくさらに「ドライ、アムネシア、バラ」と分割するためにはどうするべきでしょうか。
quickquip

2018/09/01 02:45

全部繋がっているのは アムネシア が辞書にないせいなので、ユーザ辞書を拡充するのが本筋です。正道は、1.形態素解析の勉強をする 2.mecabの未知語処理について調べる 3.char.def unk.def の設定とスコアをいじる 4.mecabの辞書を再コンパイルする 5.欲しい出力が得られるまで3と4を繰り返す でしょうか。大変なので、工学的/実用的には「未知語らしい語を処理する」ヒューリスティックな処理を書いてしまってもいいでしょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問