入門自然言語処理を順調に読み進めていた所、第6章練習問題5にて引っかかる。
文書分類を最大エントロピー分類を用いて行おうとした所、エラーを吐きまくってうごいてくれない。
# -*- coding: utf-8 -*-
#from __future__ import division
import nltk,re
import random
import numpy
#映画レビューが肯定的か否定的か分類する
#データ
from nltk.corpus import movie_reviews
documents = [(list(movie_reviews.words(fileid)),category)
for category in movie_reviews.categories()
for fileid in movie_reviews.fileids(category)]
random.shuffle(documents)
#素性抽出器
all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
word_features = all_words.keys()[:2000]#頻出ワード2000
def document_features(document):
document_words = set(document)
features = {}
for w in word_features:
features['contains(%s)' % w] = (w in document) #top2000の文字がdocに入っているかどうか
return features
#分類器の訓練とテスト
featuresets = [(document_features(d),c) for (d,c) in documents]
train_set,test_set = featuresets[100:],featuresets[:100]
#最大エントロピー分類
maxentclassifier = nltk.MaxentClassifier.train(train_set)
#test
print "MaxentClassifier"
print nltk.classify.accuracy(maxentclassifier,test_set)
print maxentclassifier.show_most_informative_features(5)
エラーはこんな感じ
==> Training (100 iterations)
Iteration Log Likelihood Accuracy
---------------------------------------
1 -0.69315 0.498
/usr/local/lib/python2.7/site-packages/nltk/classify/maxent.py:1332: RuntimeWarning: overflow encountered in power
exp_nf_delta = 2 ** nf_delta
/usr/local/lib/python2.7/site-packages/nltk/classify/maxent.py:1334: RuntimeWarning: invalid value encountered in multiply
sum1 = numpy.sum(exp_nf_delta * A, axis=0)
/usr/local/lib/python2.7/site-packages/nltk/classify/maxent.py:1335: RuntimeWarning: invalid value encountered in multiply
sum2 = numpy.sum(nf_exp_nf_delta * A, axis=0)
/usr/local/lib/python2.7/site-packages/nltk/classify/maxent.py:1341: RuntimeWarning: invalid value encountered in divide
deltas -= (ffreq_empirical - sum1) / -sum2
Final nan 0.502
どうやらmaxent.pyの初期設定状態の変数が、overflowを起こしていることが原因でエラーを吐いているようである。
で、いろいろググってみましたが日本語情報なかなか出てこなかったのでメモ。
ここを参考に修正しました。
Hello Dmitry,
will this change affect the performance? Based on my test, the improvement between iterations drops a lot, comparing to GIS algorithm with default set.
the accuracy could reach to 70% after three iterations using GIS, but only 58% after using the modified IIS.
在 2012年5月7日星期一UTC-4下午6时05分38秒,Dmitry Sergeev写道:
It seems that changing exp_nf_delta = 2 ** nf_delta (maxent.py line ~1350) to exp_nf_delta = 2 ** numpy.sqrt(nf_delta) do the trick.
ってことで、
sudo vi /usr/local/lib/python2.7/site-packages/nltk/classify/maxent.py
.
.
.
for rangenum in range(MAX_NEWTON):
nf_delta = numpy.outer(nfarray, deltas)
#exp_nf_delta = 2 ** nf_delt # ここから
exp_nf_delta = 2 ** numpy.sqrt(nf_delta) #これに変更
nf_exp_nf_delta = nftranspose * exp_nf_delta
sum1 = numpy.sum(exp_nf_delta * A, axis=0)
sum2 = numpy.sum(nf_exp_nf_delta * A, axis=0)
.
.
.
で再度試してみたら成功しました。
なかなか日本語の情報が少なくて学習も大変ですが、自然言語処理、しっかり習得したいですね!