LoginSignup
1
1

More than 3 years have passed since last update.

言語処理100本ノック-70(StanfordNLP使用):データの入手・整形

Last updated at Posted at 2019-11-27

言語処理100本ノック 2015の70本目の記録です。
基本的に「素人の言語処理100本ノック」とほぼ同じ内容にしていたので、ブロクに投稿していなかったのですが、「第8章: 機械学習」については、真剣に時間をかけて取り組んでいてある程度変えているので投稿します。StanfordNLPをメインに使用していきます。

参考リンク

リンク 備考
070.データの入手・整形.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:70 言語処理100本ノックで常にお世話になっています
PythonによるStanfordNLP入門 Stanford Core NLPとの違いがわかりやすかったです

環境

種類 バージョン 内容
OS Ubuntu18.04.01 LTS 仮想で動かしています
pyenv 1.2.15 複数Python環境を使うことがあるのでpyenv使っています
Python 3.6.9 pyenv上でpython3.6.9を使っています
3.7や3.8系を使っていないことに深い理由はありません
パッケージはvenvを使って管理しています

問題

第8章: 機械学習

本章では,Bo Pang氏とLillian Lee氏が公開しているMovie Review Datasentence polarity dataset v1.0を用い,文を肯定的(ポジティブ)もしくは否定的(ネガティブ)に分類するタスク(極性分析)に取り組む.

70. データの入手・整形

文に関する極性分析の正解データを用い,以下の要領で正解データ(sentiment.txt)を作成せよ.

  1. rt-polarity.posの各行の先頭に"+1 "という文字列を追加する(極性ラベル"+1"とスペースに続けて肯定的な文の内容が続く)
  2. rt-polarity.negの各行の先頭に"-1 "という文字列を追加する(極性ラベル"-1"とスペースに続けて否定的な文の内容が続く)
  3. 上述1と2の内容を結合(concatenate)し,行をランダムに並び替える

sentiment.txtを作成したら,正例(肯定的な文)の数と負例(否定的な文)の数を確認せよ.

読み込むファイルの注意点

  1. 文字コードがUTF-8ではなくWINDOWS-1252らしい(しっかりと確認していませんが「素人の言語処理100本ノック:70」と同じふぁいる読み込みをしています)
  2. 英語だけでなくウムラウトを含むテキストがある(「Ü」みたいな文字)
  3. 基本的に全文字が小文字化されています

回答

回答前提

Jupyter Notebookのディレクトリの下にこんなフォルダ構成にしています。元データを解凍して置いています。

└── rt-polaritydata
    ├── rt-polarity.neg
    └── rt-polarity.pos

回答プログラム 070.データの入手・整形.ipynb

import codecs
import random

FNAME_SMT = 'sentiment.txt'
pos_prefix = '+1'
neg_prefix = '-1'

result = []

def read_file(fname, prefix):
    # codecsを使わずにopen関数で読み込めるか未確認()
    with codecs.open(fname, encoding='cp1252') as file:  # Encodingは Windows-1252
        return ['{0} {1}'.format(prefix, line.strip()) for line in file]

# ポジティブ読込
result.extend(read_file('./rt-polaritydata/rt-polarity.pos', pos_prefix))

# ネガティブ読込
result.extend(read_file('./rt-polaritydata/rt-polarity.neg', neg_prefix))

random.shuffle(result)

with open(FNAME_SMT, 'w') as file_out:
    file_out.write('\n'.join(result))

# 数の確認
cnt_pos = 0
cnt_neg = 0
with open(FNAME_SMT) as file:
    for line in file:
        if line.startswith(pos_prefix):
            cnt_pos += 1
        elif line.startswith(neg_prefix):
            cnt_neg += 1

print('pos:{}, neg:{}'.format(cnt_pos, cnt_neg))

回答解説

基本的にファイル読込と書込なのであまり特筆することをしていないです。
ファイルオープンのためにcodecsライブラリを使っていますが、これは素人の言語処理100本ノック:70の該当箇所をコピペしただけなので、通常のopen関数でも可能かは検証していません。
ただ、後続のプログラムでまたcodecsライブラリを使いたくなかったので保存はUTF-8にしています。それでもウムラウトを含んだ文字も正しく保存できています。

実行すると最後のprint関数によって以下のように件数が出ます。

pos:5331, neg:5331
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1