テキスト分類問題その2 チュートリアル

はじめに

本チュートリアルでは「テキスト分類問題その2」コンペティションを題材にして、Pythonとscikit-learnを利用した分類器の実装方法を解説します。具体的には、Bag-of-featuresデータの読み込み方法と初歩的な分類器の学習手順を紹介します。なお、本チュートリアルでは学習手法の詳細には立ち入りません。

掲載コードは、Python2.7.8、scikit-learn 0.15NumPy 1.9.1SciPy 0.14.0で動作確認を行っております。scikit-learnのインストール方法は、Installing scikit-learn — scikit-learn 0.15.2 documentationを参照してください。

訓練データの読み込み

まずは、正解ラベルが与えられている「訓練データ」を読み込みます。本コンペティションで用いられているsvmlightフォーマットのデータは、scikit-learnのload_svmlight_fileにより読み込むことができます。コンペティションページより予測用データをダウンロードし、以下のコードを./text-classification-002/上で実行すると、Xに特徴量、yに正解ラベルが格納されます。

In [1]: import os
In [2]: from sklearn.datasets import load_svmlight_file
In [3]: DATA_TRAIN_PATH = 'data-train.dat'
In [4]: N_FEATURES = 1881
In [5]: X, y = load_svmlight_file(DATA_TRAIN_PATH, n_features=N_FEATURES, dtype=int, zero_based=True)

次に読み込んだデータを、分類器学習に用いるサンプル(X_train, y_train)と、分類器の評価に用いるサンプル(X_val, y_val)に分割します。分割には、train_test_splitが利用できます。

In [6]: from sklearn.cross_validation import train_test_split
In [7]: TEST_SIZE = 0.2
In [8]: RANDOM_STATE = 0
In [9]: X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=TEST_SIZE, random_state=RANDOM_STATE)

ここでは、全体の20%を評価用としています。以下のコードにより、167件のサンプルが133件(学習用)と34件(評価用)に分割されていることが確認できます。

In [10]: X.shape, y.shape
Out[10]: ((167, 1881), (167,))
In [11]: X_train.shape, y_train.shape
Out[11]: ((133, 1881), (133,))
In [12]: X_val.shape, y_val.shape
Out[12]: ((34, 1881), (34,))

ナイーブベイズ分類器の学習と評価

初歩的な分類器であるナイーブベイズ分類器の学習手順を紹介します。scikit-learnにはいくつかのナイーブベイズの実装がありますが、ここではMultinomialNBを用います。

以下のコードで、分類器の学習を実行できます。

In [13]: from sklearn.naive_bayes import MultinomialNB
In [14]: clf = MultinomialNB(alpha=1.0)
In [15]: clf.fit(X_train, y_train)
Out[15]: MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)

ここでは、分類器のパラメータをalpha=1.0に設定しています。

次に、評価用データを用いて、分類器の性能を確認します。まず、評価用データに対する予測結果を出力します。

In [16]: y_pred = clf.predict_proba(X_val)[:, 1]

ここでは、コンペティションで指定されている通り、「ラベルが1である確率」を出力しています。

コンペティションで採用されている評価指標 (Area under the ROC curve, AUC)により、性能を評価します。roc_auc_scoreを用います。

In [17]: from sklearn.metrics import roc_auc_score
In [18]: roc_auc_score(y_val, y_pred)
Out[18]: 0.74652777777777779

評価用データに対するAUCスコアを確認できました。次に、alphaの値を変えて新しい分類器を学習してみましょう。

In [19]: clf_new = MultinomialNB(alpha=0.1)
In [20]: clf_new.fit(X_train, y_train)
Out[20]: MultinomialNB(alpha=0.1, class_prior=None, fit_prior=True)
In [21]: y_pred_new = clf_new.predict_proba(X_val)[:, 1]
In [22]: roc_auc_score(y_val, y_pred_new)
Out[22]: 0.78819444444444442

alpha=0.1にするとAUCスコアが向上することを確認できました。

予測結果の提出

alpha=0.1を採用し、予測結果を提出しましょう。これまでは評価用のデータは学習に用いませんでしたが、提出時には全てのデータ(X, y)を用いて分類器を再度学習します。

In [23]: clf_submit = MultinomialNB(alpha=0.1)
In [24]: clf_submit.fit(X, y)
Out[24]: MultinomialNB(alpha=0.1, class_prior=None, fit_prior=True)

次に、学習した分類器を用いてテストデータに対する予測結果を出力します。まずは、テストデータを読み込みます。

In [25]: DATA_TEST_PATH = 'data-test.dat'
In [26]: X_test, y_test_dummy = load_svmlight_file(DATA_TEST_PATH, n_features=N_FEATURES, dtype=int, zero_based=True)

テストデータに対する予測を行い、結果を出力します。

In [27]: SUBMIT_PATH = 'sample-submission-basic.dat'
In [28]: y_submit = clf_submit.predict_proba(X_test)[:, 1]
In [29]: import numpy as np
In [30]: np.savetxt(SUBMIT_PATH, y_submit, fmt='%.10f')

コンペティションページにて、sample-submission-basic.datを提出しましょう。以上で、分類器の学習と予測結果の提出が完了しました。