【データコンペ】Signate 医学論文の自動仕分けチャレンジ
はじめに
昨年Signateで開催された医学論文の自動仕分けチャレンジに挑戦したので、その時に実施した内容を備忘録として記載します。
コンペの内容は、医学論文のタイトルと概要から、その論文がシステマティックレビューの対象となる論文かどうかを判別するというもの。英語の自然言語処理と、不均衡データ(システマティックレビューの対象は全体のうち非常に少ない)へのアプローチが必要になる。
最終結果は、60%ラインをギリギリ超える346位で、初めての分野の挑戦にもかかわらずランキングの半分以上に食い込めたので個人的には満足。
実行環境
- Python 3.9.0
実施
データの前処理から学習までの流れは以下の図の流れで実施した。一度モデル作成をした後に学習したモデルを用いた特徴量選択と、学習データのアンダーサンプリングを行い、再度学習したモデルを最終的なモデルとした。
前処理
前処理には、こちらの記事に記載した前処理のうち、いくつかの手法を利用している。
クリーニング
英文のクリーニング処理として、TextHeroを利用したクリーニング処理を行った。上記の記事でも取り上げたが、TextHeroは英文のクリーニングを簡単に実施してくれるため非常に便利。
特徴量作成と次元削減
特徴量作成では論文のタイトルと論文の概要に対して、それぞれ以下の表の手法を適応した。
特徴抽出手法 | 次元削減 | 次元数 |
---|---|---|
GoogleNewsで全ての単語をベクトル化し平均をとる | Umap | 10次元 |
FastTextで全ての単語をベクトル化し平均をとる | Umap | 10次元 |
TFIDF(sklearnのTfidfVectorizer を利用) |
主成分分析 | 64次元 |
単語の出現頻度のカウント(sklearnのCountVectorizer を利用) |
主成分分析 | 64次元 |
文章のベクトル化に関して、上位の解法ではBERTを利用しているものが多かったが、私の端末で実行したら2日かかっても処理が終わらなかったためBERTは利用していない。(性能の良いPCほしい)
特徴量を作成後、作成した特徴量に対してUmapや主成分分析を用いた次元削減を行った。次元削減手法にUmapか主成分分析のどちらを利用するかは特に根拠はなく、複数組み合わせて最も性能が良い手法を適応した。
特徴量作成と次元削減により、合計296個の特徴量が作成された。
モデル構築
今回はlightGBMでモデルを構築する。
初期モデル構築
作成した特徴量を全て利用しlightGBMで学習する。交差検証は、StratifiedKFoldを利用し学習データを3分割にしている。StratifiedKFoldは、目的変数のデータに不均衡がある場合に用いる分割手法で、目的変数の分布を維持したまま分割をするという手法である。そのため今回のタスクのような不均衡なデータでは、StratifiedKFoldを用いるのが適切らしい。
特徴量選択
学習が終了後、作成されたモデルの特徴量の重要度を可視化し、重要度が高い特徴量を確認する。lightGBMで学習した際のそれぞれの特徴量の重要度をグラフにしたものを以下に示す。
ほとんどの特徴量がベクトル化と次元削減された特徴量のため各カラムの意味は不明だが、これを基準に重要度が低い特徴量を削減していく。今回は298個の特徴量のうち、重要度の上位100個の特徴量を学習に利用する。
アンダーサンプリング
今回のデータは、正例の数が極めて少ない不均衡データが対象である。不均衡データの場合、データが偏っている方(今回であれば負例)に偏った出力をしてしまいがちである。そこで正例と負例を同じデータ数にすることで、データの偏りをなくすアンダーサンプリングを実施する。アンダーサンプリングはimblearn
ライブラリで以下のように実装できる。
pip install -U imbalanced-learn
train_x
が説明変数、train_y
を目的変数とすると、以下のように実装する。train_x
とtrain_y
のデータ数は同じである必要がある。
# アンダーサンプリング from imblearn.under_sampling import RandomUnderSampler X_resampled, y_resampled = RandomUnderSampler(random_state=123).fit_resample(train_x, train_y)
アンダーサンプリングを実施することで、元の偏った分布を同じ割合にすることができた。
再学習
アンダーサンプリングと特徴量選択を行ったデータで、再度lightGBMで学習を行う。1回目の学習と異なりデータを4分割して学習を行い、評価の際はそれぞれのモデルの出力の平均値をモデル全体の予測値とする。
学習したモデルの検証データに対するFbetaスコアは0.8449
であり、大体85%くらいの精度を確認できた。学習したモデルによる混合行列を見ても、検証用データに関してはかなり高い精度で分割ができたことが確認できる。
こちらで学習したモデルで提出したところ、最初に添付した順位の暫定評価0.806、最終評価0.841を得られた。
終わりに
自然言語処理には初めて触れたため結果は散々だったが、自然言語処理という分野について多くを学べる機会となった。これを機に今後は自然言語処理系のコンペにも挑戦していきたい。