先週末は新居を探しに行ったし、今週末は引越しの見積りの人が家に来たし、内定先に色々な書類も出した。着々と準備が進んでいる気がする。準備は進んでいるものの、新しい仕事への不安もつのる。
新型肺炎の拡散防止のために日本語教室も休みになってしまい、とても寂しい。
言語処理100本ノック #072
# 72. 素性抽出
極性分析に有用そうな素性を各自で設計し,学習データから素性を抽出せよ.素性としては,レビューからストップワードを除去し,各単語をステミング処理したものが最低限のベースラインとなるであろう.
記号を除去してから、ストップワードを除去し、最後にステミングした。
ステミングとストップワードの除去、どちらを先にやるべきなのか?と少し悩んだけど、問題文の順序でやろう。
記号を除去する
Python のライブラリにある、記号の文字列 string.punctuation を使う。 参考 👉 Python 半角の記号を削除したい - Qiita
>>> import string >>> string.punctuation '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
記号は全部スペースに置き換えることにした。
ストップワードを除去する
言語処理100本ノック#071 で使った NLTK のstopwords.words(‘english’)
に、
[’film’, ‘films’, ‘movie’, ‘movies’]
を加えたものをストップワードとする。
ステミングする:NLTK の ステミングツール PorterStemmer()
言語処理100本ノック#052 では、stemming.porter2 の stem()
を使ったが、NLTK パッケージにもステミングツールがあるので、今回はこちらを使ってみよう。
使い方の参考 👉 NLTKの使い方をいろいろ調べてみた - Qiita
stemming.porter2 でうまくいかなかったやつはうまくいくのかな〜と思って、比較してみたけど、ほぼ変わらない(両方とも同じ Porter の方法だから当然か)。
# knock_072_2.py # for studying stemming from nltk import stem as nltkstem from stemming.porter2 import stem as p2stem stemmer = nltkstem.PorterStemmer() words = ['beatuy', 'beautiful', \ 'have', 'had', 'has', 'having'] print('w', '\t', 'stemmer.stem(w)', '\t', 'p2stem(w)') print('--------------------') for w in words: print(w, '\t', stemmer.stem(w), '\t', p2stem(w))
👇
w stemmer.stem(w) p2stem(w) -------------------- beatuy beatuy beatuy beautiful beauti beauti have have have had had had has ha has having have have
‘has’ だけちょっと違った。
解答
# knock_072.py import string import nltk from nltk import stem from nltk.corpus import stopwords SENTIMENTFILE = './70_sentiment.txt' FEATUREFILE = './72_feature.txt' def replace_symbol(line): returnline = '' for char in line: if char in string.punctuation: returnline += ' ' else: returnline += char return returnline def judge_stop(word): if len(word) < 1: return True if word in stopwords.words('english') + \ ['film', 'films', 'movie', 'movies']: return True else: return False def extract(line): stemmer = stem.PorterStemmer() for word in line.split(' '): word_stem = stemmer.stem(word) if judge_stop(word): continue yield stemmer.stem(word_stem) if __name__ == '__main__': with open(SENTIMENTFILE, 'r') as fr, open(FEATUREFILE, 'w') as fw: for line in fr: fw.write(line[:2]+' ') rep_line = replace_symbol(line[3:-1]) for word in list(extract(rep_line)): fw.write(word+' ') fw.write('\n')
出力
# 72_sentiment.txt 20行目まで +1 powder blue sun splash white tuni make allur backdrop sensuou spirit tale prim widow find unlik relea belli danc club -1 hate everi minut +1 grip even viewer interest rap cut heart american societi unnerv way -1 fluffi dispo +1 escap preciou trap romant comedi infu stori real complic emot +1 argento 26 bring youth chang world aggress project cut open vein bled raw stock -1 gleefulli thumpingli hyperbol term cover everi clich compendium crass jade type phoni baloney biz -1 mariah carey give us anoth peek magic saw glitter wisegirl -1 grand fart come director begin resembl someon crazi french grandfath +1 wit sever greek american wed happili victim none testifi compar accuraci ms vardalo memori insight +1 sweetli sexi funni touch +1 final genr deliv coupl genr less +1 vividli convey shadow side 30 year friendship two english women +1 weight piec uner profess chilli product fascin emb lurid topic prove recommend enough -1 string rehash sight gag base insipid vulgar -1 return neverland manag straddl line anoth classic compani anoth run mill disney sequel intend home video market +1 pranc way tailor made part male hooker approach end vital jagger obviou relish everi self mock moment +1 immer us endlessli invent fierc competit world hip hop dj project sensat revelatori even scratch make itch -1 screenplay come across rather unint hip hop scoobi doo -1 pedestrian flat drama scream amateur almost everi frame