<エムスリー Advent Calendar 2020 まで残り1日となりました。Advent Calendar本編に先んじて新卒1〜2年目メンバーが執筆します。>
エムスリーのエンジニアリンググループ AI・機械学習チームの李です。インターン累計2ヶ月+新卒入社8ヶ月にして初めての投稿になります。今回はキーフレーズ抽出アルゴリズムの1つであるEmbedRankを医療記事タグのスコアリングに使ってみた話を紹介したいと思います。
背景
エムスリーでは、ニュースや海外ジャーナルをはじめに、様々な自然言語ベースのコンテンツを取り扱っております。関連記事の表示などの応用先で素性として使われているのは、事前に用意した辞書から選ばれ記事に付与されたタグです。そのタグ付けの役目を担うのはGaussという基盤的なシステムです(Gaussについて紹介するブログはすでにあったのでここは詳細を割愛しますが、気になる方はこの記事をご参考ください)。
Gaussのタグ付け結果はエムスリー内で広く使われているのですが、いくつかの課題が残されています。その1つとして挙げられるのは、既存アルゴリズムによって付与された、タグと記事との関連度を表すスコアの一部は精度が低いかつ使い勝手が悪いという問題です。その理由は、Gaussは薬剤や大学などのタグタイプ(辞書にある単語のジャンル)に対してシンプルなキーワードマッチングをタグ付けアルゴリズムとして使っており、結果ほとんどのタグが同じスコアになってしまうからです。さらに、疾患などの一部タグタイプのスコアリングに機械学習モデルを使用しており、そのスコアの値は他のキーワードマッチングベースのタグスコアと直接に比較できず、スコアだけを使って複数タイプのタグを並び替えるのは難しいのです。
下記のテーブルに実際記事の一例です。この記事に「検査」タイプのタグ臨床検査
と「疾患」タイプのタグ嗅覚障害
や外傷
はGaussによって付与されますが、スコアリングには異なるアルゴリズムが用いられています。検査タグのスコアはキーワードマッチングで全部1になる一方、疾患タグは機械学習モデルによって1より小さい実数のスコアが付与されます。その結果外傷
と嗅覚障害
のスコアは意味のある比較ができるものの、嗅覚障害
と臨床検査
をスコアの値でランキングする場合は本文との関連度で行う場合と真っ逆の結果になるのです。
タイトル | 本文の抜粋 |
---|---|
喫煙と嗅覚障害に関連はあるか | 嗅覚の専門医療機関2施設の嗅覚喪失者3900例を対象に...嗅覚検査、検鼻法などの臨床検査で病因を特定し...現喫煙者は外傷後の嗅覚障害罹患率が高かったが... |
この課題を解決しようと、タグと記事主題の関連度を表すようなスコアリング手法を試みました。
EmbedRank
今回はこのスコアリング問題をキーフレーズ抽出タスクとして解きます。キーフレーズ抽出とは、記事の中から記事の特徴、主題を最も表せるプレーズの集合を選び出すタスクです。実際に使っていたEmbedRankと呼ばれるアルゴリズムは3つのステップから構成されています
- 一定のルールを従ってキーフレーズ候補を生成
- 自然言語処理でよく用いられるEmbeddingと呼ばれる手法を使って、同じモデルで記事とキーフレーズ候補をベクトルに変換(元論文ではsent2vecとdoc2vecを利用)
- キーフレーズ候補と記事ベクトルのコサイン類似度を測り、そのスコアでキーフレーズ候補にランク付けを行う
元論文のステップ1では、記事に対して形態素解析を行い、「名詞」と「形容詞+名詞」の組み合わせを候補としましたが、今回の目的はGuassのスコアリング結果の改善であるため、キーフレーズ候補にGaussのタグ付け結果を利用しました。
形態素解析で候補を選んだ場合は、この3つのステップだけだと似たようなフレーズに近いスコアが付けられてしまい、最終的に選ばれたキーフレーズ集合に多様性が欠けることになります。多様性を増やすために、Maximal
Marginal Relevance (MMR)と呼ばれる手法を利用し、フレーズ間の類似度も考慮しつつ記事とキーフレーズの類似度ベースの抽出方法を実現したのです。
Gaussの場合は元のEmbedRankほど重複な候補を生成することはないですが、同じ記事に2型糖尿病
や糖尿病
を付与してしまうケースが存在します。多様性考慮せずにスコアリングを行う時はこういうタグのスコアに差がつけにくいため、元論文と同様にMMR採用しました。
(ちなみにSansanさんもEmbedRankについてソースコード付きの解説記事を出しているので、ぜひそっちもチェックしてみてください)
実験結果
m3.comの2ヶ月分のニュースや海外ジャーナル記事とGaussのタグ付け結果を対象に、EmbedRankでタグのスコアリングを行い、その結果を定性的と定量的にGaussと比較してみました。
定性分析
まずは先ほどGaussの問題として挙げた例からEmbedRankの働きをみてみましょう。
例1
喫煙と嗅覚障害に関連はあるか
というタイトルの記事に、GaussはEmbedRankがそれぞれ各タグに付けたランクは下のテーブルで示した通りです。EmbedRankは見事に主題である嗅覚障害
を一位として選んだのです。
タグ | Gaussスコアの順位 | EmbedRankスコアの順位 |
---|---|---|
嗅覚障害 | 2 | 1 |
臨床検査 | 1 | 2 |
外傷 | 4 | 3 |
ウィルス感染症障害 | 3 | 4 |
例2
また、MRI標的生検と系統的生検併用で前立腺がんの検出増加
という記事では、EmbedRankは前立腺癌
を一位として選んだ上で、癌
もちゃんと3位(前立腺癌
と類似度が高い)まで落としています。MMRがうまく機能していることがわかります。
タグ | Gaussスコアの順位 | EmbedRankスコアの順位 |
---|---|---|
前立腺癌 | 2 | 1 |
内科一般 | 1 | 2 |
癌 | 3 | 3 |
例3
この記事の例ではGaussはタイトルに入った脳障害
を一番高いスコアを付けたに対して、EmbedRankは本文からより精確な疾患名「脳脊髄液減少症」の抽出に成功したのです。
タイトル | 本文の抜粋 | Gauss結果 | EmbedRank結果 |
---|---|---|---|
初診日不認定、支給ゼロも 交通事故で脳障害の男性 | 障害年金を申請しても...脳脊髄液減少症がある愛知県小牧市の男性... | 脳障害 | 脳脊髄液減少症 |
うまくいかなかった例
一方、Gaussの結果より劣化したケースも存在します。例えば単純性急性虫垂炎、手術と抗菌薬治療の長期QOL同等
という記事では、Gaussのキーワードマッチングスコアは急性虫垂炎
と抗菌薬
を同点にしたのに対して、EmbedRankはもっと記事の主題に近い急性虫垂炎
を抗菌薬
より低い点数を付けてしまったのです。
定量分析
まずはEmbedRankとGaussスコアの性質がどのくらい違うのかを測ってみました。一番高いスコアが付けられたタグをそのアルゴリズムが抽出した記事の主題タグとする場合に、EmbedRankは1743件記事中1137件でGaussと違う主題タグを選びました。両者の性質がかなり離れていることがわかりました。
さらにEmbedRankは主題タグ選びというタスクでGaussよりどのくらい優れている(劣っている)かを測りたいところですが、記事に主題タグを紐付ける正解データは実際に存在しないため(それもEmbedRankのような教師なしアルゴリズムを採用した原因ではあります)、精確な定量分析は難しいです。手動で正解データを作る方法も考えられるのですが、今回は擬似正解データでNormalized Discounted Cumulative Gain (NDCG)*1 でEmbedRankの結果をGaussの付けたスコアと比較してみました。
実際にどんな風に正解データを擬似したかというと、タイトルに入っているタグが主題タグである確率が高いことを仮定し、「主題タグ選ぶ」タスクを「タイトルに入ってるタグを当てる」タスクに変換するというちょっと乱暴なやり方でした。評価データの選択とNDCGの計算は下記のように行います
- タイトルにGaussタグが含まれているかつ複数のGaussタグがつけられている記事を評価データとして使い
- 文章のタイトルに含まれるタグの
y_true
を1に、他のタグのy_true
を0にする - アルゴリズム(EmbedRank/Gauss)によるづけられたスコアを
y_score
とし、y_true
とy_score
でその文章のNDCG*2 を計算する - 評価データの全ての文章の平均を取る
2ヶ月分のニュース記事に対してこの擬似NDCGを出した結果はこのようになりました。ここで1つ注意して欲しいのはGaussのアルゴリズムはタイトルも考慮し、タイトルに含まれたタグの重みを大きくしているのに対して、EmbedRankはタグと記事本文の類似度しか測っていないので、より厳しい条件で擬似評価タスクでいい結果を出したのです。
アルゴリズム | NDCF |
---|---|
EmbedRank | 0.404 |
Gauss | 0.392 |
結論
この記事ではEmbedRankを医療記事タグのスコアリングに適用してみた話を紹介さていただきました。定性と定量分析の結果からわかるように、タグタイプ別のスコアリングモデルが用いられ、タイプ間のスコアが直接比べられないGaussと反して、EmbedRankは全てのタイプに対して同じアルゴリズムを使うことでより使いやすいスコアを生成することに成功しました。またEmbeddingを利用することによって、より正確にタグと記事の関連度を測ることも可能にしました。
EmbedRankが発表された当時は、大規模の言語モデルによる転移学習はまだ今のように盛んでないのですが、元論文で使われていたdoc2vecをみんな大好きなBERT*3 に置き換えばさらにいい結果を得られるのではないかと思います。
We are hiring!
エムスリーでは新卒エンジニアの研修がないため、実際に稼働しているサービスの開発を通して実務中でキャッチアップしていく形になっていますが、チームメンバーの皆さんはとても手厚くサポートしてくださるので、個人的には効率よく勉強を進める方法だと感じています。
この記事で紹介させていただいたタグ付けを含め、自然言語処理が活躍できる場面はたくさんあるので、興味のある方はぜひ応募してみてください!