scikit-learn
python3

scikit-learnのtutorialをやってみた(Working With Text Data: Exercise 3)

Exercise 2に引き続き3もやったのでメモ書きしておきます。

環境

  • macOS High Sierra(10.13.4)
  • Python 3.6.0

資料

内容

今回のexerciseは前回、前々回までで作成したモデルをコマンドラインから利用するプログラムを作成していきます。そのため新しいアルゴリズムやscikit-learnのモジュールを導入するといったことはないです。作成するプログラムは、ユーザから入力されたデータ(文章)を学習済みのモデルを使って解析して言語を推定、さらに英語と推定された場合は極性(ポジティブかネガティブか)の判定も行う、といったものです。

exercise1、2で作成したプログラムに処理を追加

事前に学習済みモデルが必要なのでexercise1、2で作成したコードにpickleというモジュールによる処理を追加し、学習したモデルのインスタンスをファイルに書き出すようにします。pickleモジュールはクラスのインスタンスなどをバイナリ形式でファイルにダンプしたり、ダンプしたインスタンスをロードしてプログラム内で利用したりといったことができるモジュールです。詳しくは公式ドキュメントを参照ください。
処理を追加する箇所は両方ともclf.fit()で学習が完了した直後になります。

exercise_01_language_train_model.py
(snip)
import pickle

# インスタンスのダンプ先になるファイルをオープンする
trained_clf = open(sys.argv[2], "bw")
# インスタンスをダンプする
pickle.dump(clf, trained_clf)
trained_clf.close()
(snip)
exercise_02_sentiment.py
(snip)
    import pickle

    trained_clf = open(sys.argv[2], "bw")
    pickle.dump(text_clf, trained_clf)
    trained_clf.close()
(snip)

新たに作成するプログラム

次に学習済みモデルを利用するプログラムです。

exercise_03_simple_CLI_tool.py
#-*- coding: utf-8 -*-

import argparse

# ロードするインスタンスが利用するモジュールをインポートしておく
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import perceptron
from sklearn.pipeline import Pipeline
from sklearn.datasets import load_files
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.svm import LinearSVC

# cpickleがあればインポート、なければpickleをインポート
try:
    import cpickle as pickle
except:
    import pickle

def main():

    # argparseモジュールの設定
    parser = argparse.ArgumentParser(description="Detect language of input sentence. When it's English, also estimate the polarity.")
    parser.add_argument('--language-detector',dest='ex01_file' , help='pickle file which \
            is already trained model class.')
    parser.add_argument('--polarity-estimater',dest='ex02_file' ,  help='pickle file \
            which is already trained model class.')

    args = parser.parse_args()
    # インスタンスをロードする
    ex01_object = open(args.ex01_file, "rb")
    ex02_object = open(args.ex02_file, "rb")

    # インスタンスをロードする
    language_detector = pickle.load(ex01_object)
    polarity_estimater = pickle.load(ex02_object)

    ex01_object.close()
    ex02_object.close()

    # ユーザからの入力待ち
    sentence = input('Input sentence to detect lauguage and estimate polarity.:')

    target_languages = ['Arabic' ,'German' ,'English' ,'Spanish' ,'French' ,'Italian' ,'Japanese' ,'Dutch' ,'Polish' ,'Portuguese' ,'Russian']
    target_polarity = ['Negative ' ,'Positive ']

    # ユーザからの入力を解析し、結果を出力
    predict = language_detector.predict([sentence])
    if target_languages[predict[0]] == 'English':
        polarity = polarity_estimater.predict([sentence])
        print("{0}: {1}".format(sentence, target_languages[predict[0]]))
        print("polarity is {0}".format(target_polarity[polarity[0]]))
    else:
        print("{0}: {1}".format(sentence, target_languages[predict[0]]))

if __name__ == '__main__':
    main()

動作例

# helpの表示
MBP:TEST_scikit-learn user$ python exercise_03_simple_CLI_tool.py --help
usage: exercise_03_simple_CLI_tool.py [-h] [--language-detector EX01_FILE]
                                      [--polarity-estimater EX02_FILE]

Detect language of input sentence. When it's English, also estimate the
polarity.

optional arguments:
  -h, --help            show this help message and exit
  --language-detector EX01_FILE
                        pickle file which is already trained model class.
  --polarity-estimater EX02_FILE
                        pickle file which is already trained model class.

# exercise2で利用したposのテストデータから抜粋した一文
MBP:TEST_scikit-learn user$ python exercise_03_simple_CLI_tool.py --language-detector trained_clf1 --polarity-estimater trained_clf2
Input sentence to detect lauguage and estimate polarity.:a good movie allows its characters to learn and grow .
a good movie allows its characters to learn and grow .: English
polarity is Positive

# サンプル
MBP:TEST_scikit-learn user$ python exercise_03_simple_CLI_tool.py --language-detector trained_clf1 --polarity-estimater trained_clf2
Input sentence to detect lauguage and estimate polarity.:今日は天気がいい。
今日は天気がいい。: Japanese

MBP:TEST_scikit-learn user$ python exercise_03_simple_CLI_tool.py --language-detector trained_clf1 --polarity-estimater trained_clf2
Input sentence to detect lauguage and estimate polarity.:What's done is done.
What's done is done.: English
polarity is Negative

まとめ

以前pickleモジュールを勉強したときはいまいちピンとこなかったのですが、今回のように利用方法を知ると良さがわかって理解が進みました。今後の学習する際に役立ちそうです。

チュートリアルで扱わなかったモジュールを試してみたり、他のチュートリアルを触ってみたりしていきたいですね。kaggleに挑戦するのもいいかもしれないです。

参考

12.1. pickle — Python オブジェクトの直列化