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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

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

Mecab

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

Q&A

解決済

2回答

1339閲覧

MeCabを用いてJsonファイルの中身の形態素解析

maro

総合スコア13

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

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

Mecab

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

0グッド

0クリップ

投稿2022/10/20 09:33

編集2022/10/21 04:42

前提

json形式のファイルからtextを取り出して,その内容をMeCabを用いて品詞分解を目指しています.
しかし,エラーが出てしまい,その原因がわからないので教えていただけますと幸いです.

実現したいこと

  • json形式の中身を形態素解析

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

Traceback (most recent call last): File "C:\Users\subaru narahashi\graduation_research\mecab_2.py", line 59, in <module> main() File "C:\Users\subaru narahashi\graduation_research\mecab_2.py", line 31, in main m = mecab.parse(data) TypeError: in method 'Tagger_parse', argument 2 of type 'char const *' Additional information: Wrong number or type of arguments for overloaded function 'Tagger_parse'. Possible C/C++ prototypes are: MeCab::Tagger::parse(MeCab::Lattice *) const MeCab::Tagger::parse(char const *)

該当のソースコード

python

1import sys 2import MeCab 3import requests 4import urllib 5import re 6import json 7import pandas as pd 8from collections import Counter 9 10 11 12def main(): 13 # ファイル読み込み 14 new_data = [] 15 m = [] 16 17 with open('pre_replace_kurashiki.json', "r", encoding = 'utf-8') as f: 18 j = json.load(f) 19 20 """ 21 for key in j: 22 i = print(neologdn.normalize(key["text"])) 23 p = print(key["day"]) 24 """ 25 26 27 for key in j: 28 data = {key["text"]} 29 print(data) 30 mecab = MeCab.Tagger() 31 m = mecab.parse(data) 32 node = m.parseToNode(data) 33 34 new_data.append(node) 35 36 print(new_data) 37 38 39 40 41 #print(new_data) 42 43 """ 44 mecab = MeCab.Tagger() 45 mecab.parse(new_data) 46 node = mecab.parseToNode(new_data) 47 48 49 50 m.append(mecab) 51 52 print(m) 53 """ 54 55 #for document in documents: 56 57 58if __name__ == "__main__": 59 main() 60

追加情報1:jsonファイルの中身

[ { "text": "全ての季節で情緒を感じることができる。古きを訪ね新しくを知る旅にもってこい。一人旅にも、家族、カップル、全てのシチュエーションにも満足がいく旅になると思います。", "day": "2021年9月" }, { "text": "何度か行ったことがあるのですが、いつ行っても綺麗な景観です。やっぱり日本の景色は良いですね。落ち着きます。", "day": "2022年10月1日" }, { "text": "建物の雰囲気がとても良かった。食べ歩きができ恋みくじ団子は美味しかった。スヌーピー倉敷限定商品がありました。", "day": "2022年9月" } ]

追加情報2:実施したこと

以下のようにコードを変更しました

import sys import MeCab import requests import urllib import re import json import pandas as pd from collections import Counter def main(): # ファイル読み込み new_data = [] data_1 = [] with open('pre_replace_kurashiki.json', "r", encoding = 'utf-8') as f: j = json.load(f) """ for key in j: i = print(neologdn.normalize(key["text"])) p = print(key["day"]) """ for key in j: data = key["text"] print(data) mecab = MeCab.Tagger() m = mecab.parse(str(data)) node = m.parseToNode(str(data)) new_data.append(node) print(new_data) #print(new_data) """ mecab = MeCab.Tagger() mecab.parse(new_data) node = mecab.parseToNode(new_data) m.append(mecab) print(m) """ #for document in documents: if __name__ == "__main__": main()

追加情報3:変更後のコードに対するエラーメッセージ

Traceback (most recent call last): File "C:\Users\subaru narahashi\graduation_research\mecab_2.py", line 61, in <module> main() File "C:\Users\subaru narahashi\graduation_research\mecab_2.py", line 34, in main node = m.parseToNode(str(data)) AttributeError: 'str' object has no attribute 'parseToNode'

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

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

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

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

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

guest

回答2

0

ベストアンサー

Pythonは誰にでも使えると謳われるとはいえ,何を書いても動くというわけではありません.
おそらく,質問のコードは何かのWebサイトや教科書を参考にして書かれていると思いますが,参考元のコードは概ねドキュメントを読んだ上で書かれたもので,適当に書いて動いた,というものではありません.これから「理屈で解決する.」ということを念頭に話を進めていきます.

さて,このドキュメントが示すコードリファレンスでは,Tagger Classについての記述があります.今回はコード中でMeCab.Tagger()としてこのクラスを使用していることから,これに関するものが使われるということになりますね.

中でも

Return TypeMember Functions
virtual const char *parse(const char *str)
virtual const Node *parseToNode(const char *str)

の記述が今回使いたそうにしているものと一致するように見えます.MeCabはC++で書かれているのでPythonの書式とは異なるものの,parse()parseToNode()もどちらも文字列を意味するchar *strを引数に要求していますね.parse()の戻り値は文字charのポインタchar *parseToNode()の戻り値はノードのポインタNode *であることがわかりました.

返り値は違うものの,いずれも集合型を受け付けておらず,文字列を引数に取らなければならない.というのはここで確認ができました.

追加情報2に対するfix

現状のコードは

Python

1data = key["text"] # JSONデータから文字列を取り出し 2mecab = MeCab.Tagger() # Tagger Classであるmecabを作成 3m = mecab.parse(str(data)) # 文字列str(data)をtagger.parse()して文字列mを作成(先述の通りparseの返り値は文字列である) 4node = m.parseToNode(str(data)) # 文字列mに対してstr.parseToNode()を実行 <- ここでエラー

でしたね.提示いただいたJSONファイルの例でkey["text"]は既に文字列型であることがわかったので,mecab.parse(str(data))の際にstr()は不要であることがわかります.

現状出ているエラーAttributeError: 'str' object has no attribute 'parseToNode'に関して

私としては,これでstr型の引数を与えられているとは思うのですが、、、

と考えられているものの,引数に文字列を与えていることは正しいですが,解決にあたって着眼点が本質的ではありません.

内容はstrオブジェクトには属性parseToNodeは存在しない.というものです(翻訳してそのまんまの意味です).strオブジェクトの属性を確認すると,確かにparseToNodeは存在しないことがわかります.

parseToNodeは,先ほどTagger Classについて述べた通り「Tagger Classの」Member Function(Pythonで言う属性)であったはずです.なのにも関わらず,m = mecab.parse(str(data))で得られた文字列型オブジェクトmに対して,m.parseToNode(str(data))と書かれていますね.これでは動くはずがありません.

ちゃんとTagger Classであるmecabに対してparseToNode()を行いましょう.

具体的には,次のようにコードを書く必要があります.

Python

1for key in j: 2 data = key["text"] 3 mecab = MeCab.Tagger() # Tagger Classであるオブジェクトmecabを作成 4 m = mecab.parse(data) # Tagger Classには文字列を受け付けて文字列を返すtagger.parse()があるので使ってみる(文字列mは今後使われない) 5 node = mecab.parseToNode(data) # Tagger Classには文字列を受け付けてノードを返すtagger.parseToNode()があるので使ってみる 6 while node: # nodeがNoneになるまで 7 word = node.surface # nodeの文字を取り出し 8 pos = node.feature.split(',')[0] # 品詞(part of speech)を取り出し 9 print(f"{word}: {pos}") # 両方とも表示 10 node = node.next # nodeを次のnodeに置き換える

突然出てきたnodeの扱いですが,もちろんこれもmecab_node_t Struct Referenceに記述があり,これに基づいて書かれるコードです.node.wcostとかで単語コストを見れることがわかりますね.

普通はエラーを見て,Pythonが示す意図を察し,実装したいことと比較して,対処を考える必要があります.なので,こういったリファレンスを参照する力も要求されると思います.そうでなくても最低限「mecab parse to node」などと検索して使いたい機能を使ってみている人を探され,真似るべきです.ただ,Webサイトや本で書かれているコードが正しいとも限りません.さらには自分がやりたいことに合致しないコードなんてざらにあります.他人のコードを丸々コピペして動くと思わない方が良いでしょうけれど,少なくともあなたの力になるはずです.

エラーの読解力と,情報収集力に繋がればと思い,長々と書かせていただきました.疑問の解消と今後の成長になれば幸いです.自然言語処理に取り組まれるよりも先にプログラミングの勉強から始められることをお勧めしておきます.1つ前の質問配列操作に関する知識があれば実装可能かと思います.

投稿2022/10/21 05:48

編集2022/10/21 06:50
PondVillege

総合スコア1579

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

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

PondVillege

2022/10/21 10:05

quickquipさんのおっしゃられている > 自分が今使おうと思っているものを実際に使ってみて観察したらよい というのも,私が例示したドキュメントを参照して論理的にコードを書く.という手法に関係しています. 普通のコーディングでは,「ドキュメントを参照して簡単なコードを書いて動作確認を行ったのち,大元のコードに書き加える.」ということをします.さらには「書き加えた後も目的の動作と同じ動作になるかの確認」を取ることも大事です. 私の方では長くなりそうだったので確認を省略しましたが,動作確認のステップは重要です.途中で何が起きているか不明なまま処理を書くのは論理的ではありません.
maro

2022/10/21 11:59

丁寧に回答いただきありがとうございます. 冒頭に振られていたように,これからは理屈を理解するように努めます. コードについては,正直に言うと完璧に理解できたわけではないですが,これから調べながら理解を含めていきます.
guest

0

parseメソッドには集合型ではなくてstr型を引数に与えてください。


(追記)

そもそも、まず初手として、Pythonの対話環境か何かを使って

python

1import MeCab 2 3mecab = MeCab.Tagger() 4s = 'あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。' 5m = mecab.parse(s) 6print(m) 7print('----') 8print(repr(m))

などとしてみて、自分が今使おうと思っているものを実際に使ってみて観察したらよいと思います。

結果例(辞書が違えば結果は変わります。念のため)

plain

1あの 連体詞,*,*,*,*,*,あの,アノ,アノ 2イーハトーヴォ 名詞,一般,*,*,*,*,* 3の 助詞,格助詞,一般,*,*,*,の,ノ,ノ 4すきとおっ 動詞,自立,*,*,五段・ラ行,連用タ接続,すきとおる,スキトオッ,スキトーッ 5た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ 6風 名詞,一般,*,*,*,*,風,カゼ,カゼ 7、 記号,読点,*,*,*,*,、,、,、 8夏 名詞,一般,*,*,*,*,夏,ナツ,ナツ 9で 助詞,格助詞,一般,*,*,*,で,デ,デ 10も 助詞,係助詞,*,*,*,*,も,モ,モ 11底 名詞,一般,*,*,*,*,底,ソコ,ソコ 12に 助詞,格助詞,一般,*,*,*,に,ニ,ニ 13冷た 形容詞,自立,*,*,形容詞・アウオ段,ガル接続,冷たい,ツメタ,ツメタ 14さ 名詞,接尾,特殊,*,*,*,さ,サ,サ 15を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ 16もつ 動詞,自立,*,*,五段・タ行,基本形,もつ,モツ,モツ 17青い 形容詞,自立,*,*,形容詞・アウオ段,基本形,青い,アオイ,アオイ 18そら 感動詞,*,*,*,*,*,そら,ソラ,ソラ 19、 記号,読点,*,*,*,*,、,、,、 20うつくしい 形容詞,自立,*,*,形容詞・イ段,基本形,うつくしい,ウツクシイ,ウツクシイ 21森 名詞,一般,*,*,*,*,森,モリ,モリ 22で 助詞,格助詞,一般,*,*,*,で,デ,デ 23飾ら 動詞,自立,*,*,五段・ラ行,未然形,飾る,カザラ,カザラ 24れ 動詞,接尾,*,*,一段,連用形,れる,レ,レ 25た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ 26モリーオ 名詞,固有名詞,地域,一般,*,*,* 27市 名詞,接尾,地域,*,*,*,市,シ,シ 28、 記号,読点,*,*,*,*,、,、,、 29郊外 名詞,一般,*,*,*,*,郊外,コウガイ,コーガイ 30の 助詞,連体化,*,*,*,*,の,ノ,ノ 31ぎらぎら 副詞,一般,*,*,*,*,ぎらぎら,ギラギラ,ギラギラ 32ひかる 動詞,自立,*,*,五段・ラ行,基本形,ひかる,ヒカル,ヒカル 33草 名詞,一般,*,*,*,*,草,クサ,クサ 34の 助詞,連体化,*,*,*,*,の,ノ,ノ 35波 名詞,一般,*,*,*,*,波,ナミ,ナミ 36。 記号,句点,*,*,*,*,。,。,。 37EOS 38 39---- 40'あの\t連体詞,*,*,*,*,*,あの,アノ,アノ\nイーハトーヴォ\t名詞,一般,*,*,*,*,*\nの\t助詞,格助詞,一般,*,*,*,の,ノ,ノ\nすきとおっ\t動詞,自立,*,*,五段・ラ行,連用タ接続,すきとおる,スキトオッ,スキトーッ\nた\t助動詞,*,*,*,特殊・タ,基本形,た,タ,タ\n風\t名詞,一般,*,*,*,*,風,カゼ,カゼ\n、\t記号,読点,*,*,*,*,、,、,、\n夏\t名詞,一般,*,*,*,*,夏,ナツ,ナツ\nで\t助詞,格助詞,一般,*,*,*,で,デ,デ\nも\t助詞,係助詞,*,*,*,*,も,モ,モ\n底\t名詞,一般,*,*,*,*,底,ソコ,ソコ\nに\t助詞,格助詞,一般,*,*,*,に,ニ,ニ\n冷た\t形容詞,自立,*,*,形容詞・アウオ段,ガル接続,冷たい,ツメタ,ツメタ\nさ\t名詞,接尾,特殊,*,*,*,さ,サ,サ\nを\t助詞,格助詞,一般,*,*,*,を,ヲ,ヲ\nもつ\t動詞,自立,*,*,五段・タ行,基本形,もつ,モツ,モツ\n青い\t形容詞,自立,*,*,形容詞・アウオ段,基本形,青い,アオイ,アオイ\nそら\t感動詞,*,*,*,*,*,そら,ソラ,ソラ\n、\t記号,読点,*,*,*,*,、,、,、\nうつくしい\t形容詞,自立,*,*,形容詞・イ段,基本形,うつくしい,ウツクシイ,ウツクシイ\n森\t名詞,一般,*,*,*,*,森,モリ,モリ\nで\t助詞,格助詞,一般,*,*,*,で,デ,デ\n飾ら\t動詞,自立,*,*,五段・ラ行,未然形,飾る,カザラ,カザラ\nれ\t動詞,接尾,*,*,一段,連用形,れる,レ,レ\nた\t助動詞,*,*,*,特殊・タ,基本形,た,タ,タ\nモリーオ\t名詞,固有名詞,地域,一般,*,*,*\n市\t名詞,接尾,地域,*,*,*,市,シ,シ\n、\t記号,読点,*,*,*,*,、,、,、\n郊外\t名詞,一般,*,*,*,*,郊外,コウガイ,コーガイ\nの\t助詞,連体化,*,*,*,*,の,ノ,ノ\nぎらぎら\t副詞,一般,*,*,*,*,ぎらぎら,ギラギラ,ギラギラ\nひかる\t動詞,自立,*,*,五段・ラ行,基本形,ひかる,ヒカル,ヒカル\n草\t名詞,一般,*,*,*,*,草,クサ,クサ\nの\t助詞,連体化,*,*,*,*,の,ノ,ノ\n波\t名詞,一般,*,*,*,*,波,ナミ,ナミ\n。\t記号,句点,*,*,*,*,。,。,。\nEOS\n'

自分が使おうとしているものがどういう振る舞いをするかを観察しないで、コードに放り込むのが無理があると思います。


個人的には、parseToNodeではなくてparseを使って得た文字列情報を相手にする方がよいと思っています。
末尾改行を取り除いてから改行で分割して、

python

1lines = mecab.parse(s).strip('\n).split('\n')

とすると

plain

1['あの\t連体詞,*,*,*,*,*,あの,アノ,アノ', 2 'イーハトーヴォ\t名詞,一般,*,*,*,*,*', 3 'の\t助詞,格助詞,一般,*,*,*,の,ノ,ノ', 4 'すきとおっ\t動詞,自立,*,*,五段・ラ行,連用タ接続,すきとおる,スキトオッ,スキトーッ', 5 'た\t助動詞,*,*,*,特殊・タ,基本形,た,タ,タ', 6 '風\t名詞,一般,*,*,*,*,風,カゼ,カゼ', 7 '、\t記号,読点,*,*,*,*,、,、,、', 8 '夏\t名詞,一般,*,*,*,*,夏,ナツ,ナツ', 9 'で\t助詞,格助詞,一般,*,*,*,で,デ,デ', 10 'も\t助詞,係助詞,*,*,*,*,も,モ,モ', 11 '底\t名詞,一般,*,*,*,*,底,ソコ,ソコ', 12 'に\t助詞,格助詞,一般,*,*,*,に,ニ,ニ', 13 '冷た\t形容詞,自立,*,*,形容詞・アウオ段,ガル接続,冷たい,ツメタ,ツメタ', 14 'さ\t名詞,接尾,特殊,*,*,*,さ,サ,サ', 15 'を\t助詞,格助詞,一般,*,*,*,を,ヲ,ヲ', 16 'もつ\t動詞,自立,*,*,五段・タ行,基本形,もつ,モツ,モツ', 17 '青い\t形容詞,自立,*,*,形容詞・アウオ段,基本形,青い,アオイ,アオイ', 18 'そら\t感動詞,*,*,*,*,*,そら,ソラ,ソラ', 19 '、\t記号,読点,*,*,*,*,、,、,、', 20 'うつくしい\t形容詞,自立,*,*,形容詞・イ段,基本形,うつくしい,ウツクシイ,ウツクシイ', 21 '森\t名詞,一般,*,*,*,*,森,モリ,モリ', 22 'で\t助詞,格助詞,一般,*,*,*,で,デ,デ', 23 '飾ら\t動詞,自立,*,*,五段・ラ行,未然形,飾る,カザラ,カザラ', 24 'れ\t動詞,接尾,*,*,一段,連用形,れる,レ,レ', 25 'た\t助動詞,*,*,*,特殊・タ,基本形,た,タ,タ', 26 'モリーオ\t名詞,固有名詞,地域,一般,*,*,*', 27 '市\t名詞,接尾,地域,*,*,*,市,シ,シ', 28 '、\t記号,読点,*,*,*,*,、,、,、', 29 '郊外\t名詞,一般,*,*,*,*,郊外,コウガイ,コーガイ', 30 'の\t助詞,連体化,*,*,*,*,の,ノ,ノ', 31 'ぎらぎら\t副詞,一般,*,*,*,*,ぎらぎら,ギラギラ,ギラギラ', 32 'ひかる\t動詞,自立,*,*,五段・ラ行,基本形,ひかる,ヒカル,ヒカル', 33 '草\t名詞,一般,*,*,*,*,草,クサ,クサ', 34 'の\t助詞,連体化,*,*,*,*,の,ノ,ノ', 35 '波\t名詞,一般,*,*,*,*,波,ナミ,ナミ', 36 '。\t記号,句点,*,*,*,*,。,。,。', 37 'EOS']

というような「文字列のリスト」が手に入ります。
これを相手にした方がよいかと思います。

投稿2022/10/20 09:36

編集2022/10/21 07:48
quickquip

総合スコア11038

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

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

maro

2022/10/20 14:09

コメントありがとうございます。 つまり、str(data)にすればよいということでしょうか。
PondVillege

2022/10/20 14:22

data = {key["text"]} と書いたときの{}のせいで集合型になっている.ので,これではダメである.という話です. この状態から文字列変換str(data)を行うと,集合型を示す{ }が文字列に付加され,これごと解析対象になります.ので,違います. 解答者側からはkey["text"]の中身が不明ですし,{}を付けることで重複排除できることから,一概に「{}を外せばよい.」とは言えないのです. mecab.parse()にはあなた自身であなた自身が解析したい文字列を与えてください.としか言いようがありません.
quickquip

2022/10/20 15:23 編集

完全に同意です。ファイルの中身が開示されない限り、付け加えることは特にありません。
maro

2022/10/21 02:18

ご指摘ありがとうございます. jsonファイルの中身の一部を公開しました.ご確認ください. 解答していただければ幸いです.
quickquip

2022/10/21 02:27 編集

質問の > エラーが出てしまい,その原因がわからないので教えていただけますと幸いです に対しては答えたつもりです。 どこがおかしいかも ps_aux_grep さんか書いてくれました。 自分で試すのは嫌で全部やって欲しいということですか?なにかをやってみて困ったこと、分からないことがあるなら質問に追記してください。
quickquip

2022/10/21 03:24 編集

ファイルの中身が開示されない限り、付け加えることは特にありません は ファイルの中身が開示されたら、付け加えます と等価ではないです。 ps_aux_grep さんの補足でもう十分ですねという意図です。 どこにわからないポイントがありますか? > data = {key["text"]} > と書いたときの{}のせいで集合型になっている.ので,これではダメである. は通じてますか?
maro

2022/10/21 04:50

返信が遅くなってしまい申し訳ありません. このエラーで止まってので,回答者様に全投げするような質問内容となっていました.申し訳ありません. str型を引数に与えるという点はわかりました. また,{}があるせいで,str型にしても{}まで文字列として認識されてしまい,そこも解析されるという理解です. そこで,実施したこととして,追加情報2のようにコードを変えました.しかし,追加情報3のエラーが発生してしまい止まっている状況です. 私としては,これでstr型の引数を与えられているとは思うのですが、、、 当方,python初心者ですので,検討違いのことをしているようでしたら申し訳ありません.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問