文章を分類④:Neural Network Librariesによる分類テスト

Neural Network Consoleによる学習済みニューラルネットワークのNeural Network Librariesでの利用方法は2種あるそうです。ここでは、一切コーディングを行うことなく、簡単に推論を実行できるという事で「コマンドラインインターフェイスを用いて推論を実行する方法」を試します。
サーバサイドでのテストは環境づくりが無理なので、ローカルでテストする事にしました。
最初は、ブラウザ上でテキストを選択して、そこに結果を表示しようと考えました。しかし、ローカルでのjavascriptによるブラウザの操作は、セキュリティによりかなり制約されます。特にjavascriptからpythonを実行出来ないので、ブラウザを使うのは諦めました。
テスト用のフォルダに文章を置いて、バッチファイルでpythonプログラムを連続実行して、結果をファイルにする事にしましたが、実際に作ってみると有意な答えが帰って来ませんでした。
原因は、word2vecが吐き出すデータが毎回異なってしまう事です。
Randomness in Doc2Vec
データが毎回異なる理由は、Python 3.3以降、特定の種類の攻撃を避けるために、ハッシングアルゴリズムが非決定的にソルトされているためです。(何となく理解出来ます。)
Disable hash randomization from within python program
word2vecで使う乱数を固定してからデータをつくって、Neural Network Consoleで学習をする事にしました。「文章を分類③」の手順と同じですが、コマンドプロンプトから一時的に存在しない環境変数PYTHONHASHSEEDをつくり、PYTHONHASHSEED=0でword2vecで使う乱数を固定します。setによる環境変数設定はこれを実行したコマンドプロンプトと、そこから起動したプロセスにのみ適用されます。
make.batを実行して、フォルダ「movie-enter」と、フォルダ「sports-watch」のテキストを「CSV file」の単語リストに直します。「文章を分類③」の手順と同じです。
make.bat

set PYTHONHASHSEED=0
gensim2.py

gensim2.py

import re
import csv
import glob
import os
from janome.tokenizer import Tokenizer
from gensim.models import word2vec
os.environ['PYTHONHASHSEED'] = '0'

# テキストを引数として、形態素解析の結果、名詞・動詞原型のみを配列で抽出する関数を定義 
def extract_words(text):
    tokens = t.tokenize(text)
    return [token.base_form for token in tokens
        if token.part_of_speech.split(',')[0] in['名詞', '動詞']]

t = Tokenizer()
path = "./test"
file_list = glob.glob(path + '/' + '*.txt')

for filename in file_list:
  with open(filename,encoding="UTF-8",mode='r',errors="ignore") as input:
    textorg = input.read()
    data2 = re.sub(r'[\s ]',"",textorg)
    data3 = re.sub(r'http.+0900',"",data2)
    text = re.sub('【[^】]*】',"",data3)

    # 全体のテキストを句点('。')で区切った配列にする。 
    sentences = text.split('。')
    # それぞれの文章を単語リストに変換(処理に数分かかります)
    word_list = [extract_words(sentence) for sentence in sentences]

    model = word2vec.Word2Vec(word_list, size=100,min_count=3,window=5,iter=100)

    with open(filename + '.csv', 'w', encoding='utf-8') as f:

       for word in model.wv.vocab.keys():
           embedding = model.wv[word]

           writer = csv.writer(f, lineterminator='\n')
           writer.writerow(embedding)

「文章を分類③」の手順のように、cut.pyを実行します。単語数8に直したcsvファイルを、フォルダ「movie-enter」フォルダ「movie-enter」に入れます。「文章を分類③」の手順と同じにshuffle.pyを実行します。
Neural Network Consoleで学習します。


Accuracyは、91.42%になりました。

この学習済みニューラルネットワークを使って分類テストをします。
適当なフォルダをつくり、そこにフォルダ「result」フォルダ「sampledata」そしてletter2.bat、settext.pyとtexttest.pyをつくります。
letter2.bat

set PYTHONHASHSEED=0
python settext.py
python texttest.py
python "C:\tool\neural_network_console_120\libs\nnabla\python\src\nnabla\utils\cli\cli.py" forward -c "C:\tool\neural_network_console_120\samples\Letter2_dataset\letter2.files\20180830_151137\net.nntxt" -p "C:\tool\neural_network_console_120\samples\Letter2_dataset\letter2.files\20180830_151137\parameters.h5" -d "C:\tool\Download\Letter2_dataset\text2_test.csv" -o "C:\tool\Download\Letter2_dataset\result"

settext.py

import re
import csv
import glob
import os
from janome.tokenizer import Tokenizer
from gensim.models import word2vec
os.environ['PYTHONHASHSEED'] = '0'

# テキストを引数として、形態素解析の結果、名詞・動詞原型のみを配列で抽出する関数を定義 
def extract_words(text):
    tokens = t.tokenize(text)
    return [token.base_form for token in tokens
        if token.part_of_speech.split(',')[0] in['名詞', '動詞']]

t = Tokenizer()
file_list = glob.glob('./sampledata/' + '*.txt')

for filename in file_list:
  with open(filename,encoding="UTF-8",mode='r',errors="ignore") as input:
    textorg = input.read()
    data2 = re.sub(r'[\s ]',"",textorg)
    data3 = re.sub(r'http.+0900',"",data2)
    text = re.sub('【[^】]*】',"",data3)

    # 全体のテキストを句点('。')で区切った配列にする。 
    sentences = text.split('。')
    # それぞれの文章を単語リストに変換(処理に数分かかります)
    word_list = [extract_words(sentence) for sentence in sentences]
    model = word2vec.Word2Vec(word_list, size=100,min_count=3,window=5,iter=100)

    with open(filename + '.tsv', 'w', encoding='utf-8') as f:
       for word in model.wv.vocab.keys():
           embedding = model.wv[word]
           writer = csv.writer(f, lineterminator='\n')
           writer.writerow(embedding)

file_list = glob.glob('./sampledata/' + '*.tsv')

for filename in file_list:
  count = 0 
  # ファイルを読み込みモードでオープン
  with open(filename,encoding="UTF-8",mode='r') as f:
    reader = csv.reader(f)
    with open(re.sub(r'\.tsv',"",filename) + '.csv','a',newline='') as fw:
       writer = csv.writer(fw)

       for row in reader:
          if count < 8:
            writer.writerow(row)
            count = count+1
       while count < 8:
            writer.writerow([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
            count = count +1

texttest.py

import glob
import re
import random

# 指定したパス内の全てのファイルとディレクトリを要素とするリストを返す
files = glob.glob("./sampledata/*.csv")

with open('text2_test.csv',encoding="UTF-8", mode='w') as fp:
     fp.write('x:image')
     fp.write("\n")
     for file in files:
          fp.write(file)
          fp.write("\n")

フォルダ「sampledata」に幾つかのテキストをセットして、letter2.batを実行します。
実行結果
フォルダ「sampledata」に、movie-enterデータ11、sports-watchデータ11入れてテストした結果です。

分類ミスが二つありました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です