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

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

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

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

Q&A

解決済

1回答

502閲覧

【Python/part3】関数を使った自然言語処理プログラムのエラーを修正したい.

studyprg

総合スコア57

Python 3.x

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

0グッド

0クリップ

投稿2022/12/30 06:29

編集2022/12/30 07:49

読む前に

これは続きものの質問です.
その1リンク
その2リンク
その3<ここ

前提

自然言語処理について勉強しています。
Wikipediaのdumpデータから本文を抜き出して処理をしようと思ってます。
用意したテキストファイルから段落ごとに分割しtf-idfで計算をして表示したいです.
テキストの処理時にエラーが発生しているようです.
このプログラムのエラーを修正して,最後まで動かしたいです.

実現したいことのリスト

  1. テキストファイルを読みこんで格納
  2. 読み込んだテキストから記号などの削除して日本語のみにする
  3. Gfileは段落ごとに分割,myfileは改行四つで区切る(テキストファイルに区切りとして改行を付与しています.),その後,それぞれを段落ごとに分割した後Mecabで名詞のみ抽出
  4. 処理を実行(tf-idfをアレンジしたもの)

現在の状況

コメントで今の問題の解決案を募集してます.

pythonソースコード

1# -*- coding: utf-8 -*- 2from gensim.models import KeyedVectors 3import math 4import MeCab 5import sys 6import re 7# global 8 9m = MeCab.Tagger() # Ochasenで失敗したのでデフォルト 10 11 12myfile = open('history_0text.txt') # history 13 14Gfile = open('koyamaike.txt') # ガイド文書(koyamaike.txt) 15print("\n\nhistoryテキストとGuideテキストを読み込みました\n\n") 16 17 18removeW = re.compile( 19 20 '[!"#$%&\'\\\\()*+,-./:;<=>?@[\\]^_`{|}~「」〔〕“”〈〉, ,『』【】&*・()$#@。、?!`+¥% ]') 21 22# def 23 24 25def makeG(guide): 26 27 guide = removeW.sub('', guide) # 記号除去 28 for x in range(0, len(guide)-1): 29 guide = [line.split()[0] for line in m.parse( 30 guide[x]).splitlines() if "名詞" in line.split()[-1]] 31 return guide 32 33 34def makeH(history): 35 history = removeW.sub('', history) # 記号除去 36 history = history.split('\n\n\n\n') # 記事分割 37 for y in range(0, len(history)-1): 38 history = [line.split()[0] for line in m.parse(history[y]).splitlines() if "名詞" in line.split()[-1]] 39 return history 40 41 42 43def idfe(t, p): 44 idf = 0 45 x = 0 46 for i in range(len(p)): 47 if t in p: 48 x += 1 49 if x == 0: 50 x += 0.05 # beta 51 52 idf = len(p)/x 53 idf = math.log(idf) 54 return idf 55 56 57def tfe(t, para): 58 tf = 0 59 s = 0 60 for x in para: 61 s += para.count(x) 62 63 tf = para.count(t)/s 64 65 return tf 66 67 68def idfe_2(t, H): 69 idf2 = 0 70 x = 0 71 for i in range(len(H)): 72 if t in H[i]: 73 x += 1 74 if x == 0: 75 x += 0.05 # beta 76 77 idf2 = len(H)/x 78 idf2 = math.log(idf2) 79 return idf2 80 81def Rexact(paragraf, history): 82 R = 0 83 for t in paragraf: 84 R += (tfe(t, paragraf)*idfe(t, paragraf)*idfe_2(t, history)) 85 86 return R 87 88 89 90 91 92# main 93history = makeH(myfile) # 段落ごとに分9割された二次元リスト(str) 94G = makeG(Gfile) # 記事ごとに分割された二次元リスト 95for n in range(len(G)): 96 97 Rdice = {} 98 x = 0 99 y = 0 100 101 y = Rexact(G[n], history) 102 Rdice.setdefault(n, y) 103 104 print(n, "段落のtfidf:", y) 105Rsort_s = sorted(Rdics.items()) 106Rsort_e = sorted(Rdice.items()) 107print(Rsort_s) 108print(Rsort_e) 109print("ended") 110 111exit 112

次にエラーです.

cmd

1python3 Jtest.py 2 3 4historyテキストとGuideテキストを読み込みました 5 6 7Traceback (most recent call last): 8 File "/Users/****/Jtest.py", line 151, in <module> 9 history = makeH(myfile) # 段落ごとに分割された二次元リスト(str) 10 File "/Users/****/Jtest.py", line 40, in makeH 11 history[y]).splitlines() if "名詞" in line.split()[-1]] 12IndexError: list index out of range 13

###実行環境
Macbook Pro(2017,OS:11.6.7)
Python3実行
一応利用するテキストファイルの一部も添付しておきます.

koyamaike.txt

1湖山池 2{{Infobox 湖 3|名称=湖山池 4|画像=[[画像:湖山池.jpg|right|300px]] 5|所在地={{JPN}} [[鳥取県]][[鳥取市]] 6|面積=7 7|周囲長=18 8|最大水深=6.5 9|平均水深= 10|貯水量= 11|標高=0 12|成因=[[海跡湖]] 13|淡汽=[[汽水]] 14|湖沼型=[[富栄養湖]] 15|透明度=0.7 16}} 17'''湖山池'''(こやまいけ)は、[[鳥取県]][[鳥取市]]の北部にある[[汽水湖]]。「[[池]]」と付く湖沼の中では[[日本]]最大の広さである。 18== 概要 == 19湖山池は鳥取県内では、[[中海]]の次に大きい湖沼である。古代に[[日本海]]から湾入した場所が、[[砂丘]]の発達や[[堆積]]により、海と分離されてできた[[海跡湖]]である。大小多数の小[[島]]が浮かぶ。最大の島である[[青島 (鳥取県)|青島]]には、湖岸から架橋されており、桜の木が多数植えられた道路で徒歩や自転車により一周することができ、キャンプも可能である。数本の河川が流入、湖山川によって[[日本海]]と結ばれる。鳥取市郊外の行楽地の一つである。 20 21鳥取市三津地区では、全国的にも珍しい[[石がま漁]]が冬季に行われている。石の隙間に潜む魚を棒でつついて追い込み捕獲する漁法で、県指定無形民俗文化財に指定されている。地元自治会やNPOが保存に努めている。漁期間中には[[石がま祭]]も行われる。 22 23広大な水田を有していた長者が、日没までに田植えが終わらなかったため、扇子で夕日を招き返して田植えを終えたが、一夜明けると田は全て池に変わっていた、という「[[湖山長者]]」の伝説が知られる(似たような話が[[岐阜市]]の[[ゆうべが池]]に伝わっている)。古くから開けた地域であり、青島周辺には[[縄文時代]]から[[弥生時代]]にかけての[[遺跡]]がある。また[[戦国時代 (日本)|戦国時代]]には東側の湖畔に[[因幡国]]守護所である[[布勢天神山城]]がおかれ、西側の湖畔に突き出た半島には国人領主[[吉岡氏]]の居城である[[防己尾城]]が築かれた。 24 25 26#以下略

list_history_0.txt

1日本ゴルフツアー機構 2{{基礎情報 非営利団体 3|名称=日本ゴルフツアー機構&lt;br /&gt;''Japan Golf Tour Organization'' 4|ロゴ= 5|創立者= 6|団体種類=[[社団法人|一般社団法人]] 7|設立=[[2005年]][[7月28日]] 8|所在地= 9|起源= 10|主要人物=会長 [[海老沢勝二]] 11|活動地域={{JPN}} 12|製品= 13|主眼= 14|活動内容=プロ[[ゴルフ]]ツアーの主催 15|活動手段= 16|収入= 17|基本財産= 18|ボランティア人数= 19|従業員数= 20|会員数= 21|子団体= 22|標語= 23|ウェブサイト= http://www.jgto.org/ 24|解散= 25|特記事項= 26}} 27'''一般社団法人日本ゴルフツアー機構'''(にっほんゴルフツアーきこう、JGTO;''Japan Golf Tour Organization'')とは、[[1999年]]度から[[日本]]のプロ[[ゴルフ]]ツアーの試合について主催・主管を行っている組織である。 28 29== 概要 == 30シーズンは4月の「[[東建ホームメイトカップ]]」が新年度の最初の試合となり、12月まで25前後の試合を開催している。基本的には1大会4日間競技で開催している。なお、一部の大会では当ツアーと[[ワンアジアツアー]]が共同で主催する国外での大会があり、[[2014年]](2試合。&lt;ref&gt;日本開催・[[アジアンツアー]]共催の「ダイヤモンドカップ」を含むと3試合&lt;/ref&gt;)の実質的な当ツアーの[[開幕戦]]は「インドネシアPGA選手権」である&lt;ref&gt;[http://www.jgto.org/pc/OtherTopicsDetail.do?year=2014&amp;tournaKbnCd=0&amp;conferenceCd=000&amp;languageKbn=0&amp;administerNo=944 いよいよ2014年の初戦、インドネシアPGA選手権](日本ゴルフツアー機構。当初は[[タイランドオープン]]が実質的な開幕戦の予定だったが、[[タイ王国]]の政治的な内紛が起こっているという事情により延期となった)&lt;/ref&gt;。 31 32#中略 33 34{{デフォルトソート:にほんこるふつあきこう}} 35[[Category:日本ゴルフツアー|*]] 36[[Category:ゴルフに関する日本の組織|こるふつあきこう]] 37[[Category:一般社団法人 (スポーツ関係)]] 38[[Category:東京都港区の一般社団法人]] 39[[Category:2005年設立]] 40 41 42 43桂米朝 44[[画像:Musubi-kashiwa.svg|right|thumb|結び柏は、桂[[米朝一門]]の[[定紋]]である。]] 45'''桂 米朝'''(かつら べいちょう)は、[[上方落語]]の[[名跡]]。本来は、大名跡である[[桂米團治]]を継ぐ前段階の名跡。初代が入門した際、師匠の「米」と夫人の名前である「あさ」から「米朝」とつけたのが始まり。当代は3代目。 46 47 48 49

よろしくお願いします.

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

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

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

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

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

melian

2022/12/30 06:50 編集

File "/Users/****/Jtest.py", line 40, in makeH history[y]).splitlines() if "名詞" in line.split()[-1]] IndexError: list index out of range このエラーメッセージから判ることは、line が空文字列("")である、ということです。
studyprg

2022/12/30 06:50

lineが空っていうのはわからなかったです.historyの要素を突っ込んでると思いました. どうしたらいいですか?
melian

2022/12/30 06:58

何をどうしたいのかがよく分からないのですが、 if "名詞" in line.split()[-1] この部分を、 if line.strip() and "名詞" in line.split()[-1] とでもすれば、あるいは動作するかもしれません。全体の処理を見直す方がよいかとは思いますが。
studyprg

2022/12/30 07:06

melianさんの修正案で試しましたが以下のエラーが出ました. Traceback (most recent call last): File "/Users/****/Jtest.py", line 151, in <module> history = makeH(myfile) # 段落ごとに分割された二次元リスト(str) File "/Users/****/Jtest.py", line 40, in makeH history[y]).splitlines() if line.strip() and "名詞" in line.split()[-1]] IndexError: list index out of range 質問文と同様のものでした. >とでもすれば、あるいは動作するかもしれません。全体の処理を見直す方がよいかとは思いますが。 ここってどうゆう意味ですかね? 教えていただけると幸いです.
studyprg

2022/12/30 07:08

何をどうしたいのかがよく分からないのですが、> 前に読んだ自然言語処理の論文に段落ごとにTf-Idfを計算して推薦度を求めるやつがありまして,それをPythonで再現したいと思ってるんです.
melian

2022/12/30 08:03 編集

今更ながらに気がついたのですが、ループの内部で history を上書きしていますね。これがエラーの原因です。 history = history.split('\n\n\n\n') # 記事分割 for y in range(0, len(history)-1):  history = [line.split()[0] for line in m.parse(history[y]).splitlines() if "名詞" in line.split()[-1]] なので、おそらく、以下の様にするのかと。 def makeH(history):   history = removeW.sub('', history) # 記号除去   history = history.split('\n\n\n\n') # 記事分割   hist = []   for y in range(0, len(history)-1):     hist += [line.split()[0] for line in m.parse(history[y]).splitlines() if "名詞" in line.split()[-1]]   return hist
studyprg

2022/12/30 08:17

ありがとうございます。 guideも上書きされてますかね?
melian

2022/12/30 08:23

はい、その通りです。
studyprg

2022/12/30 08:30

動かしてみたら最後までうまいこといきました. 回答お願いします.
melian

2022/12/30 08:48

はい、回答しました。
studyprg

2022/12/30 09:10

guideも書き毛が必要では?
studyprg

2022/12/30 09:11

書き毛が=>書き換え
guest

回答1

0

ベストアンサー

※ コメントから転記

ループの内部で history を上書きしていることが原因です。

python

1history = history.split('\n\n\n\n') # 記事分割 2for y in range(0, len(history)-1): 3 history = [line.split()[0] for line in m.parse(history[y]).splitlines() if "名詞" in line.split()[-1]]

なので、以下の様にするとよいかと思います。

python

1def makeH(history): 2 history = removeW.sub('', history) # 記号除去 3 history = history.split('\n\n\n\n') # 記事分割 4 hist = [] 5 for y in range(0, len(history)-1): 6 hist += [line.split()[0] for line in m.parse(history[y]).splitlines() if "名詞" in line.split()[-1]] 7 return hist

投稿2022/12/30 08:48

melian

総合スコア19809

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問