Less is Best

rubyが好き。技術の話とスタートアップに興味があります。

nltk.MaxentClassifier.train()がエラーを吐く。

入門 自然言語処理

入門 自然言語処理

nltk.MaxentClassifier.train()がエラーを吐く。

入門自然言語処理を順調に読み進めていた所、第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)
.
.
.

で再度試してみたら成功しました。 なかなか日本語の情報が少なくて学習も大変ですが、自然言語処理、しっかり習得したいですね!