【備忘録】 ③word2vecに変換 ~拡散されるニュースツイートを判別したい~

### 開発環境
Windows10
Anaconda3 (jupyter notebook)
### 説明と目的
ある大学生の卒論備忘録
テーマは、ニュースツイートにおいて、拡散されるものとされないものの判別器を作るというものです。
今回は、東北大学の学習済みword2vecを用いて、文書のベクトル平均で文書ベクトルを作ろうと思います。
### 前提条件
・東北大学のword2vecインストール済み
※Windowsでの解凍はLhaplusで行うのが良いかと思います。
### 参考URL
・東北大学word2vec
http://www.cl.ecei.tohoku.ac.jp/~m-suzuki/jawiki_vector/
・使い方
http://blog.hassaku-labs.com/post/pretrained-word2vec/
### 1. 必要なライブラリをインポート
```python:tohoku_word2vec.ipynb
import gensim
import pandas as pd
import numpy as np
from gensim.models import KeyedVectors
```
### 2. モデルの読み込み
```python:tohoku_word2vec.ipynb
# model読み込み
model = KeyedVectors.load_word2vec_format('C:/entity_vector/entity_vector.model.bin', binary=True)
```
'C:/entity_vector/entity_vector.model.bin'の部分は解凍した場所のディレクトリです。すこし時間がかかります。
### 3. データセットを作る
前回の前処理済みツイートを取得します。また、直近3日分のツイートと5000RT～7000RTのツイートは拡散と非拡散の判別が困難なため、除きたいため、それ以外のデータのインデックスを取得します。
ちなみに、
前回作ったデータセットはこのようになっています。

|index| tweet_no |       time        | text | favorite_count | RT_count |  Owakati  |Buzz|
|-----|----------|--------------------|------|----------------|----------|-----------|----|
|   0| 00000000 |yyyy-mm-dd 時間:分:秒|XXXXXX|              xx|       xx|xx x x xx|0or1|


```python:tohoku_word2vec.ipynb
# データの読み込み
acount = "@livedoornews"
df = pd.read_csv("../data/finish_preprocessing_{}.csv".format(acount))

# 直近3日間を除外
now = datetime.datetime.now()
escape = now - datetime.timedelta(days=3)
usual_news_index = [] # 非拡散ツイートのindex格納用の空リスト
buzz_news_index = [] # 拡散ツイートのindex格納用の空リスト

for index, t in zip(df.index,df["time"]):
    if df.iloc[index,6] == 1:# 拡散だったかどうか
        buzz_news_index.append(index)
    elif escape < datetime.datetime.strptime(t, '%Y-%m-%d %H:%M:%S') or 7000 > df.iloc[index,4] > 5000:#直近3日間かor5000RT~7000RTか
        pass
    else:
        usual_news_index.append(index)

print("通常ニュース数 ; {}".format(len(usual_news_index)))
print("拡散ニュース数 ; {}".format(len(buzz_news_index)))
```
>
通常ニュース数 ; 1702
拡散ニュース数 ; 144

次に、取得したindexを使って、Buzz判定と分かち書きのデータセットを作ります

```python:tohoku_word2vec.ipynb
data_news_index = usual_news_index + buzz_news_index
sample_data = df.iloc[data_news_index].reset_index()
data = np.array(sample_data[['Buzz', 'Owakati']])
data.shape
```
>Out[ ]: (1846, 2)

### 4. word2vecで数値化する
では、1つの文章ずつword2vecを用いて文章のベクトル平均を計算していいきます。

```python:tohoku_word2vec.ipynb
result = [] # 文章ベクトルを格納するためのリスト
dict_word = [] # 学習済みword2vecに存在していた単語を格納するためのリスト
dict_escaped = [] # 学習済みword2vecに存在していなかった単語を格納するためのリスト
for i in range(data.shape[0]): #1文章ずつ取り出す
    print("{}回目 (残り{}回)".format(i+1,data.shape[0]-i-1))
    sentense_list = data[i][1].split(' ')
    vector = [] # 文章の中の単語のベクトルを格納するためのリスト
    for word in sentense_list:
        try:
            vector.append(model[word].tolist())
            dict_word.append(word)
        except:
            dict_escaped.append(word)
    result.append(np.mean(np.array(vector), axis=0).tolist())

data_vector = pd.concat([pd.DataFrame({"label" : data[:, 0].tolist()}), pd.DataFrame(np.array(result))], axis=1)
data_vector
```
> 
1回目 (残り1845回)
2回目 (残り1844回)
3回目 (残り1843回)
4回目 (残り1842回)
..............
Out[ ]:
![データ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522226/d3348709-d213-6e6a-7271-ba27e2cd1447.jpeg)

1846件の200次元のベクトル値とlabel(拡散かどうか)をpandasで格納したdata_vectorを取得します。
また、学習済みword2vecに存在していない単語はErrorになるので、try~exceptを使用しています。
### 5. 反映できた文書とできなかった文書
では、word2vecに存在していた文書をみてみます。

```python:tohoku_word2vec.ipynb
dict_word = list(set(dict_word))
print(len(dict_word))
print(dict_word)
```
>12145
['つかの間', '1969年', '対局', 'うつ病', 'シーズ', '抑制', 'リスク', '書状', '代表者', '不当', '民事訴訟', '睡眠薬', 'ザ', '溺れる', 'かぶせ', '凍結', 'B2', '遺品', '伝染', '岩根', '増え'.......]
のようになっていました。

次に、word2vecに存在していなかった単語を調べました。

```python:tohoku_word2vec.ipynb
dict_escaped = list(set(dict_escaped))
print(len(dict_escaped))
print(dict_escaped)
```
>2273
['後見制度', '勉強していたい！', '走塁', '6種類', 'オウムアムア', '一部店舗', '30発', '牧草地', '緑茶飲料', '数年前', '優勝争い', '太川蛭子の旅バラ', 'ゆりやん', 'アリキリ石井', '公判前整理手続き', '昨冬', 'ブラウザーゲーム', '岩手県野田村', 'みずほフィナンシャルグループ', '2軍', '大門未知子', '神戸山口組', '読解力', '夕張市長', '午後8時', '陽性反応', 'インディチャンプ'.......]

個人的に大事なのではないか？と思われる単語が入っていて残念な気がしました。まぁ、2,273件の単語しか抜かれなかったのは良いと言っていいのかな？という感じですが...

では、最後に作成したデータセットを保存します。

```python:tohoku_word2vec.ipynb
data_vector.to_csv("../data/word2vec_result_@アカウント名.csv", index=False)
```
### まとめと次回内容
今回は東北大学のword2vecを用いて単語のベクトル平均で文書を数値化しました。次回はこれを用いてロジスティック回帰を行いたいと思います。