ホーム
企業情報
テックレポート - TechReport
テックレポート詳細
テックレポート - TechReport
ツイートから好みのタイプの女の子を見つけるセンチメント分析とDeep Learning 2014年6月
執筆者
- 執筆者:
- 斉藤広和
- 所属部署:
- 株式会社WAVEST メイクme
- 業務経歴:
- 2012年株式会社サイバーエージェント入社。現在、子会社WAVESTにてJCJK向けメイクと自撮りの研究サービス「メイクme」のシステム責任者を担当。主にサーバサイドを担当しています。
概要
膨大なツイートから好みの女の子を見つけたいです。
好きな女の子のタイプのキーワードを入力すると、該当するアカウントを出力するステキなシステムを作ります。
作成したコードやデータはこちら
https://github.com/inkenkun/tech_twitter
目次
1. 女の子だけのアカウントを取得したい
Twitterには性別という属性がないため、まずは女の子のアカウントを何とかして大量に取得してこなければなりません。
おっさんとマッチングされても困りますからね。
1-2. 女性単語辞書を作る。
確実にこれは女性だってわかるアカウントを30個ほど目視で取得します。
そして抽出した女性アカウントのツイートを最新200件ずつ取ってきます。
RTツイートとbotは含めません。
Twitterで女性がよく使う言葉を取得するために、抽出したツイートから単語辞書を作成します。
女性アカウントのツイートを取得する際に、mecabで分かち書きし、女性単語辞書テーブルに、単語と使用頻度を突っ込みます。
この時、ノイズを減らすために名詞と動詞と副詞だけを引っ張ってきます。
今回は女性単語辞書テーブルに入れた単語6526単語のうち90パーセンタイルを使用することにしました。
作成したデータは以下の通りです。
girls
女性マスタ
|
id |
username |
create_at |
|---|---|---|
|
1 |
06031111 |
2014-06-11 00:00:00 |
|
2 |
lopipa_yu |
2014-06-11 00:00:00 |
| 3 | rinamoiin | 2014-06-11 00:00:00 |
girls_timeline
女性アカウントのタイムライン
|
id |
tweet_id
|
username |
body
|
wakachi
|
create_at |
|---|---|---|---|---|---|
| ツイートID | アカウント名 | 本文 | スペース区切りの分かち書き | ツイート日 | |
|
1 |
477237122873581600 |
06031111 |
ATSUSHI のライブまでもう少し♪ 超楽しみ *´∀` 次の日仕事っていうの忘れて楽しむぞぉ♪ | ATSUSHI の ライブ まで もう少し ♪ 超 楽しみ *´∀` 次 の 日 仕事 っていう の 忘れ て 楽し むぞぉ ♪ |
2014-05-22 04:08:32 |
|
2 |
474849506740011000 |
0607OOO |
call Me! 行きたいなあ~ | call Me ! 行き たい なあ ~ |
2014-06-14 04:02:50 |
| 3 | 477652593670250500 | yuinosuke_m | ディズニーランド入園制限かかっておる T ^ T | ディズニーランド 入園 制限 かかっ て おる T ^ T | 2014-06-14 21:23:47 |
girls_word
女性単語辞書
|
id |
word |
hindo |
|---|---|---|
| 単語 | 出力頻度 | |
|
1 |
iLoveMusic |
1 |
|
2 |
人気 |
6 |
| 3 | 最新 | 1 |
| 4 | 聴き | 1 |
| 5 | 放題 | 2 |
girls_timeline_word
girls_timelineとgirls_wordをひもづけるテーブル
|
id |
t_id |
w_id |
|---|---|---|
| girls_timeline.id | girls_word.id | |
|
1 |
1 |
7 |
|
2 |
1 |
8 |
| 3 | 1 | 9 |
1-3. 女性ツイートの特徴を抽出する
girls_timeline_wordテーブルを元に、女性ツイートの教師コーパス「女性教師コーパス」というのを作成します。
この女性教師コーパスとは、簡単に言うとツイートとそのツイートに出てくる単語と頻度を紐付けたものです。
ただこのままだと、単語データが多すぎるので、pythonで特徴の次元削減(LSI)します。
今回は20トピックに指定しました。
次元削減とは、すごいおおざっぱに言うと、女性ツイートから抽出した6千個の単語を、出現頻度を元に20個にまとめたって感じです。
1ツイートに対して、その20個の特徴がどれだけあるかを数値化したのがコーパスです。
例えばこんな感じ
|
id |
tweet_id |
is_female |
v0
|
v1
|
v2
|
v3
|
v4
|
v5
|
v6
|
v7
|
v8
|
v9
|
v10
|
v11
|
v12
|
v13
|
v14
|
v15
|
v16
|
v17
|
v18
|
v19
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
1 |
468420336761860100 |
1 |
-0.995848 | 0.000914188 | 0.0897001 | 0.0127015 | -0.00662591 | -0.00121336 | 0.00425892 | -0.00216391 | 0.00110394 | 0.000506512 | 0.00221946 | -0.000934771 | 0.000263865 | -0.00118693 | 0.000410661 | 0.000194178 | -0.000548632 | -0.000109973 | -0.000112813 | -0.000932135 |
|
2 |
473730479607148540 |
1 |
-0.683974 | 0.726128 | 0.0452496 | 0.0457684 | -0.015661 | -0.00130161 | 0.0185422 | -0.00396264 | 0.00343795 | -0.00985174 | 0.00552777 | -0.00364097 | -0.00112312 | -0.00156012 | -0.00186006 | -0.000224107 | -0.00226358 | -0.00152444 | 0.00109055 | -0.000144751 |
上のコーパスの作成はPythonのGenshimで行います。
GenshimはLSIやLDAなどを用いた次元圧縮を簡単に行えるので便利です。(girls.py)
1-4. 女性以外のツイートの特徴を抽出する
女性特定するために、女性以外のデータも必要になるので、抽出していきます。やり方は1-3と同じ。(get_other.js)
男性や広告など、女性以外のツイートの特徴を抽出するために、1-2 , 1-3同様、女性以外だってわかるアカウントを目視で30個ほど抽出し、女性以外単語辞書を作り、「女性以外教師コーパス」を作ります。(others.py)
1-5. 女性かどうかを検証したいツイートを引っ張ってくる
twitterからlang:ja のツイートを30万件ほど引っ張ってきます。(get_all_timeline.js)
取得したツイートと女性単語辞書を組み合わせた「男女不明コーパス」を作ります。
これが検証したいコーパスとなります。(unknowns.py)
1-6. 性別判定する
Weka Toolkitで女性予測をします。
前処理として、「女性教師コーパス」と「女性以外コーパス」を読み込ませます。
予測するための決定木のアルゴリズムの精度を調べるために、J48、Naive Bayes、RandomForestの3つを試してみます。
それぞれ交差検証での精度は以下の通りです。
J48: 99.735%
Naive Bayes: 69.28%

RandomForest: 99.8896%
J48も99.735といい数字を出してますが、RandomForestの99.8896% はかなり驚異的な精度です。
この結果、RandomForestで女性判定を行うことにしました。
「男女不明コーパス」をWekaに入れて、女性のツイートかそうじゃないかを予測します。
取得したツイートの「60%以上が女性ツイートと判断されたアカウント」を女性としました。
女の子と判断されたアカウントリストをforecastテーブルに格納し、forecastテーブルとuser_timelineテーブルからSQLでladyテーブルを作成します。(forecast.py)
forecast
女の子予測テンポラリテーブル
|
id
|
is_female |
is_female_text |
tweet_id |
|---|---|---|---|
| 女の子か | 女の子の文章か | ツイートID | |
| 1 |
1 |
True |
477677782244147200 |
| 2 |
1 |
True |
477677786736242688 |
| 3 | 1 | True | 477677800942346240 |
lady
多分女の子だよアカウント
|
username |
tweet_num |
feminin_point |
|---|---|---|
| アカウント名 | ツイート回数 | 女の子ポイント |
|
yuya9cirno |
5 |
3 |
|
rinriiiine |
5 |
3 |
| cocotanz32hnnn | 5 | 3 |
これで機械的に女の子と判断されたアカウントリストを生成することが出来ました。
2. マイナス思考な女の子はタイプから外したい
女の子に限らず男でもマイナス思考な人は嫌ですよね。
できればそういう子は除外したいわけです。
そこで感情を判断できるセンチメント分析です。
センチメント分析を用いると、ある文章がポジティブなのか、ネガティブなのか、中立なのかを判断することができます。
2-1. ポジネガを判定するセンチメント分析
女の子のツイート内容からどういった感情(ポジティブなのかネガティブなのか)を判断します。
解析器にはzunda https://code.google.com/p/zunda/ を使います。
zundaは
| 時制 | 未来、非未来 |
|---|---|
| 仮想 | 条件、帰結、0 |
| 態度 | 叙述、意志、欲求、働きかけ-直接、働きかけ-間接、働きかけ-勧誘、欲求、問いかけ |
| 真偽判断 | 成立、不成立、不成立から成立、成立から不成立、高確率、低確率、低確率から高確率、高確率から低確率、0 |
| 価値判断 | ポジティブ、ネガティブ、0 |
を判断してくれます。
例えば、「今日はラーメン食べた。明日はハンバーグ食べたい」というのをzundaにかけると以下のようになります。
#EVENT0 4 wr:筆者 非未来 0 叙述 成立 0 0#EVENT1 11 wr:筆者 未来 0 欲求 0 ポジティブ 0* 0 2D 0/1 1.517062今日 名詞,副詞可能,*,*,*,*,今日,キョウ,キョーは 助詞,係助詞,*,*,*,*,は,ハ,ワ* 1 2D 0/1 3.754632ラーメン 名詞,一般,*,*,*,*,ラーメン,ラーメン,ラーメンを 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ* 2 5D 0/1 -1.168598食べ 動詞,自立,*,*,一段,連用形,食べる,タベ,タベた 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ。 記号,句点,*,*,*,*,。,。,。* 3 5D 0/1 -1.168598あした 名詞,副詞可能,*,*,*,*,あした,アシタ,アシタは 助詞,係助詞,*,*,*,*,は,ハ,ワ* 4 5D 0/1 -1.168598ハンバーグ 名詞,一般,*,*,*,*,ハンバーグ,ハンバーグ,ハンバーグを 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ* 5 -1D 0/1 0.000000食べ 動詞,自立,*,*,一段,連用形,食べる,タベ,タベたい 助動詞,*,*,*,特殊・タイ,基本形,たい,タイ,タイEOS |
「#EVENT」が対象の情報です。
ただこのままだと、どこの文章にどの#EVENTがかかってるかわかりづらいのと、Nodejsで使いたかったので、npm作りました。
ZundaJS
https://www.npmjs.org/package/zunda
これにさっきの文章をかけるとこうなります。
[ { event: [ '#EVENT0', '4', 'wr:筆者', '非未来', '0', '叙述', '成立', '0', '0' ], words: '今日はラーメンを食べた。', wakachi: '今日 は ラーメン を 食べ た 。' }, { event: [ '#EVENT1', '11', 'wr:筆者', '未来', '0', '欲求', '0', 'ポジティブ', '0' ], words: 'あしたはハンバーグを食べたい', wakachi: 'あした は ハンバーグ を 食べ たい' } ] |
wordsはeventがかかっている文章、wakachiはそれを分かち書きにしたものです。
zundaがtwitterのつぶやきという崩れた日本語に対して、どれだけ的確に解析できるかが分かれ目な気がします。
ladyテーブルを元に、多分女の子であろうアカウントがツイートした内容を引っ張ってきて、それをzundaにかけて、ツイートの文章とzundaのイベントを紐付けます。
1アカウントに対し100件づつタイムラインを取得します。(get_lady.js)
zundaの解析が遅いのとTwitterのAPIのリクエスト制限があるのでかなり遅いです。(10日くらいスクリプトを回して22万ツイートくらい)
lady_timelineテーブル
多分女の子であろう子たちがツイートした内容
構造はgirls_timelineと同じ。
lady_timeline_zunda
lady_timelineとzundaのイベントをひもづけるテーブル
|
id |
tweet_id
|
jise |
kaso
|
taido
|
shingi |
kachi
|
body
|
wakachi
|
|---|---|---|---|---|---|---|---|---|
| ツイートID | 時制 | 仮想 | 態度 | 真偽判断 | 価値判断 | ツイート本文 | スペース区切りの分かち書き | |
|
1 |
478887176524951550 |
未来 |
0 | 欲求 |
0 |
ポジティブ | 一度でいいからパイを投げ合いたいね。 | 一 度 で いい から パイ を 投げ 合い たい ね 。 |
|
2 |
478881779336478700 |
未来 |
0 | 欲求 |
0 |
ポジティブ | 乗りたい | 乗り たい |
| 3 | 478881098705821700 | 未来 | 0 | 欲求 | 0 | ポジティブ | てかちょー乗りてぇ | てか ちょ ー 乗り てぇ |
これで、あるツイートに対してのポジネガを出すことが出来ました。
lady_timeline_zundaからデータを取得し、ステム処理してファイル(zunda.txt)に出力します(zunda2txt.py)
3. タイプの女の子を探す
あるキーワードに対して、関連性が高い項目を引っ張ってくるために、word2vecを使います。
キーワードに対して関連性の高い単語や文章以外にも、アカウントも引っ張ってこることができます。
と言うか、アカウントの文字列も他の単語同様に扱われます。
word2vecは文章をDeep learningで学習させることができて類語を取得することができるツールです。
文章に対象のキーワードが入っていなくても関連性が高かったら取得できるわけです。
3-1. word2vecに女の子のツイートデータを突っ込む
女性教師コーパスを作ったgensimにはword2vecも扱える機能が備わっています。
word2vecに入れるには分かち書きされたデータが必要です。
2-1の最後で作成したzunda.txtを使って、モデルと言われるいわゆる辞書を作ります。(w2v2.py)
python w2v2.py 0 --text zunda.txt -s |
3-2. キーワード検索する
モデルができたらいよいよ好みのタイプの女の子を検索します。
今回は「アニメ好き」で「眼鏡っ子」を探したいと思います。
キーワードを「アニメ」「眼鏡」にして、ネガティブ以外で上位10件取得します。
python w2v2.py 10 --model zunda.model --posi "アニメ" "眼鏡" --nega "ネガティブ" 1 @asmz_k 0.476201772692 @BlackWhitewww 0.4421932101253 @eve127ast 0.4310051202774 @bomusoca342838 0.4187217056755 @cocotaaaaan58 0.4186984598646 @ayunoko 0.418449461467 @candycofin 0.4151680767548 @burattinata 0.4147556722169 @d6y_ 0.404557377110 @azunagisa858 0.403305977583 |
腐女子っぽいアカウントが多めに出てきました。
「料理好きの人妻」は
キーワードを「ごはん」「掃除」「旦那」とかにしてみます。
python w2v2.py 10 --model zunda.model --posi "ごはん" "掃除" "旦那" --nega "ネガティブ" 1 @BND1354 0.5227938890462 @Cs_Another 0.5157579779623 @chizufuchan 0.5048305988314 @bump9848rad 0.49819573765 @ch1taru519 0.4941828846936 @Cypher_AR_801 0.4917736947547 @Ayami_SP 0.4870145618928 @forest_green13 0.4858876466759 @buin_buin_buin_ 0.48278287053110 @cottonXcandy301 0.479955106974 |
と人妻らしき人が出てきましたね。
4. まとめ、こういう使い方のがいいかも
上記の検索だと、アニメ、メガネに関連するツイート → アニメに登場するあるメガネキャラが好きな女の子 → 「アニメ好きでメガネをかけてる男が好きな女の子」がヒットする可能性が大いにあります。
ツイートを元に検索をかけてるのでキーワード選定がちゃんとされてないとほとんど引っかかりません。
例えば、「女子高生」でヒットさせたい場合、「女子高生」というキーワードで検索をかけても、自分で「わたし女子高生なの」なんてつぶやく人はいないためほとんど引っかかりません。
たぶん「あー学校だりぃ」とか「学校終わった、これからバイト」みたいな文章がほとんどだと思うので、「学校」というキーワードで出てくる可能性のが高いです。(中学生も引っかかってきそうなので、「バイト」と入れたほうがいいかもしれないですね)
自分で自分の外見的特徴をなかなか言わないように、好みのタイプを探すにはキーワード選定が結構難しいと思います。
ツイートは基本的に本人が興味あること、好きなこと、嫌いなことをつぶやくため、「芸能人」や「アプリ」で検索して今女の子に人気の芸能人や、「最近のアプリのネガティブな意見を引っ張ってくる」みたいな使い方のが、実用性があるかなと思いました。
5. 参考文献
Differences in the Mechanics of Information Diffusion
Across Topics: Idioms, Political Hashtags, and Complex
Contagion on Twitter
http://dromero.org.s3-website-us-east-1.amazonaws.com/info_diffusion_topics_slides.pdf
Topic and Sentiment Analysis on OSNs:
a Case Study of Advertising Strategies on Twitter
http://arxiv.org/pdf/1312.6635v1.pdf
Introduction to Weka- A Toolkit for Machine Learning
http://iasri.res.in/ebook/win_school_aa/notes/WEKA.pdf
LSIやLDAを手軽に試せるGensimを使った自然言語処理入門
http://yuku-tech.hatenablog.com/entry/20110623/1308810518
潜在的意味インデキシング(LSI)徹底入門
http://d.hatena.ne.jp/a_bicky/20120324/1332591498
Python用のトピックモデルのライブラリgensim の使い方
http://sucrose.hatenablog.com/entry/2013/10/29/001041
モデルの精度を推定する
http://musashi.sourceforge.jp/tutorial/mining/xtclassify/accuracy.html
gensim
http://radimrehurek.com/gensim/index.html
zunda Japanese Extended Modality Analyzer
https://code.google.com/p/zunda/
word2vec
https://code.google.com/p/word2vec/