教師なしLDAでTwitterのスパム判別をしてみる(予備実験編)
※普通は「教師なしLDA」という言い方はしないです
モチベーション
元々は、TwitterからURLつきのツイートを取りたかった。某ニュースアプリがTwitter上で(?)話題になっているニュース記事を(法的な是非があるとはいえ)配信しており、そんな感じのマイニングがしたかった。
ただ、普通に「http,https」でTwitter上で検索すると、量が膨大だった。加えて、ほとんどがスパム。なーにが「このサイトすごすぎwwwww」じゃ。
ということで、検索の段階でスパミーなキーワードを取り除き、純度の高い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上に置いた。これは、トピックごとの単語分布のうち、頻出上位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)