Twitter APIで取得したツイートをGiNZAで形態素解析する

#はじめに
SNS解析を行ったりするとき、Twitterのツイートデータを形態素解析やらなんやかんやの解析をしていきたいそこのあなた！
そんなあなたのために、やり方をまとめてみました。

#環境
python3.7
python-twitter3.5
GiNZA2.2.5
pymongo3.9.0

#Twitter API
Twitter APIを利用するには、Twitter Developerでappを作成する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508288/22785e29-c1e3-d567-6225-310e4adeda65.png)

appを作成すると、API keyとAccess Tokenがゲットできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508288/d565a0a8-9840-58b0-af09-6cccd5baa435.png)
Twitter API呼び出し時に上で黒塗りしているもの４つすべてを使用します。

#python-twitter
まずは、pytnon-twitterをインストールします。

```bash:python-twitter
pip install python-twitter
```
Twitter APIを呼び出して、ツイートを取得してみましょう。
まずは、twitter.Api クラスを構築します。

```python:twitter.Api構築
import twitter
import json

api = twitter.Api(consumer_key='[API key]',
                  consumer_secret='[API secret key]',
                  access_token_key='[Access token]',
                  access_token_secret='[Access token secret]',
                  tweet_mode='extended')
```

上記の、[　] 部分は、appを作成した時にゲットしたものを指定してください。
`tweet_mode='extended'`を指定しないと、長いツイートが途中で途切れてしまいます。なのでつけてます。


「遅延」というキーワードでツイートを取得します。
取得には`api.GetSearch`を使用します。

```python:api.GetSearch
results = api.GetSearch(
    raw_query="q=遅延%20&result_type=recent&since=2019-10-17&count=1000")
```
戻り値は、`twitter.Status`インスタンスのリストで返却されます。

取得結果を表示してい見ましょう。

```python:results
for result in results:
    print(result.AsJsonString())
```
下記のような出力が返されます。jsonですね。

```json:results
{"created_at": "Thu Oct 17 10:37:20 +0000 2019", "full_text": "RT @udzura: \u6628\u65e5\u306e\u30d6\u30ed\u30b0\u304c\u9045\u5ef6\u3057\u307e\u3057\u305f\u3002\u305d\u3046\u3044\u3046\u3053\u3068\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 / 1\u4ef6\u306e\u30b3\u30e1\u30f3\u30c8 https://t.co/yj6aDZnLbE \u201cNginx\u3092bpftrace\u3067\u8ffd\u3044\u304b\u3051\u308b - \u30ed\u30fc\u30d5\u30a1\u30a4\u65e5\u8a18\u201d (1 user) https://t.co/hZJosbxStr", "hashtags": [], "id": 1184780427359162368, "id_str": "1184780427359162368", "lang": "ja", "retweet_count": 4, "retweeted_status": {"created_at": "Thu Oct 17 06:54:18 +0000 2019", "favorite_count": 4, "full_text": "\u6628\u65e5\u306e\u30d6\u30ed\u30b0\u304c\u9045\u5ef6\u3057\u307e\u3057\u305f\u3002\u305d\u3046\u3044\u3046\u3053\u3068\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 / 1\u4ef6\u306e\u30b3\u30e1\u30f3\u30c8 https://t.co/yj6aDZnLbE \u201cNginx\u3092bpftrace\u3067\u8ffd\u3044\u304b\u3051\u308b - \u30ed\u30fc\u30d5\u30a1\u30a4\u65e5\u8a18\u201d (1 user) https://t.co/hZJosbxStr", "hashtags": [], "id": 1184724298558144512, "id_str": "1184724298558144512", "lang": "ja", "retweet_count": 4, "source": "<a href=\"http://b.hatena.ne.jp/\" rel=\"nofollow\">\u306f\u3066\u306a\u30d6\u30c3\u30af\u30de\u30fc\u30af</a>", "urls": [{"expanded_url": "https://b.hatena.ne.jp/entry/s/udzura.hatenablog.jp/entry/2019/10/17/155317", "url": "https://t.co/yj6aDZnLbE"}, {"expanded_url": "https://htn.to/4sYB93mPVt", "url": "https://t.co/hZJosbxStr"}], "user": {"created_at": "Wed Oct 13 06:30:05 +0000 2010", "description": "Systems programmer wannabe, linguist wannabe / duolingo = uchio2", "favourites_count": 51999, "followers_count": 3826, "friends_count": 3038, "geo_enabled": true, "id": 202062015, "id_str": "202062015", "listed_count": 175, "location": "\u30de\u30cc\u30b3\u30fc\u30d2\u30fc\u5927\u540d\u5e97", "name": "Uchio KONDO \ud83d\udd2b", "profile_background_color":
```
長いので、途中で切っています。

#GiNZA
リクルートのAI研究機関と国立国語研究所が共同で開発した，日本語の自然言語処理ライブラリです。
https://megagonlabs.github.io/ginza/

GiNZAは内部でspaCyを使用しているそうです。
GiNZAをインストールします。

```bash:GiNZA
pip install "https://github.com/megagonlabs/ginza/releases/download/latest/ginza-latest.tar.gz"
```
先ほど取得したツイートの一つ目のは以下です。

```text:一つ目のツイート
RT @udzura: 昨日のブログが遅延しました。そういうことにしてください。 / 1件のコメント https://t.co/yj6aDZnLbE “Nginxをbpftraceで追いかける - ローファイ日記” (1 user) https://t.co/hZJosbxStr
```

これをを形態素解析してみます。

```python:GiNZA
import spacy

nlp = spacy.load('ja_ginza')
doc = nlp(json.loads(results[0].AsJsonString())['full_text'])
for sent in doc.sents:
    for token in sent:
        print(token.i, token.orth_, token.lemma_, token.pos_, token.tag_, token.dep_, token.head.i)
    print('EOS')
```
モデルとして`ja_ginza`をロードしています。ツイートの一つ目を指定してセンテンスごとにトークンを取得し、その形態素解析結果を表示しています。

```text:結果
0 RT RT NOUN 名詞-普通名詞-一般 nmod 3
1 @ ＠ PUNCT 補助記号-一般 dep 2
2 udzura udzura NOUN 名詞-普通名詞-一般 compound 3
3 : ： PUNCT 補助記号-一般 ROOT 3
EOS
4 昨日 昨日 NOUN 名詞-普通名詞-副詞可能 nmod 6
5 の の ADP 助詞-格助詞 case 4
6 ブログ ブログ NOUN 名詞-普通名詞-一般 nsubj 8
7 が が ADP 助詞-格助詞 case 6
8 遅延 遅延 VERB 名詞-普通名詞-サ変可能 ROOT 8
9 し 為る AUX 動詞-非自立可能 aux 8
10 まし ます AUX 助動詞 aux 8
11 た た AUX 助動詞 aux 8
12 。 。 PUNCT 補助記号-句点 punct 8
EOS
13 そう そう ADV 副詞 advmod 14
14 いう 言う VERB 動詞-一般 ROOT 14
15 こと こと NOUN 名詞-普通名詞-一般 compound 14
16 に に ADP 助詞-格助詞 case 14
17 し 為る AUX 動詞-非自立可能 aux 14
18 て て SCONJ 助詞-接続助詞 mark 14
19 ください 下さる AUX 動詞-非自立可能 aux 14
20 。 。 PUNCT 補助記号-句点 punct 14
EOS
21 / / PUNCT 補助記号-一般 compound 23
22 1 1 NUM 名詞-数詞 nummod 23
23 件 件 NOUN 名詞-普通名詞-助数詞可能 nmod 25
24 の の ADP 助詞-格助詞 case 23
25 コメント コメント NOUN 名詞-普通名詞-サ変可能 ROOT 25
EOS
26 https https NOUN 名詞-普通名詞-一般 compound 27
27 : ： PUNCT 補助記号-一般 ROOT 27
EOS
28 / / PUNCT 補助記号-一般 compound 30
29 / / PUNCT 補助記号-一般 compound 30
30 t t NOUN 名詞-普通名詞-助数詞可能 ROOT 30
31 . . PUNCT 補助記号-句点 punct 30
EOS
32 co CO NOUN 名詞-普通名詞-一般 compound 34
33 / / PUNCT 補助記号-一般 compound 34
34 yj yj NOUN 名詞-普通名詞-一般 ROOT 34
EOS
35 6 6 NUM 名詞-数詞 ROOT 35
EOS
36 aDZnLbE adznlbe NOUN 名詞-普通名詞-一般 dep 45
37 “ “ PUNCT 補助記号-括弧開 punct 38
38 Nginx nginx NOUN 名詞-普通名詞-一般 obj 42
39 を を ADP 助詞-格助詞 case 38
40 bpftrace bpftrace NOUN 名詞-普通名詞-一般 advcl 42
41 で で SCONJ 助詞-格助詞 mark 40
42 追いかける 追い掛ける VERB 動詞-一般 acl 45
43 - - PUNCT 補助記号-一般 compound 44
44 ローファイ ローファイ NOUN 名詞-普通名詞-一般 compound 45
45 日記 日記 NOUN 名詞-普通名詞-一般 ROOT 45
EOS
46 ” ” PUNCT 補助記号-括弧閉 punct 47
47 ( （ PUNCT 補助記号-括弧開 compound 48
48 1 1 NUM 名詞-数詞 dep 52
49 user ユーザー NOUN 名詞-普通名詞-一般 compound 50
50 ) ） PUNCT 補助記号-括弧閉 compound 52
51 https https NOUN 名詞-普通名詞-一般 compound 52
52 : ： PUNCT 補助記号-一般 ROOT 52
EOS
53 / / PUNCT 補助記号-一般 compound 55
54 / / PUNCT 補助記号-一般 compound 55
55 t t NOUN 名詞-普通名詞-助数詞可能 ROOT 55
56 . . PUNCT 補助記号-句点 punct 55
EOS
57 co CO NOUN 名詞-普通名詞-一般 compound 58
58 / / PUNCT 補助記号-一般 dep 59
59 hZJosbxStr hzjosbxstr NOUN 名詞-普通名詞-一般 ROOT 59
EOS
```
形態素解析できました！

#最後に
これで、ツイートを自然言語解析する準備ができました。
ツイートを解析することでいろいろなことができるようになりそうです。

#参考にしたサイト
GiNZA
https://megagonlabs.github.io/ginza/
【Python】日本語NLPライブラリ”GiNZA”で言語処理100本ノック（第4章）やってみた
https://qiita.com/derodero24/items/b49dd92e14c7e7655ccc