ニコニコ動画の全コメントをBigQueryに入れる

# これはなに

オープンデータとして公開されているニコニコ動画の全動画メタ情報、全コメント情報を、Google Cloud Platformの[BigQuery](https://cloud.google.com/bigquery/)に入れる。最後に、そのデータを入れてデータの分析を行う。

# 時間がない人向けのまとめ

 * 誰でも使えるニコニコデータセットの紹介
 * そのデータセットを加工してBigQueryに入れるま手法の紹介
 * 入ったデータを使って実際にデータ分析を行った

# ニコニコデータセット

https://www.nii.ac.jp/dsc/idr/nico/nico.html

ニコニコ動画は、サービス開始から、2018年11月8日までの動画メタデータ、コメントデータを公開している。動画メタ情報は、`16,703,325（約1,670万）` コメント情報は、 `3,773,083,461（約38億）` が公開されている。上記サイトを見ると、研究者向けという印象を受けるかもしれないが、利用に制限はなく、個人でも利用できる。メールアドレスなどを入力すれば誰でも使える。

# ニコニコデータセットをBigQueryに入れる

上で紹介したニコニコデータセットのデータをBigQueryに入れてみよう。

## データのダウンロード

上のサイトにメールを登録すると、データダウンロードのためのページを紹介されるので、そちらからデータをダウンロードする。ファイルリストがあるので参考情報にあるように

```
% wget -r リストファイルのURL
```

としてファイルをダウンロードするのが楽だろう。動画メタデータの情報は、3,411ファイル合計 約4.4GB（圧縮）ある。コメント情報は3,411ファイル 合計 約70GB（圧縮）ある。そのため、HDDの空き容量に注意が必要だ。GCEなどでインスタンスを立てても良いかもしれない。

## データのフォーマット

動画メタ情報、コメント情報は、それぞれ、1レコード1Jsonのjsonlで構成されている。[^1]
[^1]: ニコニコ動画コメント等データ仕様を参照した。

### 動画メタデータのデータ仕様

|キー |値 |値の型 |例|
|:----:|:---:|:---:|:---:|
|video_id |動画ID |String |“sm9”|
|title |動画タイトル |String |“新・豪血寺一族 -煩悩解放 - レッツゴー！陰陽師”|
|description |動画説明文 |String |“レッツゴー！陰陽師（フルコーラスバージョン）”|
|watch_num |再生数 |Number |15903574|
|comment_num |コメント数 |Number |4413238|
|mylist_num |マイリスト登録数 |Number |164924|
|category |動画カテゴリ |String (nullable) |null|
|tags |タグの列 |Array[String] |[“ゲーム” “音楽” “レッツゴー！陰陽師” “公式” “陰陽師” “最古の動画” “sm9” “空耳” “巡礼”]|
|upload_time |投稿時間 (UNIX時間・秒) |Number |1173108780|
|file_type |動画フォーマット |String (“flv”, “swf”, “mp4”) |“flv”|
|length |動画再生長 (秒数) |Number |319|
|size_high |高画質動画のファイルサイズ (byte) |Number |21138631|
|size_low |低画質動画のファイルサイズ (byte) |Number |17436492|

### コメントデータのデータ仕様

コメントデータのデータ情報は次のようになっている。

|キー |値 |値の型 |例|
|:----:|:---:|:--:|:---:|
|date |コメント投稿時間 (UNIX時間・秒) |Number |1173122885|
|content |コメント本文 |String |“きたｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗ”|
|vpos |書き込み再生位置 (秒を100倍) |Number |1061|
|command |コマンド |String (nullable) |“big green”|

コメントデータで特徴的なのは、コメント情報に **動画ID情報が含まれていない** 点だ。zipに含まれる **動画ID.json** というファイル名に含まれる。そのため、データを加工して次のようにする。


|キー |値 |値の型 |例|
|:----:|:---:|:--:|:---:|
|video_id(新しく追加) |動画ID |String |“sm9”|
|date |コメント投稿時間 (UNIX時間・秒) |Number |1173122885|
|content |コメント本文 |String |“きたｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗ”|
|vpos |書き込み再生位置 (秒を100倍) |Number |1061|
|command |コマンド |String (nullable) |“big green”|

## データの整形

動画メタ情報も、コメント情報も、zipで圧縮しており、BigQueyで読むには都合が悪い。そのため、zipファイルからgzファイルへの変換を行う。コメント情報の場合はあわせて、video_idの追加を行う。

### 変換スクリプトの準備


データを整形するための簡単なスクリプトを用意した。

https://github.com/shibacow/niconico_dataset_add_smid

pythonの `from concurrent.futures import ProcessPoolExecutor` に対応しているため、コア数が多いほうが性能がでるので、クラウドで一時的にインスタンスを借りるのも良いだろう。

#### 動画メタ情報の変換

上記のレポジトリをクローンして、

```shell
cd niconico_dataset_add_smid
mkdir ../video
# videoフォルダに動画メタ情報を置く。
cp foobar/*.zip v../ideo/
mkdir ../video_dst
python3 video_convert.py
```

を実行する。そうすると、 `video_dst` フォルダに `NNNN.json.gz` が出来る。

### コメント情報の変換

上記と同じく、上記のレポジトリをクローンして、

```shell

cd niconico_dataset_add_smid
mkdir ../comment
# videoフォルダに動画メタ情報を置く。
cp foobar/*.zip ../comment/
mkdir ../comment_dst
python3 comment_convert.py
```

を実行する。そうすると、`comment_dst` フォルダに `0000.json.gz` が出来る。CPU数によって実行速度は変わるが、ゆっくり待つ。GCEで借りたインスタンス36coreで２時間位かかった。

## BigQueryへのロード

BigQueryへのロードは、一旦、GCSにデータを格納してからBigQueryへロードしたほうが早い。そのため、`.json.gz`のファイルをGCSへ送る。
BigQueryに移動し、先に、`nico_data` というデータセットを作っておくこと。

その後、

```shell

bq load --source_format=NEWLINE_DELIMITED_JSON nico_data.video "gs://foo-bar/video/*.json.gz" video.json
bq load --max_bad_records=1000 --source_format=NEWLINE_DELIMITED_JSON nico_data.comment "gs://foo-bar/comment/*.json.gz" comment.json
```

を行う。コメント情報で、bad_recordsを指定しているのは、 vposの値が、intの上限を超えるデータがあったため。
それぞれロードに、**20分程度** かかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26986/627f36b0-62b7-1380-8c18-c3befa98dcea.png)

暫く待つとこのようにデータが入る。

# 簡単な分析

簡単に分析をしてみよう。

## ニコニコ動画コメント数推移

せっかくコメントが入っているのでコメント数の時系列変化を見てみる。SQLは `standard sql` を利用する。

```sql
SELECT date_trunc(date(`date`),YEAR) as dt,
count(1) as cnt
FROM `nico_data_2018`.`comment`
GROUP BY dt
ORDER BY dt;
```
これで、コメントの時系列の変化を見ることが出来る。ちなみに、37億件が、19秒で処理できる。

集計結果はこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26986/b02d76f4-22d4-d9d1-35df-b3406114cee8.png)

18年は、11月までしか集計していないが、徐々に右肩下がり。
7年-9年は、コメント数が、増えているが、10年以降下がっている。ちょうどその頃、スマホが出てきて、世の中に普及した。社会がスマホに移行することで、動画を見ながら画面に文字を打ち込むことが不自由になりコメントされにくくなったという仮説は立てられる。


## 888888を含むコメントはどのジャンルでどのように推移したか？

BigQueryのすごいところは、中間一致を含むSQLがすごく早いところだ。今回はもう少し複雑なSQLを書いてみよう。

ニコニコ動画には、自分が感動した動画には　**8888888** をつける習慣がある。8888 は パチパチパチパチと拍手の意味。 https://dic.nicovideo.jp/a/8 

その 88888 はどのカテゴリでどのように変化したかを見ていく。
使用したSQLは

```SQL
SELECT a.category,b.dt,sum(b.cnt)
FROM 
( SELECT video_id,
  date_trunc(date(`date`),YEAR) as dt,
  count(1) as cnt
  FROM `nico_data`.`comment`
  WHERE content like "%8888%"
  GROUP BY video_id,dt
) b
JOIN (
  SELECT category,video_id
  FROM `nico_data`.`video`
) a
ON a.video_id=b.video_id
GROUP BY a.category,b.dt

```

カテゴリ情報は、動画メタ情報にしかなく、コメントの詳細はコメントにしかないのでその２つをjoinする必要がある。

37億件のコメントをなめた上に、37億件のコメントと1700万件のジョインをして、11秒で処理が終わる・・・。

集計結果はこちら。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26986/642b9a0d-e301-09e9-0997-558ac476752f.png)

一番、　8888 を集めていたのは、歌ってみただった。その次が、ゲーム+ゲーム実況。その次がボカロだった。その下に、その他や、踊ってみたが続く。

888が集まるというはある意味人の感動が集まるという意味で、歌ってみたやボカロ、踊ってみたに **8888** が集まるのはわかる気がする。

# まとめ

誰でも利用できるデータセットと、大容量のデータをすばやく、驚異的に安く、処理が出来るBigQueryを組み合わせて、数億件のデータを使った集計が出来る。それは特に研究所や大学に属していない野生の研究者が研究できることを意味する。このノウハウが、野生の研究者の一助になれば幸いである。

 * 誰でも使えるニコニコデータセットの紹介
 * そのデータセットを加工してBigQueryに入れるま手法の紹介
 * 入ったデータを使って実際にデータ分析を行った