エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

記事へのタグ付けシステム"Gauss"の精度改善取り組み

はじめまして。エムスリーエンジニアリングG AI・機械学習チーム所属の田中といいます。本ブログ初投稿です。今回は自分が関わっている、Gaussと呼ばれる、記事へのタグ付けシステムに利用する機械学習モデルにおいて一定の精度改善ができたので、ご紹介させてもらおうかと思います。写真はここ最近食べた中で一番美味しかった焼肉ランチの写真です。麻布十番の商店街にある、おくむらというお店で食べました。

本文とは一切の関係がない牛タンと牛ハラミと牛カルビの画像

Gauss概要

Gaussの概要について説明します。本ブログでもインターンの方が過去に改善の紹介をしてくださっているため、そちらの記事もご紹介します。

www.m3tech.blog

紹介した記事中にもありますが、Gaussの概要についてここでも改めて説明させていただこうと思います。

f:id:r-t433102:20200928134735p:plain
Gaussのイメージ

まずシステム的な側面から説明させていただきます。 自然言語を含むコンテンツに対して、その文章情報から事前に用意したタグリストの中から複数選びタグを付与するシステムになります。 これは日次のバッチで動いています。前日に新たに追加、公開されたサイト内のコンテンツを取得し、タグを付与する機械学習モデルに入力し、タグを出力します。 日次のバッチによって動かしているので計算時間のかかるモデルでも許容されます。 タグの種類も豊富で、疾患や薬剤はもちろんのこと、地域や大学、研究会、学会名、人名などもあります。

次にそのアプリケーションについていくつか例をあげさせていただきます。 つけられたタグはコンテンツ情報を要約するような素性になり、エムスリーの運営するサイトであるm3.comにおける、関連記事の表出や、内部の広告システムなどに活用されています。 また疾患や薬剤の情報をユーザーのトレンドの分析にも活用しています。 例えばユーザー側のPVと、Gaussによって記事に付与されたタグを使って、ユーザー側に興味のあるタグを付与する、弊社内でMaxwellと呼んでいるシステムがあります。こちらもマーケティング情報やレコメンドに積極的に活用されていっています。 他にもGaussタグがつけられたコンテンツが一覧できるページを用意し、そのページに遷移できるエンティティリンクを埋め込むことで、興味のあるタグを軸にコンテンツ間の回遊をサポートするIsaacsというシステムも存在しています。 これらはAIチーム内のプロダクトですが、もちろんエムスリー内の他のチームにもPDCAの中で活用されていっています。 他方で、より活用してもらい、ユーザー体験の改善により貢献するには、タグ付けの精度が求められます。

機械学習におけるタグ付けの難しさ

私は、機械学習におけるタグ付けの難しさは、基本的にタグの種類の多さからくる教師データの生成の困難さにあると考えています。 用意されるタグリストは当然ビジネスにおいて活用されうるタグリストでないといけないため、仮にオープンソースでタグと記事のペアのデータセットがあったとしても、そのタグリストが必要要件にマッチしなければ使えるものではないと考えられます。また、ほとんどのケースでマッチしないでしょう。 したがってタグリストは自然と自前で新しく用意されるものになるわけですが、そうなるとどの記事の時にどのタグをつけるかという教師データも、自分たちで用意しなければなりません。 そしてタグリストは少ないものでも100は超え、記事は少なくとも数千、多い時は数万になります。真っ当に用意しようと思うと(タグリストの数)*(記事の数)だけチェックをせねばならず、開発の傍にこれをやるのは非常に厳しいです。 したがって、精度確認程度の教師ラベルは用意できても、学習に使えるほどの教師ラベルの生成は難しいと思われます。

この問題に対して、今回はキーワードマッチングのような簡単なタグ付けからスタートし、つけられたものをベースにLabel Spreadingを用いて更に改善する形で精度向上を目指すことにしました。

モデル概要

内容の知識前提として、ある程度機械学習に関して知識がある方を想定した書き方をしています。ただ、検索して上位をクリックすればおおよそ答えが得られるような簡単で有名なロジックのみで構成されています。

基本的なロジックは、先に述べた通り、キーワードマッチングでタグを擬似的に付与し、擬似タグ付けデータから学習し、かつ教師として与えられたラベルを修正するというものです。 教師データが少ない時に行う、いわゆるpseudo labelingと似た方法です。 記事にキーワードマッチングによりタグをつけ、その結果を教師データとしつつも、半教師あり学習、具体的にはLabel Spreadingを用いて更に補正することで改善を目指しました。 pseudo labelingとの差異は、pseudo labelingが教師データは多少なりともあるのに対し、今回は1つも教師データがないところから学習を行なっています。(差異を示すことで理解してもらえるようにする意図での記述であり、新規性を主張するわけではないです)

今回取り組んだモデルについて図に簡単な処理のフローを示します。 まず、キーワードマッチングにより擬似タグ付けデータを生成します。それとは別に特徴変換を行い、更に特徴抽出とコンテンツ抽出を擬似タグ付けデータから行います。 最終的に、特徴抽出後の特徴量と擬似タグ付けデータを入力にした、Label Spreadingによってタグ付け結果を出力します。

f:id:r-t433102:20200928075529p:plain
処理フロー

各処理については次から詳細を説明します。

キーワードマッチングによる擬似タグ付け

名前の通りではありますが、マッチするキーワードと、それに対応するタグを事前に用意し、そのキーワードが出現する記事には対応するタグをつけるようにします。 今回取り組んだタグの種類はm3.comで提供されている、医師の趣味やグルメ、投資など私生活などに関わるタグ(ライフスタイルタグと呼んでいます)です。 次のような対応表を事前に作っておき、擬似タグ付けを実現します。

キーワード タグ
SUV クルマ
軽自動車 クルマ
焼肉 グルメ
寿司 グルメ
賃貸 不動産
マンション 不動産

この方法ではFalse Positiveは確かに増えやすいため、それをより後段で是正していく形になります。 またこのペアは利用側であるビジネスサイドに用意していただきました。

特徴変換

今回は本文の自然言語情報のみ用いるものとし、TF-IDFを用いた特徴変換を行なっています。 TF-IDFの定義は数式では出しませんが、ざっくり説明すると、ある単語について、記事中の登場頻度と、他の記事への登場頻度の逆数をかけたものです。 記事によく登場する単語は重要なので重みをつけるものの、その単語があらゆる記事に出るようであればそれは助詞だったり代名詞だったりなどといった、トピックに関係なくよく出てくる単語であるため、そういった単語は重みを下げようという考え方を反映したスコアです。 各単語についてそれを計算し、それらを要素として並べたベクトルを得る処理になります。

TF-IDFの場合、のちに行う特徴抽出において、抽出された要素と実際の単語の紐付けがしやすいため、モデリング時のデバッグが行いやすいと考えています。 すなわち、特徴抽出時に正しそうな単語が選ばれているかを速やかに確認できるということです。 TF-IDFより性能が良い結果が数多く報告されている単語埋め込みを用いなかった理由は、上記のメリットが打ち消される点が、デバッグやテスト時に負荷が高くなるという悪影響を及ぼすと考えたためです。

特徴抽出とコンテンツ抽出

のちの半教師あり学習を効率的に行うため、また擬似タグ付けデータの妥当性を確認するため、特徴抽出を行います。 An Extensive Empirical Study of Feature Selection Metrics for Text Classification という論文を参考にしました。 この論文はタイトル通り特徴選択基準をテキスト分類タスクにおいて適用した場合の性能比較になります。

何を行なっているのか、何を行いたかったのかを簡単に説明します。

擬似タグ付けデータについて、ある1つのタグだけに着目し、付与の有無を各々Positive sample, Negative sampleと振り分けます。 Positive, Negativeのデータ集合に対し、特徴量ベクトル1つ1つの次元に対して、判別に寄与する次元であるかどうかを統計的に調べます。 最終的に判別に寄与する次元のみを残すことで特徴量抽出がなされます。 今回はTF-IDFタグの抽出に寄与するようなトークンを抽出できます。 なお、いろんな選択基準で特徴量抽出を行うクラスがscikit-learnにも実装されています。

実際にやりたいことは次元削減とそれに類するコンテンツ抽出です。 コンテンツ数が数千しかなく、後述の半教師あり学習において、サンプル数を上回る次元を特徴量に使うことになりうるため、線形回帰でないとはいえ特徴量が過完備な状況が生じえます。 これによって正しく学習できないことを杞憂して先に特徴量選択を行うことにしました。これについては特徴抽出がない場合との比較評価はしていません。

特徴抽出とセットで、コンテンツ抽出も行います。 特徴抽出後、そもそも特徴ベクトルのノルムが非常に小さくなってしまうコンテンツがあります。 これはそもそもそのタグに関係のない内容ばかりということになりますが、Negative sampleのほうが圧倒的に多い状態がほとんどですので、できれば全部は学習にいれたくありません。 特徴ベクトルのノルムが大きくなってもNegative sampleらしいコンテンツは残るようだったのでノルムが小さいコンテンツは弾くようにしました。

半教師あり学習(Label Spreading)

半教師あり学習は、ラベルを含む教師データとラベルがそもそもついていない教師なしデータを混ぜて教師あり学習と同じ学習ができる方法です。 今回は単に半教師あり学習の中に、教師データのラベルも修正する手法があるので、それを活用するためだけに半教師あり学習を選びました。 具体的にはscikit-learnにも実装されているLabelSpreadingを用いています。 この手法の詳細は、CAMLPというLabel Propagationの手法を発表されているyamaguchiyutoさんのブログ記事が詳しいのでそちらを参照されたいです。

また、キーワードマッチと大きく異なる点はタグの推論をやりなおしているため、上記のキーワードマッチの辞書に含まれないキーワードだけで構成された場合でもつけられるようになっている点です。

ここの実装の補足をいくつかします。 まずこの学習は各タグについて行うのでバイナリの判別機の学習を行うことになっています。これはタグ付けの問題が記事に複数のラベルがつくことが真であるマルチラベル問題であること、タグが追加されるたびに他のタグが影響を受けるのを好ましくないと考えられるためです。

また、システムの話になりますが、学習は日次のバッチごとにやり直します。 日次で、前日に追加されたコンテンツのみをタグ付与対象にすると最初の概要で述べていますが、実際には過去一定期間遡ってその間の全部のコンテンツをタグ付けに利用しています。 モデルを一度学習し、その学習済みモデルを使いまわして推論する方式にしなかったのは、過学習を回避できなかったためです。

結果

性能評価として、タグ付けされた結果のみをチェックし、Precisionだけ確認することにしました。 Recallも評価すべきですが、Recallの場合、本来つけるべきタグを決定してからでないと評価ができないため、コスト的に難しくなることが理由です。 また、タグ付けの活用は基本的に関連記事表出や、広告システムに使われることから、Precisionがよりユーザー体験に直結すると考えられます。Precisionが低いと間違ったコンテンツを表出させてしまうことが起きやすく、ユーザー体験を損ねかねません。 ですので、今回はPrecision重視とします。

対象記事数は131件であり、ベースラインとして一番最初のキーワードマッチでつけた結果と比較します。 記事とタグのペアのみで測っているため、記事数より多くの検証サンプルがあります。

f:id:r-t433102:20200928072953p:plain
つけられた全てのタグについて評価

(※注:ベースライン評価とこの手法の評価の間にタグを新規に追加しているために、検討手法の場合でタグ付与数が増えています。実際には推論結果もタグ付け結果に追加することによって増えているものもありますが、タグ付与数の増加はベースラインと検討手法の間で正しく比較できる値ではありません)

Precisionが52%から67%の改善でした。 一方でタグ付け結果には、特定の記事で数多くのタグがついてしまっているケースもあり(タグの特性に依存するもの、まとめ記事の存在など)、 また、ビジネスサイドからも記事ごとのTop5で、紐付けたいタグの数としては十分ではないのかと提案もあり、学習結果の推論時のラベル確率をスコアとしてTop5のみ抽出した結果を確認しました。 ベースライン手法でも単純なキーワードマッチではなくて、単語頻度と出現位置(タイトルに含まれるか否か、タイトルに含まれるとスコアが高い)による重み付けを行なっていたため、ベースラインではそちらをスコアとしTop5としました。

f:id:r-t433102:20200928073321p:plain
記事ごとのTop5の評価

よさそうです。悪いことやってないかこれって思っちゃうような数字なので本当に正しいのか逆に自信なくなってます。

なお、トレードオフの関係であるRecallについては、コストを理由にして評価していませんが、極端に下がっていないことは目視においては確認しています。

課題

課題としては、評価はタグごとに特に重みをつけない一般的な数値評価になっています。 一方でタグごとに、数多くのユーザーが興味を持ちやすさ、コンバージョンにつながりやすさの違いがあります。本来はそういったタグがより正しくついている方がサービス貢献としては重要になってくるので、そこの重みを考慮しての評価はしていませんでした。 よりサービスに直結した評価をするためにはタグごとに重みを考慮すべきと考えています。 またRecallが低いと、例えばコンテンツベースレコメンドに使った場合には機会損失に直結しうるので、いずれは評価すべきです。 他にも、動的につけるといったニーズを満たす場合に現状のシステムではクイックに切り替えできないため、過学習の問題をクリアして都度学習し直しているタグ付けモデルを学習済みモデルを活用する方針にできたらいいなと思っています。

We are hiring!

エムスリーでは、自然言語処理、推薦システム、画像認識などの機械学習技術を用いて、医療を前進させるプロダクトを開発するエンジニアを募集しています! 我こそは! という方はぜひ以下よりご応募ください!

jobs.m3.com