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

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

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

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

Q&A

解決済

CaboChaっで係り受け解析.結果をファイルに書き込みたいのですが期待通りにできません、、、

maro
maro

総合スコア12

Python

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

1回答

0グッド

0クリップ

179閲覧

投稿2022/11/26 08:56

前提

CaboChaで係り受け解析を行っています.係り受け解析自体は実行できているのですが,それを期待する形でファイルに格納する点で苦戦しています.

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • 係り受け解析を観光地のレビューに対して行い,[名詞,形容詞]もしくは[名詞,動詞]の組み合わせの取得(実現済み)
  • kakariuke1.txtに係り受け解析を行った名詞を書き込み(実現済み)
  • kakariuke2.txtに係り受け解析を行った[名詞,形容詞]もしくは[名詞,動詞]の組み合わせを書き込み(実現済み)
  • kakariuke3.txtに係り受け解析を行った結果を名詞ごとに形容詞もしくは動詞の書き込み.(未実現,以下の例参照)

【例】kakariuke1.txt

駐車場 0分 場所 ロス 町並み ところ たくさん 実感 観光地 朝 一 一番 歴史 船 食事 時間 一日 ・ ・ ・

【例】kakariuke2.txt

[('駐車場', 'かかる'), ('駐車場', '食べる歩くできる'), ('駐車場', '高い'), ('駐車場', 'ある'), ('駐車場', 'ある')] [('0分', 'かかる')] [('場所', 'かかる'), ('場所', '行く'), ('場所', '思う'), ('場所', '行う'), ('場所', '面白い'), ('場所', '触れ合える'), ('場所', 'ある'), ('場所', 'する'), ('場所', '訪れる'), ('場所', '訪れる'), ('場所', '思える'), ('場所', 'ある'), ('場所', '楽しめる'), ('場所', '思う'), ('場所', '思える'), ('場所', '良い'), ('場所', '美味しい'), ('場所', 'ある'), ('場所', '過ごす'), ('場所', '良い'), ('場所', '過ごす')] [('ロス', '落ち着く')] [('町並み', '古い'), ('町並み', '通り抜ける'), ('町並み', '感じる'), ('町並み', '美しい'), ('町並み', '回る切れる'), ('町並み', '走る'), ('町並み', '古い'), ('町並み', 'なる'), ('町並み', 'なる')] [('ところ', 'たどり着く'), ('ところ', '見る'), ('ところ', 'ある'), ('ところ', 'ある'), ('ところ', '回る'), ('ところ', 'ない'), ('ところ', 'ある'), ('ところ', 'ない'), ('ところ', '多い')] [('たくさん', '落ち着く'), ('たくさん', 'ある'), ('たくさん', 'ある'), ('たくさん', 'ある'), ('たくさん', 'ある'), ('たくさん', 'ある'), ('たくさん', 'ある'), ('たくさん', 'ある楽しめる'), ('たくさん', '売る'), ('たくさん', 'ある'), ('たくさん', '多い'), ('たくさん', 'ある'), ('たくさん', '残る'), ('たくさん', 'ある'), ('たくさん', 'ある')] [('実感', '落ち着く'), ('実感', '思う')] [('観光地', '行く'), ('観光地', 'ある'), ('観光地', '遊べる'), ('観光地', '楽しい'), ('観光地', 'なる'), ('観光地', '来る'), ('観光地', '感じる'), ('観光地', '来る'), ('観光地', '多い')] [('朝', '行く'), ('朝', '楽しめる'), ('朝', '貰える')] [('一', '行く')] [('一番', '行く')] [('歴史', '感じる'), ('歴史', 'あふれる'), ('歴史', '感じる')] [('船', '乗る'), ('船', '流れる')] [('食事', '過ぎる'), ('食事', 'する'), ('食事', 'あるつける')] [('時間', '過ぎる'), ('時間', 'かかる'), ('時間', '過ごす'), ('時間', 'ある'), ('時間', '足る'), ('時間', 'かける'), ('時間', '含める'), ('時間', '長い'), ('時間', 'する'), ('時間', '流れる')] [('一日', '回る切れる')] ・ ・ ・

【例】kakariuke3.txt

かかる,食べる歩くできる,高い,ある,ある,ある かかる かかる,行く,思う,行う,面白い,触れ合える,ある・・・ ・ ・ ・ 

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

IndexError: list index out of range

該当のソースコード

python

1import CaboCha 2import codecs 3from collections import OrderedDict 4import neologdn 5import re 6import pickle 7 8def get_word1(tree, chunk): 9 """ 10 chunkからtree内のトークンを得て、そのトークンが持つ名詞の表層形を取得する 11 """ 12 surface = '' 13 beg = chunk.token_pos # このチャンクのツリー内のトークンの位置 14 end = chunk.token_pos + chunk.token_size # トークン列のサイズ 15 16 for i in range(beg, end): 17 token = tree.token(i) 18 features = token.feature.split(',') 19 20 if features[0] == '名詞': 21 surface += token.surface # 表層形の取得 22 #print("名詞 " + surface) 23 else: 24 break 25 26 return surface 27 28 29def get_word2(tree, chunk): 30 """ 31 chunkからtree内のトークンを得て、そのトークンが持つ動詞と形容詞の表層形を取得する 32 """ 33 surface = '' 34 beg = chunk.token_pos # このチャンクのツリー内のトークンの位置 35 end = chunk.token_pos + chunk.token_size # トークン列のサイズ 36 37 for i in range(beg, end): 38 token = tree.token(i) 39 features = token.feature.split(',') 40 41 if features[0] == '動詞': 42 surface += features[6] 43 #print(surface) 44 elif features[0] == '形容詞': 45 surface += features[6] 46 #print("形容詞 " + surface) 47 else: 48 break 49 50 return surface 51 52 53 54def get_2_words_take(file): 55 cp = CaboCha.Parser('-f1') 56 chunk_dic = {} 57 chunk_id = 0 58 tuples_sub = [] 59 tree = cp.parse(file) 60 61 for i in range(0, tree.size()): 62 token = tree.token(i) # トークンを得る 63 if token.chunk: # トークンがチャンクを持っていたら 64 chunk_dic[chunk_id] = token.chunk # チャンクを辞書に追加する 65 chunk_id += 1 66 67 68 69 for chunk_id, chunk in chunk_dic.items(): 70 if chunk.link > 0: 71 from_surface1 = get_word1(tree, chunk) #from_surface=名詞 72 to_chunk = chunk_dic[chunk.link] 73 to_surface1 = get_word2(tree, to_chunk) 74 75 from_surface2 = get_word2(tree, chunk) #from_surface=名詞 76 to_chunk = chunk_dic[chunk.link] 77 to_surface2 = get_word1(tree, to_chunk) 78 79 tuples_sub.append((from_surface1, to_surface1)) 80 tuples_sub.append((to_surface2, from_surface2)) 81 82 return tuples_sub 83 84 85if __name__ == '__main__' : 86 #line = 'GW中の昼過ぎという時間のせいか、駐車場探しに0分もかかりしかも遠い場所だったため、時間をロスした。古い町並みを通り抜け水路のところまでたどり着いたが、やはり人がたくさんで、落ち着かなかった。やはり、こういうべたな観光地は朝一で行くのが一番だと実感した。すいていれば、もう少し見るところはあったと思うが・・・。,' 87 88 file = codecs.open("/content/stopwords.txt", 'r', 'utf-8') 89 stopwords = [line.strip() for line in file] 90 file.close() 91 92 file = codecs.open('/content/dataset_kurashiki_spring_test.txt', 'r', 'utf-8') 93 94 tuples_sub = [] 95 new_line = [] 96 97 documents = [line.strip() for line in file] 98 for line in documents: 99 new_line = re.sub(r"[!,^_^().<>?]","",line) 100 line = neologdn.normalize(new_line) 101 tuples = [] 102 tuples = get_2_words_take(new_line) 103 104 105 for t in tuples: 106 if not len(t[0])==0 and not len(t[1])==0: 107 tuples_sub.append(t) 108 file.close() 109 110 111 count = [] 112 new_count = [] 113 for n in range(len(tuples_sub)): 114 count_sub = [] 115 for t in range(len(tuples_sub)): 116 if tuples_sub[n][0] == tuples_sub[t][0]: 117 count_sub.append(tuples_sub[t]) 118 count.append(count_sub) 119 120 for element in count: 121 if element not in new_count: 122 new_count.append(element) 123 124 125 126 file = codecs.open('kakariuke1.txt','w','utf-8') 127 for i in range(len(new_count)): 128 file.write(new_count[i][0][0] + "\n") 129 file.close() 130 131 132 file = codecs.open('kakariuke2.txt','w','utf-8') 133 for i in range(len(new_count)): 134 file.write(str(new_count[i]) + "\n") 135 file.close() 136 137 138 139 file = codecs.open('kakariuke3.txt','w','utf-8') 140 for i in range(len(new_count)): 141 file.write(new_count[i][0][1] + "\n") 142 file.close()

試したこと

file = codecs.open('kakariuke3.txt','w','utf-8') for i in range(len(new_count)): file.write(new_count[i][0][1] + "\n") file.close()

上記のkakariuke3.txtに書き込むコードにおいて,これでは各名詞の最初の形容詞もしくは動詞しか書き込むことができません.原因はnew_count[i][0][1] となっていることはわかっています.

そこで,以下のようなコードに変更しました.

file = codecs.open('kakariuke3.txt','w','utf-8') for i in range(len(new_count)): for n in range(len(new_count)): file.write(new_count[i][n][1] + "\n") file.close()

しかし,これでは,エラーが発生してしまいます.
エラー内容:IndexError: list index out of range

これは,range(len(new_count))の範囲でfor文を行っているためだと思います.

この部分の範囲をどのように設定すれば例で示したような形式でファイルに書き込むことができるのかがわからないので教えていただきたいです.

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

0

ベストアンサー

python

1 for n in range(len(new_count)): 2 file.write(new_count[i][n][1] + "\n")

これでは、 new_count の分だけ、 new_count[i] を回してしまうので、リストの数と合わないのでしょう。

python

1 for n in range(len(new_count[i])): 2 file.write(new_count[i][n][1] + "\n")

として、 new_count[i] の数だけ回せばいいのではないでしょうか。

投稿2022/11/26 09:04

TakaiY

総合スコア10557

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

maro

2022/11/26 09:24

エラーはでなかったのですが,出力結果は期待する結果は得られませんでした. ちなみに,結果は以下の意見しか表示されませんでした. あたたかい また,この結果は何の名詞の形容詞が出力されているのかわかりませんでした.
maro

2022/11/26 09:38

file = codecs.open('kakariuke3.txt','w','utf-8') for i in range(len(new_count)): for n in range(len(new_count[i])): file.write(new_count[i][n][1] + ",") file.write("\n") 以上のように変えたら書き込めました!!!

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Python

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