17
28
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

ニコ動の人気タグ遷移を一発でアニメーション化できるpythonライブラリが生まれたらしいので試してみた

Last updated at Posted at 2024-01-08

AnimatedWordCloudというライブラリを作りました。

どんなライブラリ?

  • WordCloudを時系列順に処理してくれるライブラリです。
    ↓イーロンマスクの呟き2012から2017までの描画
    68747470733a2f2f6769746875622e636f6d2f6b6f6e6272617068617435312f416e696d61746564576f7264436c6f75642f6173736574732f3130313832373439322f38393035326332302d623232382d343264382d393231652d656261653966376533306130.gif

ダウンロード方法

PyPIで配布中です

使う時は

pip install AnimatedWordCloudTimelapse

としてダウンロードしてください。

元リポジトリ

ここにあります。StarやContributeをしてくださるとありがたいです。

使い方

まずは可視化するためのデータが必要です。そこで, 今回はニコニコ動画のデータセットを使いましょう。ニコニコ動画の2007年から2021年のタグを可視化することを目指します。ニコニコ動画データセット
このデータは重いので今回はそのうちの一つである0000.jsonlを可視化します。
必要事項を記入したら0000.jsonlをwgetで取得しましょう

!wget https://dlsv.dsc.nii.ac.jp/idr/hogehoge/hugahuga/nicocomm/data/video/0000.jsonl

ここからはデータ整形を行っていきます。今回はみんなに優しくGoogle Colaboratoryでの実行を仮定しています。
まずはjsonlデータを[date, tag]のcsvデータに整形しましょう。

import json
json_data = []
with open('0000.jsonl', 'r') as json_open:
    for line in json_open:
        json_data.append(json.loads(line))


csv_data = [["date", "tag"]]
for data in json_data:
  tags = data["tags"].split(" ")
  for tag in tags:
    csv_data.append([data["upload_time"], tag])

import csv
with open("tags.csv", "w") as f:
  csv_writer = csv.writer(f)
  csv_writer.writerows(csv_data)

Google Colaboratoryの/content/以下にtags.csvが保存されているので, それをpandasで読みこんで前処理をしましょう。

import pandas as pd
df = pd.read_csv("/content/tags.csv")

df["date"] = pd.to_datetime(df["date"]) #datetime型にする

df.head(5)
date tag
0 2007-03-06 12:14:17+09:00 MAD
1 2007-03-06 12:14:17+09:00 アニメ
2 2007-03-06 12:14:17+09:00 最終兵器彼女
3 2007-03-06 19:27:26+09:00 3月6日投稿動画
4 2007-03-06 19:27:26+09:00 IDニ謝レ

読み込むと上のような表が出力されます。このデータを以下の手順に沿って前処理しましょう。

  1. dateをdatetime型に変換してsortする
  2. 厳密な時間ではなく投稿年で再ラベリング
df = df.sort_values(by='date') #dateでsort
df["year"] = df["date"].dt.year #yearに関して再度ラベリング, カラムを追加

これで前処理は終了です。ここで僕らのチームが作成したAnimatedWordCloudライブラリをインストールしておきましょう。

pip install AnimatedWordCloudTimelapse

ここで, WordCloudのアニメーションを制作するためにはAnimatedWordCloudライブラリのanimateという関数を用いますが, これの入力のために, List[year, dict[word, 登場頻度]]という形のデータを作る必要があります。登場頻度も全てをカウントしていると数が多すぎるため, 上位100個にしましょう。

timelapse = []

for year in df["year"].unique():
  df_year = df[df["year"] == year]
  counter = df_year["tag"].value_counts()[:100]

  word_vector = counter.to_dict() #{word: 登場頻度}の辞書に

  timelapse.append((str(year), word_vector))

このデータが作れたらついにWordCloudのアニメーションを制作することができます。制作する前に, NotoSansJP-VariableFont_wght.ttfをダウンロードしておいて/contentの下に置き, 日本語の文字列に対応しておきましょう。
以下のコードではConfigというものを指定しています。簡単に今回使ったConfigを紹介しておきます。

  • font_path: 表示に使うフォントのパスです。
  • output_path: gif画像出力先のパスです。現Versionでは必ず指定してください。
  • image_width, image_height: 出力gif画像のサイズです。
  • verbosity: gif画像の作成状況の表示を行うか否かを指定します。silent, minor, debugの3つのモードがあり, silentは作成状況を表示しません, minorは進捗バーが表示されます。debugは全ての進捗が表示されます。minorとdebugモードではgif画像出力先のパスも表示されます。
  • n_frames_for_interpolation: ある時間とある時間の間を埋めるのにどれぐらいのフレームを使うのかを指定します。デフォルトでは20ですが今回はqiitaにあげれる画像容量の関係で10にしています。補間フレームは文字の線形移動によって実装されています。今後線形以外の補間方法が追加される予定です。
from AnimatedWordCloud import animate, Config

config = Config(
    font_path="/content/NotoSansJP-VariableFont_wght.ttf",
    output_path="/content/",
    image_width=1600,
    image_height=1200,
    verbosity="debug",
    n_frames_for_interpolation=10
)

result = animate(timelapse, config)
#resultには出力gifが保存されている場所のpathが与えられる。

上のコードを実行すると以下の表示がでます。この表示が出れば保存成功です。

------------------------------Success!------------------------------
    your animation was successfully saved in /content/output.gif    
--------------------------------------------------------------------

作成されたgif画像はこんな感じです。
output-2.gif

作成後, フレームごとの画像も保存されてしまうため, 気になる方はMac, Linux, WSLの方はrmコマンドで削除すると良いでしょう。

#例
rm /content/*.png

今後の展望

今はgif画像の出力のみですが, 正直言って娯楽以外ではデータの可視化としては使いづらいと思います。そこで, 今後のMajor updateとしてjsonによる出力を追加し, フロントエンドでの実装に役立つような機能を追加予定です。お楽しみにしていてください。

他の実装例

相方が何通りか作成してくれています。是非遊んでみてください。

17
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
28