と。

Github: https://github.com/8-u8

アニメ公式Twitterアカウントのフォロワーの推移について

はじめに

MrUnadon先生の書かれたこんな記事があります. 6月9日に開催されたTokyoRにて,(Mr. Unadon氏)https://twitter.com/mrunadonが2018年冬に放送されたアニメ,『ヴァイオレット・エヴァーガーデン』のTwitter公式アカウントのフォロワー数の推移をベイズモデリングで明らかにしたということがありました. 僕もオタクなので,アニメ系のデータ分析とかしたいけど「どうやってデータ集めるんだ?」という部分から結構苦しんでいたのですが,Mr. Unadon氏はデータの取得元までまるっと教えてくださいました……素敵です……
ヴァイオレット・エヴァーガーデン』を語るUnadon氏は同志だという気持ちが強まり,「わかる……」っていいながらお話を伺っていました.テーマ設定とは裏腹に綿密に組まれたモデリングに舌を巻き,同志Unadonはデータ屋さんとしてははるか雲の上の存在だと感じました.
……そんなMr. Unadon氏ですが,同じクールで放映されていたあの神アニメ『ラーメン大好き小泉さん』をよく知らない,ということだったので「あの 美少女がラーメンを食べるアニメ を知らないままこれからの人生を過ごしていただきたくない」という 一方的な思いやり を,この記事に投下しておきたいと思います.

この記事でやること

  1. ラーメン大好き小泉さん』について
  2. データ元について
  3. データの前処理について
  4. データの傾向について
  5. おわりに

なお,ここで使っているコードの多くはMrUnadon氏の成果に依るもので,部分的に編集したものです.

0.『ラーメン大好き小泉さん』について

言わずとしれた名作なので説明する必要もないかもしれませんが,改めて今回取り上げるアニメ『ラーメン大好き小泉さん』を確認します.

ramen-koizumi.com

あらすじ
美少女の小泉さんが様々なラーメンを食べる

以上です.中の人好きな皆さん向けに申し上げれば

竹達彩奈さんが毎回,時々佐倉綾音さんや鬼頭明里さんや原由実さんや中村悠一さんがラーメンを食べるアニメ

です.見ましょう.

Twitter公式アカウントはこちらです.
原作は鳴見なる先生による漫画です.今すぐAmazonで買いましょう.

https://www.amazon.co.jp/dp/B00O438BF0/ref=cm_sw_r_tw_dp_U_x_jIFoBbXEAM651 www.amazon.co.jp

ちなみに放送期間中は週3ラーメンでマジで5kg太りました.

1. データ元について

1.1. データの取得

データの取得元はココア☆ソーダ☆クエン酸(その名もProject-ShangriLa)です.
このAPI,なんとアニメアカウントのフォロワー数のログをとっています.どんなデータだ.

データの取得については先に挙げたMrUnadon氏のコードをベースに地味な変更をしています.
とりあえずそれぞれ説明します. Rユーザーのみなさん(文法が違えどPythonユーザーのみなさん)にとっては当たり前ですが,
使うライブラリを読み込むところから始めます. この記事は1月近くかけて書いていますが,途中でRに「rlangってぇ知ってるぅ!?」と言われました.
理由は謎ですが,入れないと機嫌が悪いので入れます.

#Refarence
#https://mrunadon.github.io/Rとstanで-ヴァイオレット-エヴァーガーデン-のベイズ統計モデリング/
#/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
#/_/_ラーメン大好き小泉さんを見ろ/_/_
#/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_

#libraries
library(rlang)       # NAZO NO OMAJINAI
library(tidyverse)   # Anyone MUST use this package
library(rstan)       # Bayesian MUST use this package
library(RCurl)       # About API operation
library(rlist)       # list operation
library(rjson)       # json operation
library(lubridate)   # Time series analysis
library(anytime)     # Time variable operation
library(formattable) # HTML Table
library(DT)          # HTML Table
library(scales)      # dat_breaks()でggplot2の時間ラベル
library(shinystan)   # stan結果確認と収束診断
library(ggmcmc)      # Anyone should use this package.  

それ以外は多分変更はありません.
次に,データを収集します.それに先立って,諸々の定数について定義します. 詳しくはUnadon氏の記事を参照してください.今回ご紹介する『ラーメン大好き小泉さん』は2018年冬アニメなので,この部分は『ヴァイオレット・エヴァーガーデン』と変更はありません.

大きな(?)変更はend変数です.ここで「この日から前のログ」を遡るための基準を設けています. Unadon氏の記事では「今日の日付に依存して遡る」という仕様でしたが,こうすることで
2014年冬アニメであるところの『未確認で進行形』の放送期間中のフォロワー数推移も楽に抜き出すことも
(理論上は)可能なのではないかと思います. ただ,なんか怪しいのでもし「ちょっと小泉さん!?」ってなったらコメントください.

#DataCollect
yearBC    <- c(2018)
season    <- c(1)
EndTime   <- c(1)
samplings <- c(56)
SubtractUNIXtime<-c()

#UNIX時間で放送時間さかのぼりゲットする.
#endを固定.

for(t in 1:samplings){
  SubtractUNIXtime[t] <- c((((60*30*100)*t)-(60*30*100))-3)
  }
end  <- unclass(as.POSIXct("2018-04-08")-endTime*60)
endP <- round(c(end-SubtractUNIXtime)-180000,0)
#Followerの推移をゲットする
FollowerHistory <- data.frame(matrix(NA,0,5))

ここではフォロワー数をどれだけ取得するかを指定し,その指定分取得します.
放送期間分のフォロワーを取得するだけなので,実はここを大きく変える必要はありません.
僕はpaste0()派なのでその流儀に従っただけです*1
43~とか定数が入っている2重のfor文は,リストの各要素にtmpResに格納した情報をブチ込むときに,
取得したデータの数の都合でエラーを吐いたのでやむを得ず分離したやつです.
この辺からもAPIからの取得がうまく行っていない香りがしますが,今回は強行します.
本当はやってはいけません.

#何回分サンプリングするか?
tmpRes <- c(length(samplings))
for(t in 1: samplings){
    tmpRes[t] <- paste0("http://api.moemoe.tokyo/anime/v1/twitter/follower/history?account=ramen_koizumi&end_date=",endP[t]) %>% sprintf("account")
}
tmpRes <- tmpRes %>% list.load()

for(i in 1 : 42){
  for(u in 1 : 100){
    FollowerHistory[
      (nrow(FollowerHistory)+1),]<-c(
        2018,1,"ラーメン大好き小泉さん",
        as.numeric(unlist(tmpRes[[i]][[u]][2])),
        as.numeric(unlist(tmpRes[[i]][[u]][1])))
  }
}

for(u in 1 : 21){
  FollowerHistory[
    (nrow(FollowerHistory)+1),]<-c(
      2018,1,"ラーメン大好き小泉さん",
      as.numeric(unlist(tmpRes[[43]][[u]][2])),
      as.numeric(unlist(tmpRes[[43]][[u]][1])))
}

ここからはあまり変更はありませんが,今回の分析に用いる変数を残して,
ほかを削ります.

#Data Cleasing
StartDay <- as.POSIXct("2018-01-04")
EndDay <- as.POSIXct("2018-04-04")

Base <- data.frame(
  Date = as.Date(
    seq(StartDay,
        EndDay, 
        by = "days")))
RamenAnime <- FollowerHistory %>% 
  dplyr::mutate(Year = as.integer(X1),
                Season = as.integer(X2),
                Anime = as.factor(X3),
                UnixTime = as.integer(X4),
                Follower = as.integer(X5)) %>%
  dplyr::mutate(Time = as.POSIXct(as.Date(anytime(as.numeric(UnixTime),
                                                  tz = "Asia/Tokyo"))),
                Date = lubridate::date(Time)
  ) %>%
  dplyr::select(Year, Season, Anime, Time, Date, Follower) %>%
  dplyr::group_by(Date) %>%
  dplyr::arrange(desc(Time), .by_group = TRUE) %>%
  dplyr::distinct(Date, .keep_all = TRUE) %>%
  dplyr::ungroup() %>%
  dplyr::right_join(Base) %>%
  dplyr::full_join(data.frame(Date = lubridate::date(StartDay) + (seq(0:12) * 7 - 7),
                              OnAir = rep(1),
                              OnAirDate = lubridate::date(StartDay) + (seq(0:12) * 7 - 14))
  ) %>%
  dplyr::arrange(Date) %>%
  tidyr::replace_na(list(OnAir = 0)) %>%
  tidyr::fill(Year, Anime, Season, .direction = "down") %>%
  dplyr::filter(Date > as.POSIXct("2018-01-04") & Date < as.POSIXct("2018-04-04"))%>%
  dplyr::mutate(OnAir = ifelse(OnAir == 1, "放送日", "非放送日")) %>%
  dplyr::select(c(-"Year",-"Season",-"Anime")) %>% 
  as.data.frame()

これで一旦データは集まりました.多分.

2. データの前処理について

データの前処理のあとはグラフを出すコードを書きます. 仕様を大きく変えるとヴァイオレット・エヴァーガーデンの事例とうまく比較できなくなると思うので, 背景や色の変更はしておりません.
……そういうことにしてやってつかぁさい…… というかggplot2すっげえですね.最初はオプションつけまくれすぎて取り回しに困りましたが,
慣れるととっても面白いです. ソースコード載せようか迷いましたがMrUnadon氏のコードから変えたのは
- グラフの名前の部分
- x軸
のみなので,そちらを参照してください.

3. データの傾向について

さて,以上のコードを実行するとこういう感じのグラフたちがでてきます.

3.1. フォロワー数推移

こちらは純粋なフォロワー数の推移です.
f:id:kinuit:20180702191203p:plain
ものすごくきれいに対数関数めいた曲線を描いています.
ヴァイオレット・エヴァーガーデン』のグラフとも見比べてもらうとわかりますが,
最終回付近のジャンプがありません*2.映画化しないからでしょうか. きれいな曲線グラフがでてきて嬉しい半面,ヴァイオレット・エヴァーガーデンパワーに敵わなかったのがちょっと悔しいですね.

3.2. フォロワー数の増加量推移

さて,フォロワー数の増加量の推移を見てみます. f:id:kinuit:20180702191236p:plain
こちらも『ヴァイオレット・エヴァーガーデン』との比較をすると「放送日に伸びる」という点で大きな相違点があります.
アニメの放送前にはよく「今夜放送です!」という感じのツイートが回るようなので,そうしたツイートが効果を挙げていると解釈すれば
この推移は妥当なものかもしれません.

Twitterでこの画像を挙げたとき,MrUnadon氏本人から「8話の伸びは何でしょうか!?」というご質問をいただきました.
Twitterでもご回答しましたが水着回です.オタクは水着に弱いってはっきり……

4. おわりに

本当は「分析まで」と思いましたがリアルが忙しくなったり,Kaggleに本気で介入したくなったりして,記事の投稿がどんどん後回しになってしまいました.
「これ以上記事の投稿を遅らせるとお蔵入り確定だ」という気持ちに駆られ,とにかく「MrUnadon氏が残した課題を解決したかもしれない」という点や,アニメによってフォロワーの増え方,増加量の推移が異なるという可能性を基礎分析から示唆するところだけでも投下しておきます.ここからのベイズ分析とかはちょっとまた今度ってことで. 大きなソースコードの構成は変わっていませんし,データフレームの構築に至ってはほぼおんぶに抱っこです.
とはいえ,取得日の固定やデータの取得,リスト格納部分はそこそこ書き換えていますので,この記事を参照してエラーがでたらそれはこのブログの管理者たる私の責なので,そういうのあったら教えてください.

得られた結果について,グラフの傾向が『ヴァイオレット・エヴァーガーデン』と異なる点は検討の余地があると思われます.
ラーメン大好き小泉さん』のグラフ推移は,『ヴァイオレット・エヴァーガーデン』と比べれば「きれいな」結果になったかもしれません.
ただ,ここではアニメ別にフォロワーの増えるメカニズムが異なる可能性も示唆できていると思います.  データがちゃんと取れていれば,アニメのもつ何らかの属性(視聴ターゲット層やテーマ,プロダクション等)によってTwitterのフォロワー数の変化には違いがあるのかもしれません.
今後は複数の,そしてジャンルの異なるアニメ作品のデータを取得して比較する,というような展望も望めます.
……というのがデータがちゃんと取れている前提の解釈で,日付が1日ずつずれている可能性はあります……
いろいろ検証してみて,もし間違っていそうなら修正のために編集します……

*1:宗教上の理由です.

*2:よく見ると気持ちジャンプしていますが