キーフレーズ抽出2019-04-02
サイボウズラボ 機械学習勉強会 2019-04-05
今までやってきたことを振り返ってから今の課題と曖昧検索の話をする
色々やってきたのを一旦振り返って整理する
KyTea
文字列の単語への分割を単語境界かどうかのポイントワイズ推定でやるシステム
nishio.iconは2015年1月ごろいじっていた
これを使ってキーフレーズの境界を推定できないかと考えた
2015/03/11
金曜日の機械学習勉強会、KyTeaを使ったキーフレーズ抽出について書いていたんだけど書いている最中にこれは係り受け解析をやるべきなのでは…という気持ちがヒシヒシと湧いてきた…
この後Kaggleが盛り上がって一旦ペンディング
2017年4月の振り返り
・MaCabの1単語単位ではないキーワード抽出がやりたくてKyTeaを試す
・KyTeaでキーワード抽出をしようとするアプローチは正しくなかった
→十分な学習データの用意に関する問題
・MeCabで形態素解析したものに対して、ルールベースで「単語を繋いだもの」もキーワードに追加する、とかがよかったのでは
・今やってる「MeCabで刻んでから極大部分単語列」はそれに近いアプローチ
極大部分単語列
極大部分文字列の考え方を文字の列ではなく単語の列に対して適用するアプローチ 極大部分文字列=部分文字列のうち、同じ出現回数でその文字列を包含する文字列が存在しないような文字列
繰り返し出現する部分文字列を抽出できるアルゴリズムがある
「N回以上出現する部分文字列全部」とかが効率的に取得できる
→キーフレーズは繰り返し出現する単語列なのでこれが使えるのでは?
nishio.icon2017年4月ごろやっていた
結果
確かに期待していた長い単語列は抽出できた
しかしそれ以外のものもたくさん抽出された
Active Learningで「キーフレーズっぽそうか」のフィルタを学習
2017年4月ごろの実験結果
スコア高い方(教師データを除く)
"生物学的"(37回, 88.0%) "合成阻害剤"(20回, 88.0%) "内側側頭葉"(28回, 88.0%)
スコア低い方
"れる(図"(5回, 14.7%) "した後"(6回, 14.4%) "した場合"(5回, 14.4%)
この後Deep Learning講座が盛り上がって一旦ペンディング
2017/5/1(月) 17:32
キーフレーズ抽出したものをScrapboxに入れる実験
書籍の各ページを対象オブジェクトとした実験のまとめ
・章見出しが頻出キーフレーズとして抽出されがち
・章見出しに含まれているキーフレーズが章とは違うところにまとまって出現している例があって、それは面白い
・連続したページに出現するのは1つにまとめてしまってもよいのかも
・リンクをクリックして対象オブジェクトのページにジャンプしても、本文を読めないのがイマイチ
・技術的には本文をそこに埋め込んでしまうとか、ページの画像を埋め込んでしまうとかはできるが、著作権的にNGだから公開できない
→自分が著作権を持っている「発表資料スライドPDF」で試すのは手
「連続したページに出現するのは1つにまとめる」
繰り返し出現することが自明なのであまり有用ではない(伏線)
単語分割
事前にMeCabで単語分割してた
空白を含んだキーフレーズをきちんと空白を復元できる形で処理することに泥臭さ
単語分割するアプローチがそもそも正しいのかという疑問が...
未知語の問題
言語モデルベースのトークナイザ
テキストの可逆分割
未知語の問題がなくなる
文法的な単語の概念は関係ない
接尾辞配列を使って上位100万の出現頻度の部分文字列を抽出してから語彙数を減らしていく
2018/12/18
文字種1700の「エンジニアの知的生産術」コーパスを突っ込んで10000に分けさせたところ「エンジニアの知的生産術」を一単位の塊として認識するなどしてて良い
しかし出てくるものは当然「その文章を表現することができる10000個のトークン」なので、そこから人間にとって興味深いキーフレーズをピックアップするのには一手間必要
出力例>に基づいて, 有効です, 貼ること, 部屋の片付け, 少なすぎる, 未経験の, コーディング, 監修, 縮, 史, ようやく, レーダーチャート, 連続, オランダ, 関係のありそうなものを近くに移動, を見比べ, トップダウン, 一次元の読書体験, ▁Bacon, 倍速く, 壁, 山, やさしい, リファクタリング, 写真, 手軽に, 技術評論社, 教授, 熟成させる, 抜, 章で見た, 表示するコード, SMART, まずすべて集める
この後、エンジニアの知的生産術の英語版を作り始めて一旦ペンディング
2019年4月(つまり今)
PositionRank(2017年の論文)
単語列をグラフにした上でGoogle PageRankアルゴリズムを掛ける
ここまでは先行研究のTextRank(2004年)と同じ
これに単語の出現位置に基づく修正を加えたらTF-IDFタイプのキーフレーズ抽出に勝ちました、という論文
なんでうまくいくのかがよくわからないのでTextRankから実装してみた
単語の隣接関係をもとにグラフを作成してpagerank
遷移確率のデンスな行列を作って固有値分解
1000頂点で1秒ちょいかかる(MacBook)
当然たくさんの単語と隣接する単語のRankが高くなるのでは?
→その通り、普通にやると「は」などが高くなってしまう
オリジナルの論文では名詞と形容詞以外をフィルタしている
TextRank: 複数単語キーフレーズは?
これは結局のところ「単語になんらかの方法でスコアをつける」手法
その「方法」にPageRankを使っている
では、複数単語からなるキーフレーズはどうやって見つけているのか?
スコア上位1/3をキーフレーズ候補とし、それが原文上で隣接していたら結合する
これはもっと工夫の余地がありそう...
例えば「リーン・スタートアップ」は中黒が記号であるため「リーン」と「スタートアップ」に分かれてしまうのだが、こういうのは中黒のスコアがどうであるかと無関係につないで良さそう
TextRank: 名詞に限定したら良い結果が出る?
ため、もの、よう、どこ、それ、場合...
頻出名詞がキーフレーズとして抽出されてる
ブラックリストに入れるのか?
っていうかIDF...
TextRankとTF-IDF
結局のところTextRankのすごいところは「処理対象文書以外に何もいらない」というところ
IDFの情報すらいらない
っていうけど名詞だけ抽出するのに言語固有の知識は使ってるじゃん...
kintoneやScrapbox的なユースケースだと高頻度語の情報を使うのは現実的に問題ではない
むしろ「他の文章の情報」や特にScrapboxだと「すでに人手でつけてあるキーフレーズの情報」を活用していきたい
インクリメンタルに改善していきたい
tfidfを使うアプローチ
フレーズのスコアを構成する各単語のTF-IDFの和とする手法
キーフレーズ候補としては最長名詞句だけを使う
平均8000語の長い文章に対してはよくなったが、平均134語の短い文章に対しては悪くなった
Scrapboxのリンクのユースケースだと:
つながらなくても未来につながる余地ができるので良い
つまり
リンクの参加者をNとしたら1/Nがスコアにかかる?
これはIDFとほぼ同じ考え、ただし単語のFrequencyではなくフレーズのFrequency
「遠く」の定義は?
Scrapbox上では既存のリンクで2ホップ先まではすでにリンク先として表示されている
そこに含まれない3ホップ以上先のページにリンクすることが好ましい
Scrapboxの場合はリンクの接続関係を元にページ間の距離が決まる
これはあらかじめコンテンツ間のリンクが人手で付与されているから
kintoneなどのユースケースではそうではない?
そうでもない
アプリ内の各レコードは「同一アプリ」かそうでないかで距離の差がある
階層的な構造を持っているデータは階層の包含関係をリンクとして距離が定まる
削ったもの
Scrapboxでも「他のプロジェクト」とか「新規に追加されたコンテンツ」とかは距離が∞
こういうものの間のリンクを発見できるシステムが良い?