Kaggle Tweetコンペ振り返り - コンペ概要・BERTによるQ&Aアプローチについて

はじめに

本記事では2020年3月~6月にかけて開催され、約2200チームが参加したKaggleのコンペ Tweet Sentiment Extraction(通称Tweetコンペ)について、振り返りを兼ねてまとめたいと思います。

f:id:rishigami:20200616210732p:plain

 

コンペ概要

f:id:rishigami:20200616231427p:plain

Tweetと正解ラベルの例

まず初めに本コンペのポイントをいくつか挙げます 

  • Sentimentラベルの与えられたTweetから、そのSentimentに該当する箇所を抜き出す課題。
  • アノテーションの問題で正解ラベルにノイズが多く含まれており、noisy labelへの対処もポイントとなった。
  • BERTやRoBERTa等の言語モデルによるQuestion Answeringアプローチが解法として多く用いられた。

 1点目の課題設定についてですが、各ツイートにはneutral, positive, negativeのどれかがSentimentラベルとして付与されていて、それに該当する部分を特定する問題となっています。

2点目について、アノテーターによって抜き出された正解ラベルにはいい加減なものも多く、例えば単語の途中で途切れていたり、似たような内容でも抜き出された箇所が違っていることがあります。Trainデータのうちおよそ10%にはそのようなnoisyな正解ラベルが含まれていました。

正解ラベル例:

Tweet: Happy Mothers Day to all the Mommys.
Answer: Happy Mothers Day to all the Mommys.
Tweet: Happy Mothers Day! Same day, more chocolate
Answer: Happy Mo

 3点目について、BERTやRoBERTa等の言語モデルによって、SentimentをQuestionとして捉えてTweetから対応する箇所を答えるQuestion Answeringタスクとしてこの課題を解く取り組みがGMによるnotebookをはじめとして広く行われていました。

データ

データ数について

 Trainには約27000ツイート、Public Testには約3000ツイートが含まれていて、Private TestはPublicの3倍程度のデータが含まれています。各ツイートにはsentimentラベルとselected_text(正解ラベル)が設定されています。

Sentimentについて

Sentimentラベルはneutral, positive, negativeの3種類からなります。内訳は以下のようになっていて、neutralが多く存在していることが分かります。

f:id:rishigami:20200616192430p:plain

Trainに含まれるSentimentラベルの内訳

 出典:https://www.kaggle.com/tanulsingh077/twitter-sentiment-extaction-analysis-eda-and-model

 このneutralツイートですが、selected_textのほとんどが元のtweetそのままであることが多く、実は予測するのが非常に簡単です。実際、neutralの予測をtweetそのままにするだけでも(neutralに関しては)96.9%のスコアを出すことができます。したがってnegativeとpositiveをいかに上手く予測するかがポイントの一つになっていました。

元データについて

コンペの説明文に

In this competition we've extracted support phrases from Figure Eight's Data for Everyone platform. The dataset is titled Sentiment Analysis: Emotion in Text tweets with existing sentiment labels

とある通り、今回のデータはSentiment Analysis: Emotion in Text tweets with existing sentiment labelsという既存のデータセットを元に新規にラベル付けしたものです。

元のデータ数は40000件のツイートで、今回のコンペデータ数がtrainデータ27000+public testデータ3000+α(private)であることを考えるとそのほとんどがコンペデータとして使われていることが推測できます。したがってCode competitionでありながらPrivate dataの様子が多少分かるという状態になっています。

しかしながら、

  • 正解ラベルのselected_textは新規にラベル付けされたもの
  • コンペデータと元データではsentimentの付与のされ方が異なる

などの理由から完全なLeak状態にはなっておらず、Private dataにどのようなツイートが存在しているかなどの情報が分かる程度でした。

評価指標

評価指標はword-level Jaccard scoreで以下の式で表されます。

 \displaystyle J(A,B)=\frac{|A\cap B|} {|A\cup B|}

これは予測と正解の単語全体の中で共通の単語が占める割合を示しています。

具体的に考えてみます。

 だとすると、

  •  \displaystyle{|A\cup B|}:|pen, apple, banana, pinapple| = 4
  •  \displaystyle{|A\cap B|}:|pen, apple| = 2

となるのでこの場合のJaccard scoreは2/4=0.5となります。

コードで表すと以下のようになります。

def jaccard(str1, str2): 
    a = set(str1.lower().split()) 
    b = set(str2.lower().split())
    c = a.intersection(b)
    return float(len(c)) / (len(a) + len(b) - len(c))

このJaccard scoreをツイートごとに計算し、平均をとったものが最終的なスコアとなります。

BERTによるQ&Aアプローチ

Question Answeringについて

今回のコンペではGMによるnotebookをはじめとして、BERTRoBERTa等の言語モデルによるQuestion Answeringアプローチが数多く試みられていました。

Question Answeringタスクにおけるデータはテキスト質問文正解の3つからなります。例えば有名なデータセットであるSQuADではWikipediaの記事から質問の答えとなる部分を正解として抜き出すことが目的となっています。

本コンペにおけるアプローチ

今回のコンペでは、元のツイートがテキスト、sentimentが質問文、selected_textが正解にそれぞれ該当します。BERTによるQAアプローチでは1文目を質問文(sentiment)、2文目をテキスト(ツイート)としてinputとします。BERTの出力側のhead部分では正解となる箇所のStart indexとEnd indexをそれぞれ確率で予測します。そして最も確率の高くなったStartとEnd部分を抜き出すことで最終的な予測結果となります。

f:id:rishigami:20200616214334p:plain

BERTによるQAアプローチ

QAアプローチの課題

BERTによるQAアプローチではtokenizerで分割した単語をインプットとし、それに対してstartとendのindexを予測するため、予測する箇所によってはどうしてもselected_textと一致しなくなる場面が出てきます。

例えば、RoBERTaのtokenizerで"i'm so sad..."を分割すると"i/'m/so/sad/..."と分割されます。しかし、この場合selected_textが"sad."のようにsad+ピリオドが1つとなる時に上手く予測することができません。仮に"sad..."と予測できたとしてもピリオドの数が異なるためjaccard scoreは0となってしまうからです。

f:id:rishigami:20200616224634p:plain

tokenizerの問題点

このような課題やnoisy labelへの対処法として有効なpost-processing(通称magic)を見つけようとする試みが、コンペ終盤には盛り上がっていました

最後に

 本記事ではTweetコンペの振り返りということで、コンペの概要からBERTによるQ&Aアプローチまで簡単にまとめました。上位陣の解法を読む際などにお役立て頂ければと思います。