SIGNATEのCompetitionに挑戦してみた

前回、KaggleのCompetitionに参加してみました。関連する情報を調べてみると、日本でも同様のコンペを実施しているサイトがあったので、試しに挑戦してみました。

こちらは、Kaggleと違い日本語なのでとっつきやすいことと、参加人数が少ないので、(もしかしたら)入賞しやすいかもしれません。まあ、入賞はともかく、学習目的と考えれば「日本語である」ことは大きなメリットですね。

ただ、KaggleのCodeに当たるような「他の人からの学び」はありません。また実行環境も用意されていないので、Google Coraboratoryなどを使う必要があります。

【練習問題】スパムメール分類

チュートリアル

今回は、練習問題のスパムメール分類にチャレンジします。練習問題にはチュートリアルがありますので、まずはそれを確認します。

データの読み込み、前処理(小文字化、stopwordの除去)はそのまま流用します。

チュートリアルでは、2つのアルゴリズムを使って、スコアの良い方を選択するという方法をとっています。

# ナイーブベイズ分類器のなかで2種類のアルゴリズムを検証
gnb = GaussianNB()
mnb = MultinomialNB()

gnb.fit(X_train_array, y_train)
mnb.fit(X_train_array, y_train)

F1スコア精度を比較して、MultinomialNBを採用しています。

mnb_pred = mnb.predict(test_array)

最終的なMultinomialNBのスコアは、0.9447、GaussianNBは、0.9219だったそうです。

SVM

同じことをしても仕方がないので、SVMを試してみました。

from sklearn import svm

# SVMモデルのインスタンス化
model = svm.SVC(kernel='linear')  # カーネルは線形カーネルを使用

# モデルのトレーニング(トレーニングデータを使用して学習)
model.fit(X_train_array, y_train)

# testデータの予測
svm_pred = model.predict(test_array)

SVMのスコアは、0.9309896でした。 上の2つのアルゴリズムスコアのちょうど間になっていて、微妙な感じです。

チュートリアルの最後に以下のようなアドバイスがありました。

スパムメール分類モデルを作成しましたが、このチュートリアルから発展させていくには、

  • 語形だけが変化した同じ意味を持つ単語を統合する(ステミング)
  • 特徴量のスケールを変換する(tf-idf)

といった手法をヒントに分析を進めてみてください。
また自然言語処理以外の観点では、不均衡データですのspamデータのオーバーサンプリングなども試す価値がありそうです。

今回は、tf-idfを試してみたいと思います。

from sklearn.feature_extraction.text import TfidfVectorizer

# テキストデータをTF-IDFベクトル化
vectorizer = TfidfVectorizer()

X_train_vec = vectorizer.fit_transform(X_train.text_remove) # トレーニングデータで辞書を作成
X_test_vec = vectorizer.transform(test.text_remove) # テストデータも同じ辞書を使用してベクトル化

# SVMモデルのインスタンス化とトレーニング
svm_model = svm.SVC(kernel='linear')  # 線形カーネルを使用
svm_model.fit(X_train_vec, y_train)

# テストデータを使用して予測
y_pred = svm_model.predict(X_test_vec)

スコアは、0.9732201となり、かなり改善されました。

まとめ

日本語で説明がされているので、Kaggleよりもかなりハードルは低いです。練習問題もありますので、初学者も気軽に始められるかと思います。

また、過去のコンペを眺めてみると日本の課題を解決するためのコンペが数多く開催されているように思います。開催中のコンペは少ないのですが、引き続き面白そうなテーマをウォッチしていきたいと思います。