アイソモカ

知の遊牧民の開発記録

開発記録 200229 Sat (100本ノック #072, 素性抽出)

先週末は新居を探しに行ったし、今週末は引越しの見積りの人が家に来たし、内定先に色々な書類も出した。着々と準備が進んでいる気がする。準備は進んでいるものの、新しい仕事への不安もつのる。

新型肺炎の拡散防止のために日本語教室も休みになってしまい、とても寂しい。

言語処理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