こんにちは、3月よりファンコミュニケーションズでインターンをしている@ohmurakenです。 このエントリーでは、僕がインターンで行ったWebページの分類について書こうと思います。
なんで分類するの?
ファンコミュニケーションズが運営するスマホアドネットワーク nendでは日々大量のサイトから広告リクエストが送られてきます。広告を配信する際には、サイトの内容を考慮し、最適な広告を選ぶ事が重要です。しかし、サイトの内容を人がいちいちブラウザで確認し、分類していては日が暮れてしまいます。そこで、自動でサイトの内容を調べ分類するシステムが必要となります。nendのサイトを以下のタグのどれかに分類する事を目指します。
- two: 2chまとめ系のサイトなど
- game: ゲームの攻略サイトなど
- anime: アニメや漫画のサイトなど
- others: 上記のいずれにも属さないサイト
どうやって分類するの?
サイトには以下のような情報があります。
- 画像
- 動画
- テキスト(文字)
- SNS情報
- リンク
今回は特にテキストに注目して、分類する方法を考えていきます。テキストの取得から分類まで流れはこんな感じです。
- 登録されたURLのbodyタグ内のテキストを取得
- テキストから名詞を抽出
- 各URLに教師となるタグを人力でつける
- 各タグ内での単語の重みをきめる
- 重みに従って分類
1.登録されたサイトのbodyタグ内のテキストを取得
今回はPythonを使ってクローリングします。Pythonにはurllibや
Beautiful Soupといったクローリングに便利なライブラリがあります。
2.テキストから名詞を抽出
テキストが取れたので、MeCabを使って形態素解析をして名詞のみ抽出します。MeCabにはデフォルトでipadicという辞書が入っており、それを使って形態素解析をします。しかし、nendはネット用語といった新語が入ったサイトが大量にあるので、ipadicでは対応できません。そこで新語に対応したmecab-ipadic-NEologdという辞書を使います。
上の画像は「中二病」という単語をipadicとipadic-NEologdで形態素解析した結果です。ipadic-NEologdでは「中二病」が1つの単語として解析されている事がわかります。
3.各URLに教師となるタグを人力でつける
人力で1つ1つのサイトをブラウザで開いて教師タグを付けます。今回のインターンでは約5000件のサイトにタグを付けました。作業を簡単にするスクリプトを書いて、効率よくタグを付ける事をおすすめします。
4.各タグ内での単語の重みをきめる
サイトと単語(名詞)と教師タグが揃ったので各タグ内でどんな名詞が重要なのかを調べます。重み付けにはTF-IDFという手法を使いました。TF-IDFは、TFとIDFという2つの値を使ってある文書jでのある単語iの重みを定義する事ができます。以下に式の詳細を書きます。
「よくわからん」という方はある文書でよく出てくるけど、ほかの文書ではあまり出てこないと、その単語は重要という風に認識して貰えると良いです。今回はあるタグでよく出てくるけど、ほかのタグではあまり出てこないと、その単語は重要という風に考えてTF-IDFを使ってみます。
5.重みに従って分類
タグ毎の単語の重み付けができたら、任意のサイトに対して前述のようにクローリングをし、単語(名詞)を抽出して、各タグの毎のTF-IDFの合計スコアを求めます。そして、スコアが最も高かったTF-IDFのタグを付けます。
TF-IDFをやってみた
実際に2015年11月にnendに登録されたクリック数上位1000件のURLを使ってTF-IDFを使います。 各タグのTF-IDFが特に高かった単語をまとめました。
animeやgameの単語には時期が反映されているように見えませんが、twoは反映されています。「(ダメな私に恋してください)」は2015年11月にドラマ化発表されました。「侍ジャパン」は2015年11月に世界野球WBSCプレミア12が開催されたました。「クリス松村」は2015年11月に海老名市の市議会議員がセクシャルマイノリティへの差別発言に抗議した影響です。「決勝進出」は2015年11月にM1グランプリの決勝進出者が決まりました。
そして分類してみた
各タグの単語毎のTF-IDFが決まったので、任意のサイトが入力されてもTF-IDFにしたがって分類する事ができます。検証には以下のデータを使いました。 上位1000件のURLは異なる月でも重複している事が多いので、2000-3000位のURLも試してみました。
- 2015年10月 クリック数上位2000-3000位の500URL
- 2015年12月 クリック数上位1000位の500URL
- 2016年 2月 クリック数上位2000-3000位の500URL
two, game, othersについては約70~85%の精度で分類できました。animeの精度が低かった理由としては、純粋なanimeのサイトがそもそも少ない事と、animeのサイトは画像や動画が中心であり、テキストに注目した今回の手法では効果を発揮しにくい事が挙げられます。animeタグのようなテキスト以外の特徴をもつサイトについては、別の手法でアプローチする必要があります。
まとめ
今回はサイトのURLから自分でデータを抽出し、特徴(重み付け)を決めるという一連の流れを体験できました。一方で分類のためには、欠損値の除去やデータの正規化などが作業の大半を占めてしまいました。こういった前処理にもう少し慣れていれば異なる手法での性能比較や、より細かい重み付けができたのではないかと思っています。機会があればナイーブベイズ分類器による分類も試してみたいです。ではでは。