ロイターコーパスを使った文書分類(4)|主成分分析後のデータでの分類

前回

の続きです.

準備

bag-of-wordsにより,1つの文書を6459次元ベクトルで表しましたが,これからはデータを視ながら実験をしたいので, 主成分分析によってそれぞれを2次元ベクトルに変換したデータを使います. トレーニングデータ,テストデータをそれぞれ以下の手順でpickleモジュールにしておきます. (get_vocaburary, features, pca_return_matrixは,今までに作成した関数です.)

class1, class2 = "ship", "wheat"
train_fileids = [(fileid, 1) for fileid in reuters.fileids(categories=class1) if "train" in fileid] \
                + [(fileid, 0) for fileid in reuters.fileids(categories=class2) if "train" in fileid]
test_fileids = [(fileid, 1) for fileid in reuters.fileids(categories=class1) if "test" in fileid] \
               + [(fileid, 0) for fileid in reuters.fileids(categories=class2) if "test" in fileid]

V = get_vocaburary([reuters.words(fileid) for fileid, labels in train_fileids])
train_data = [(np.array(features(reuters.words(fileid), V), dtype=float), label) for fileid, label in train_fileids]
test_data = [(np.array(features(reuters.words(fileid), V), dtype=float), label) for fileid, label in test_fileids]
X = np.array([vector for vector, label in train_data])
B = pca_return_matrix(X)
train_data = [(B.dot(vector), label) for vector, label in train_data]
test_data = [(B.dot(vector), label) for vector, label in test_data]
pickle.dump(train_data, open("train_dim2.pickle", "wb"))
pickle.dump(test_data, open("test_dim2.pickle", "wb"))

実験

さて,これでトレーニングデータとテストデータはそれぞれ2次元ベクトルの集合となりました. ここで前回

で,行った代表ベクトルを用いた方法で分類してみます.結果は期待できませんが.

train = pickle.load(open("ship_wheat/train_dim2.pickle"))
x0 = np.array([vector for vector, label in train if label == 0])
x1 = np.array([vector for vector, label in train if label == 1])
mu0 = x0.mean(axis=0)
mu1 = x1.mean(axis=0)

test = pickle.load(open("ship_wheat/test_dim2.pickle"))
labels = [label for vector, label in test]
def predict(x): # using euclidean distance
    if (x-mu0).dot(x-mu0) < (x-mu1).dot(x-mu1):
        return 0
    return 1
predicted = [predict(x) for x, label in test]
print predicted
print labels

print "accuracy:", accuracy(predicted, labels)
print "F measure:", F_measure(predicted, labels)

結果は以下のようになりました.

[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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]
accuracy: 0.50625
F measure: 0.521212121212

これには驚きました.前回,ただのbag-of-wordsで同じ実験をしたとき精度は0.45, F値は 0.02 でした.
それが,PCAで次元削減をするだけで,精度 0.51 ,F値 0.52 まで向上したのです.

Summary

今回は,bag-of-wordsで作成したベクトルを,主成分分析により2次元に圧縮し,それを代表ベクトルのみを使うという非常にシンプルな方法で分類する実験を行った. 結果は驚くべきもので,精度 0.51 ,F値 0.52 となった. 次元を削減するだけで,これほど効果があるのかと,正直驚いた. ここで作成した2次元データは今後も使って行く予定. (補足)ひょっとして,前回コサイン類似度を用いていたが,そこをユークリッド距離に変えてしまったことに起因するかもしれないと思い, 前回のスクリプトを書き直して検証してみたが,やはりユークリッド距離を使ってもF値,精度は変わらなかった.

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中