前提・実現したいこと
実現したいこととしてはファイルの実行エラーを解消することです。
自分はある自然言語処理の本で書かれているコードをpycharmを使って実行しています。
pychramのプロジェクト構成としてあらかじめ作った新規プロジェクトの下にpreprocessing.py train.py utils.pyという名前のファイルとdataという名前のフォルダを格納し、dataフォルダにamazon_data.tsvを格納しています。
発生している問題・エラーメッセージ
本に書かれているコードを実行すると以下のようなエラーメッセージが発生しました。
FileNotFoundError: [Errno 2] No such file or directory: 'amazon_data.tsv'
該当のソースコード(utils.py/preprocessing.py/train.py)
python
1--utils.py-- 2import string 3import pandas as pd 4 5def filter_by_ascii_rate(text,threshold=0.9): 6 ascii_letters = set(string.printable) 7 rate = sum(c in ascii_letters for c in text) / len(text) 8 return rate <= threshold 9def load_dataset(filename,n=5000,state=6): 10 df = pd.read_csv(filename, sep='\t') 11 12 is_jp = df.review_body.apply(filter_by_ascii_rate) 13 df = df[is_jp] 14 15 df = df.sample(frac=1, random_state=state) 16 grouped = df.groupby('star_rating') 17 df = grouped.head(n=n) 18 return df.review_body.values, df.star_rating.values 19 20from sklearn.feature_extraction.text import CountVectorizer 21from sklearn.linear_model import LogisticRegression 22from sklearn.metrics import accuracy_score 23 24def train_and_eval(x_train, y_train, x_test, y_test, lowercase=False, tokenize=None, preprocessor=None): 25 vectorizer = CountVectorizer(lowercase=lowercase, tokenizer=tokenize, preprocessor=preprocessor) 26 x_train_vec = vectorizer.fit_transform(x_train) 27 x_test_vec = vectorizer.transform(x_test) 28 clf = LogisticRegression(solver='liblinear') 29 clf.fit(x_train_vec, y_train) 30 y_pred = clf.predict(x_test_vec) 31 score = accuracy_score(y_test, y_pred) 32 print('{:.4f}'.format(score)) 33 34--preprocessing.py-- 35import re 36 37from bs4 import BeautifulSoup 38from janome.tokenizer import Tokenizer 39t = Tokenizer() 40 41 42def clean_html(html, strip=False): 43 soup = BeautifulSoup(html, 'html.parser') 44 text = soup.get_text(strip=strip) 45 return text 46 47 48def tokenize(text): 49 return t.tokenize(text, wakati=True) 50 51 52def tokenize_base_form(text): 53 tokens = [token.base_form for token in t.tokenize(text)] 54 return tokens 55 56 57def normalize_number(text, reduce=False): 58 if reduce: 59 normalized_text = re.sub(r'\d+', '0', text) 60 else: 61 normalized_text = re.sub(r'\d', '0', text) 62 return normalized_text 63 64 65def truncate(sequence, maxlen): 66 return sequence[:maxlen] 67 68 69 70--train.py-- 71from sklearn.model_selection import train_test_split 72 73from preprocessing import clean_html, normalize_number, tokenize, tokenize_base_form 74from utils import load_dataset, train_and_eval 75 76 77 78 79def main(): 80 x, y = load_dataset('data/amazon_data.tsv', n=1000) 81 82 x_train, x_test, y_train, y_test = train_test_split(x, y, 83 test_size=0.2, 84 random_state=42) 85 86 print('Tokenization only.') 87 train_and_eval(x_train, y_train, x_test, y_test, tokenize=tokenize) 88 89 print('Clean html.') 90 train_and_eval(x_train, y_train, x_test, y_test, tokenize=tokenize, preprocessor=clean_html) 91 92 print('Normalize number.') 93 train_and_eval(x_train, y_train, x_test, y_test, tokenize=tokenize, preprocessor=normalize_number) 94 95 print('Base form.') 96 train_and_eval(x_train, y_train, x_test, y_test, tokenize=tokenize_base_form) 97 98 print('Lower text.') 99 train_and_eval(x_train, y_train, x_test, y_test, tokenize=tokenize, lowercase=True) 100 101 102if __name__ == '__main__': 103 main() 104
試したこと
解決法がわからず、とりあえずtsvファイルの格納場所を別のところに移して実行してみた
補足情報(FW/ツールのバージョンなど)
今回使っている本: https://book.mynavi.jp/ec/products/detail/id=113274
> dataフォルダにamazon_data.tsvを格納しています。
本にそういう指示があったのですか?
コードを見るとカレントディレクトリのamazon_data.tsvを読み込むようですが。
本当なら画像を貼りたいのですが、うまくいかないので本に書かれている説明を部分的に書き出すと
「dataディレクトリの中には使用するデータセットを格納しておきます。今回の場合はamazonの商品レビューを利用します。(amazon_data.tsv)」と書かれているのでおそらく間違ってはいないと思われます。
amazon_data.tsvファイルをカレントディレクトリに置いて実行してもダメだったんですね?
dataフォルダやほかのpyファイルと同じ階層にtsvファイルを格納すると、今回解決したいエラーは消えたのですが
新しくpandas.errors.ParserError: Error tokenizing data. C error: Expected 2 fields in line 6, saw 3
というエラーや別のエラーも出てきてしまいました。
では、tsvファイルは data に置いて、
load_dataset('amazon_data.tsv', n=1000)
を
load_dataset('data/amazon_data.tsv', n=1000)
にしてはどうでしょう。
KUROROさんの回答に近いですね。
実行してみたのですが、さっきと同じ内容のエラーが表示されてしまいました。
ファイルの場所の問題は解決しましたね。
本に書かれている通りに amazon_data.tsv を data の中に置いたなら、
load_dataset('data/amazon_data.tsv', n=1000)
でなければならない。これは本に載っているコードが間違っているのだと思いますので出版社に文句を言いましょう ,-)
で、pandasが吐いているエラー「Expected 2 fields in line 6, saw 3」というのは、たぶん、CSVの要素数が先頭行では2個だったので2列の表として読み込みをしていたのに、6行目でデータが3個に増えたのでpandasが怒っているようです。つまり amazon_data.tsv が良くないので直せるなら直すというのが解決策です。
現在の amazon_data.tsv をなんとかして読み込むには…
2つの方法を見つけました。
1つは、一度csvモジュールを使ってリストで読み込んでデータフレームに変換するという方法。
https://fujiyamaegg.com/python-parseerror/
もう1つは、列の数をnamesで指定してあげるという方法。
http://blog.mwsoft.jp/article/113600124.html
お試しください。
load_dataset('data/amazon_data.tsv', n=1000)の部分をload_dataset('amazon_data.tsv', n=1000)であると誤認していました。すみませんでした。
amazon_data.tsv をなんとかして読み込む方法として1つ目に提示してもらったやり方で
やってみたところpandasに関するエラーがすべて消えて、別のエラーとして
AttributeError: 'DataFrame' object has no attribute 'review_body'
というものが発生しました。
そもそも1つ目の方法を正しく実行しているかについては自信がないので自分が変更した部分をについて
説明すると、utils.pyの
def load_dataset(filename, n=5000, state=6):
df = pd.read_csv(filename, sep='\t')
という部分を
csvをインポートしてから
def load_dataset(filename,n=5000,state=6):
pd.options.display.max_rows = None
pd.options.display.max_columns = None
with open(filename, "r", encoding="utf-8", errors="", newline="") as f:
lst = csv.reader(f, delimiter=",")
df = pd.DataFrame(lst)
のように変更しました。
回答1件
あなたの回答
tips
プレビュー