Graph Convolutionを自然言語処理に応用する Part5

piqcy
programming-soda
Published in
8 min readOct 6, 2018

Part5からは、実際に実験を行うことでGraph Convolutionが有効なシチュエーションを探っていきます。今回は実験内容と実験を行うための実装の紹介で、結果は次回以降となります。実験には学習も含め時間がかかるため、Part6はちょっと先になる予定です。ただ、実装していく中で得られたノウハウは本連載とは別の記事で出していければと思います。

さて、前回述べた通りGraph Convolutionを以下のように活用ができるとポイントが高いです。

  1. 言語モデルのような、教師なしのタスクに適用できる
  2. 教師なしの次点として、大規模なコーパスがあるタスク(翻訳など)に適用できる
  3. AutoEncoder/Encoder-Decoder的な機構により、潜在表現を得ることができる

そのため、この3点を確認するための実験を順に行っていきます。ここからは筋書きのないドラマなので、実験の結果役に立たなかった、ということもあり得ます。まずは、各点についてどのような実験を行うかを整理していきます。

実装、というと前のめりにコードを書いてしまいがちですが、事前に方針を立てておくことで無駄な実験や実装を行うリスクを避けることができます。なんだか上から目線に言っていますが、これは実際私がそうなったので自戒をこめてです。特に最近コードを実装してないな~というフラストレーションがたまっている場合顕著になるので、注意しましょう。

言語モデルへの適用検証

言語モデルへの適用検証は、最初にして難易度の高いタスクになります。大きな考慮点の一つが、隣接行列の構築です。言語モデルの場合バッチとして与えるデータはまとまった一文ではなく、途中で途切れている可能性があります(一定長のsequence lengthで切ってしまうため)。そのため半端な文を対象にParseすることとなり、依存関係の抽出が上手くいかない可能性があります。そのため、検証については以下3つの方法を試してみます。

  1. (不完全かもしれないが)Parseで隣接行列を作る
  2. Structured Sequence Modeling with Graph Convolutional Recurrent Networksを参考に、単語類似度で隣接行列を作る
  3. GLoMo: Unsupervisedly Learned Relational Graphs as Transferable Representationsを参考に、隣接行列を推定する

比較対象とするベースラインは、以下の2つです。

  1. LSTMベースの言語モデル
  2. LSTM + Attentionの言語モデル

1には勝てて当然、2に勝てなければ普通にAttentionすれば?という話になってしまうので、この辺りは大前提となります。

翻訳モデルへの適用検証

翻訳モデルについても、言語モデルとほぼ同等の設計で行います。言語モデルとの相違点は、翻訳の場合概ね完全な一文を入力とできる点です。ただ、その分長さを合わせるためのPaddingが入ることになり、隣接行列がSparseになる可能性が高くなります。

翻訳モデルについても、言語モデルと同様3つの隣接行列タイプで検証してみます。比較対象とするベースラインは、以下の2つです。

  1. Encoder-Decoderモデル
  2. Encoder-Decoder + Attentionモデル

こちらも、1には勝てて当然、2には(以下略)となります。

潜在表現の獲得

潜在表現の獲得実験では、既にグラフ構造を持ったデータを扱います。というのも、言語モデル、翻訳モデルの実験でグラフ構造を持っていない自然言語リソースに対する効果は測定できるためです。

知識グラフからの潜在表現の獲得には、 Modeling Relational Data with Graph Convolutional Networksを使用します。この論文ではノードの分類とエッジの推定を検証していますが、得られる「ノードの分散表現」が他の文書分類といったタスクに有効なのかは検証されていません。最も効果がわかりやすいのが、少ない情報からの文/文書分類です。以下は最近のスポーツニュースのタイトルですが、固有名詞が非常に多く普通に分類を行おうとすると未知語だらけになってしまうことがわかります。

  • 錦織圭が8歳年下の相手と戦いながら思い出したこと
  • 組織的な守備貫き、先制点狙え サンガ、7日に大分戦
  • 伊藤美誠「美誠パンチ」の誕生秘話語った

これは、Twitterなど短いSNSメッセージの分類についても同じことが言えます。ニュースのヘッドラインの分類、ツイートのトピック分類についてはデータセットがいくつかあるため(News Aggregator Data SetReal-Time Classification of Twitter Trends — Datasetなど)、その分類精度を検証してみます。

ベースラインとなるのは、もちろん単語分散表現です。知識グラフには一般的な単語はあまり含まれていないため、単語分散表現vs知識グラフ表現ではなく、単語分散表現を知識グラフ表現でどれだけブーストできるかを検証してみます。

  • Word Embeddingのみ
  • Word Embedding + Knowledge Graph Representation

以上が、実験項目になります。

実験の準備

実際にGraph Convolutionを実装するというお楽しみに入るまでには、以下の長い過程があります。

  • データセットの準備
  • 前処理の実装
  • ベースラインモデルの実装とテスト

これらを経て、ようやく実装にたどり着けます。データセットの準備と前処理の実装については、なんども同じ実装をしていると心が折れるため汎用的なツールをすでに作成/公開しています。

データセットのダウンロードツール: chazutsu

chazutsuを利用することで、例えば著名な感情分類のデータセットであるIMDBを以下のようにダウンローすることが可能です。詳細は、こちらの記事を参照してください。

import chazutsu
r = chazutsu.datasets.IMDB().download()
r.train_data().head(5)

前処理の実装ツール: chariot

chariotは、自然言語処理の前処理を簡単に実装できるツールです。以下は「ユニコード正規化して、トークナイズして、ストップワードを除去したうえで、語彙を構築」という処理をひとまとめにしたものです。

from sklearn.externals import joblib
import chariot.transformer as ct
from chariot.preprocessor import Preprocessor
preprocessor = Preprocessor(
text_transformers=[ct.text.UnicodeNormalizer()],
tokenizer=ct.Tokenizer("en"),
token_transformers=[ct.token.StopwordFilter("en")],
vocabulary=ct.Vocabulary())
preprocessor.fit(your_dataset) # Train
joblib.dump(preprocessor, "preprocessor.pkl") # Save
preprocessor = joblib.load("preprocessor.pkl") # Load

ポイントとしては、処理をSave/Loadできる点です。これで前処理を1ファイルに固めておくことができ、デプロイなども容易になります。chariotはまだ開発中ですが、年内には正式にリリースする予定です(多分)。デモのJupyter Notebookを作成しているため、ぜひフィードバックを頂ければと思います。

現在、以下の開発を進めています。

  • chazutsuによる検証用データセットのサポート(言語モデルはサポート済みなので、翻訳と知識ベース)
  • chariotによる、言語モデル用前処理のサポート
  • ベースラインの実装

ベースラインの実装については、以下のリポジトリで行っています。

実験準備を通じて得られたノウハウについては、Graph Convolutionシリーズとは別の記事でその内容を紹介したいと思います。その後、いよいよGraph Convolutionを使用した実装と実験に取り掛かっていきます。

--

--

piqcy
programming-soda

All change is not growth, as all movement is not forward. Ellen Glasgow