病みつきエンジニアブログ

機械学習、Python、Scala、JavaScript、などなど

教師なしLDAでTwitterのスパム判別をしてみる(予備実験編)

※普通は「教師なしLDA」という言い方はしないです

モチベーション

元々は、TwitterからURLつきのツイートを取りたかった。某ニュースアプリがTwitter上で(?)話題になっているニュース記事を(法的な是非があるとはいえ)配信しており、そんな感じのマイニングがしたかった。

ただ、普通に「http,https」でTwitter上で検索すると、量が膨大だった。加えて、ほとんどがスパム。なーにが「このサイトすごすぎwwwww」じゃ。

f:id:yamitzky:20140216225341p:plain

ということで、検索の段階でスパミーなキーワードを取り除き、純度の高いURL投稿マイニングをしたいわけだが、キーワードは既知なものには限らない。例えば「無料」とか「アフィリエイト」とかがスパムなのはそうなんだけど、「パズドラ」とか「魔法石」とか、未知のキーワードとか出てきた時に対応できない。

そこで、教師なし学習のアプローチを使って、スパムなキーワードを抽出する、ということを目的として、実験を行った。

モデル

モデルは、latent Dirichlet allocation(以下、LDA)[1]を使った。LDA自体の説明は、星の数ほどあるので、ここではほぼ行わない。

LDAでは、「文書には潜在的なトピックがある。潜在的なトピックは、単語を生成する」というような生成過程を踏む。逆に言うと、「ある文書に、ある単語が出やすいのは、そこに潜在的なトピックがあるからだ」とも言える。

具体的な例を出すと、「無料レポート:インフォゼロのアフィリエイトで月収40万円と月9万円の不労所得を構築した方法」というツイートは、その背後に「スパム」というトピックが存在するからだ、とする。逆に言うと、「スパム」というトピックを持つ文書は、「アフィリエイト」みたいな単語を生成しやすいはず。

ちなみに、LDAを使って得られるものは、簡潔に2つある。「文書ごとのトピック分布」と「トピックごとの単語分布」だ。

「とりあえずLDA」を使って学習してみて、スパムなトピックが学習できるか、そして、そのトピックから特徴的な単語を炙り出せるか、を確かめる。今回は予備実験として、トピックの出方を確認してみて、スパムなトピックが決定づけられそうかを見てみる。

前処理

各ツイートを、MeCabを使ったりして次のように単語分割した。

無料レポート:インフォゼロのアフィリエイトで月収40万円と月9万円の不労所得を構築した方法 http://t.co/****** #followmejp #goen

が元のツイートだとした場合、

無料 レポート : インフォゼロ の アフィリエイト で 月収 4 0 万 円 と 月 9 万 円 の 不労所得 を 構築 し た 方法 example.com #followmejp #goen

つまり、「通常の単語」+「URLを展開してドメイン部を取り出したもの」+「ハッシュタグ」を、文書=単語列とした(語順は関係ないのだが、先にURLとハッシュタグを除いてから形態素解析しているので、形態素解析が失敗している可能性あり)。

実験設定

プログラムは、自分で実装したLDA使ってもよかったんだけど、多分遅いので、GibbsLDA++を使った。実験設定は以下。

  • 文書数:50,919ぐらい
  • トピック数:100
  • 学習回数:20,000
  • α:50 / トピック数
  • β:0.1

注意点として、

  • トピック数は少なすぎるとうまくいかない
  • 学習回数は多すぎるかも(多すぎて困ることはない。perplexityの確認はしていない)
  • α、βはデフォルトのパラメータ

LDAとツイート収集以外のソースは、全てgithub上に置いた

実験結果

結果はgithub上に置いた。これは、トピックごとの単語分布\phiのうち、頻出上位30件を書いたもの。

多分、そもそもスパムが多すぎて、トピックがスパムばっかなんだけど、特徴的なものもいくつか。

例えば、30番目のトピックは、

で を 自動 ツイッター bit.ly フォロワー 方法 収入 万

ということで、スパムっぽいトピック。45番目とか51番目とかのトピックは、

に bit.ly 裏 と 無限 ワザ 4 手 アイテム 最強

~ bit.ly の を で た 報酬 ん アフィリエイト

と、bit.lyみたいな短縮URLは、スパムっぽい傾向があることがつかめる。

逆に、42番目のトピックを見ると、

bit.ly → 無料 プレ #ニュース ソチ 五輪 ( #スポーツ 「

と、ソチの話題にも関わらず、bit.lyとか、「無料」とか、キーワードの誤爆が出てきそう。

また、

まし fb.me 写真 し 投稿 新しい Facebook

(@ 4sq.com ) 店 pic ]: [ ))

 r.gnavi.co.jp   の … goo.gl  店 。 な : 味 ランチ

とか、ドメイン名とトピックが結構関係するというのも、狙い通り。

あと、意外だったのが、stopwordsがスパムトピックの上位に残ってしまっている。本来なら、stopwordのトピックが作られてほしかった。ここらへんは、ツイートという性質の問題かもしれない。

【追記】実験その2

コメント欄でid:Kesinにぐぅ正論なアドバイスをいただいたので、再実験した。

前処理として、語彙を「名詞(おそらく記号含む)」「動詞(原形)」とハッシュタグ、URLのみに制限した。すなわち、

無料レポート:インフォゼロのアフィリエイトで月収40万円と月9万円の不労所得を構築した方法 http://t.co/****** #followmejp #goen

が元のツイートだとした場合、

無料 レポート : インフォゼロ アフィリエイト 月収 4 0 万 円 月 9 万 円 不労所得 構築 する 方法 example.com #followmejp #goen

となる。

【追記】実験結果その2

結果はgithub上に置いた

登録 ポイント 獲得 中 小遣い ギフト 券 キャンペーン

] [ 楽天 a.r10.to #RakutenIchiba ゚ 送料 #ダイエット

♡ bit.ly 女性 完全 , 4 限定 友達 ここ 今

する フォロー 方法 ツイッター bit.ly アカウント 自動 つぶやき

ここらへんなど、スパムっぽいトピックは同様に出現している。特に顕著なのが、定性的な解釈がしやすくなったことだ。マイニングで定性的に確認したいという場合は特に、ちゃんとstopwordsが取り除かれるようにしたほうがいいかもしれない。

ただ、単語分布を素性として扱うと考えると、どっちがいいのかは今のところわからないので、後々の検証の余地がある。

結論

以上から、スパムなトピックは学習できてるっぽい(ここはそんなにかっちりした結論はいらない)。

Future work

今後やろうと考えているのは、

  • ツイートのスパム分類(寄り道)
  • スパムキーワードの学習(本丸)

あとは、biterm topic model[2]みたいな、短文向けのトピックモデルも提案されているので(※読んだことない)、こちらを使ってみるのも面白いかもしれない(けど、あまり興味ないので、誰か!)

モチベーション2

ビジネス的要件で、何かを判別しましょう、機械学習しましょう、とすると、結構教師あり学習でーSVMでーみたいな流れになるような気がする。もしくはRandom Forestでー、みたいな。

この理由は、使いやすくて、使われてきたから、だと思う(違ったらごめんなさい)。

でも、LDAみたいな教師なし学習・生成モデルも結構簡単に実験できる。ので、カジュアルに使ってみても面白いんじゃないかなーと思ったり。

参考文献

  • [1] Blei, David M., Andrew Y. Ng, and Michael I. Jordan. "Latent dirichlet allocation." the Journal of machine Learning research 3 (2003): 993-1022.(PDF)
  • [2] Yan, Xiaohui, et al. "A biterm topic model for short texts." Proceedings of the 22nd international conference on World Wide Web. International World Wide Web Conferences Steering Committee, 2013.(PDF)