Python

にじさんじ,ホロライブが獲得できているユーザ層は同じなのではないかと思って調べてみた

こんにちは,しまさん(@nitkcdadon)です.

最近は収集できているデータの都合と興味もあって,VTuber関連ばかりの分析をしている気がします.

VTuber(ユーザ)の属性を決めているのは一体誰なのか~Twitterデータから分析する~VTuberの属性を決めるのは誰なのか,Twitterのデータを使用して分析します.フォロー,フォロワーを集合とすることで6種類のデータを作成し,wordcloudで可視化しています.これはソーシャルメディアでユーザの属性を決める際の1つの事例として十分な知見を得ることができます....
にじさんじのチャンネル登録者数とTwitterのフォロワーの相関を見るまで[Python]そろそろYouTube Data APIを雑に触りたいので練習がてらソーシャルメディアをまたいだ関係分析をしてみたいと思います. 今回はVTuber事務所の1つであるにじさんじ,hololive(ホロライブ)に所属するVTuberのYouTubeチャンネル登録者数とTwitterのフォロワー数に相関があるか雑に分析します. 公式ページからスクレイピングして雑な辞書に様々なデータを格納していくことにします....

前回の分析↑でにじさんじとホロライブのTwitterのフォロー数,フォロワー数,YouTubeのチャンネル登録者数は得ることができています.

今回はVTuberのTwitterのフォロワーのidを取得していこうと思います.

そして各事務所ごとにsetオブジェクトとしてidを集めることでそれぞれの事務所が抱えているユーザ数がわかります.

にじさんじとホロライブのid集合の積集合が大きければVTuberを追う人は思っている以上に実は少ないんじゃないか,VTuberの性質は事務所に依存しない可能性も考えられるので面白いです.

逆に積集合が小さければ固有のファンがいることがわかり,事務所によって抱えているユーザ層が違う可能性があるのでこれも面白いです.

つまりどっちに転んでも面白いので私がやらないわけがないということですね.

環境

  • macOS Catalina 10.15
  • Python 3.6.8

スポンサーリンク

ライブラリのインポート

※ 使用していないライブラリもあるので注意

from pprint import pprint
import os
import sys
import glob
import json
from bs4 import BeautifulSoup
from pathlib import Path
import re
import math
import requests
import collections
import numpy as np
import japanize_matplotlib
import matplotlib.pyplot as plt
import datetime
import time
import pickle
%matplotlib inline
from requests_oauthlib import OAuth1Session
from apiclient.discovery import build
from apiclient.errors import HttpError

スポンサーリンク

フォロワーのidを収集する

今回はにじさんじを例にとってデータ収集しますがホロライブも同様の手順でやっています.

にじさんじのライバー97名,ホロライブのライバー27名のフォロワーデータを集めていきます.

config.py,dicについては前回参照です.

にじさんじのチャンネル登録者数とTwitterのフォロワーの相関を見るまで[Python]そろそろYouTube Data APIを雑に触りたいので練習がてらソーシャルメディアをまたいだ関係分析をしてみたいと思います. 今回はVTuber事務所の1つであるにじさんじ,hololive(ホロライブ)に所属するVTuberのYouTubeチャンネル登録者数とTwitterのフォロワー数に相関があるか雑に分析します. 公式ページからスクレイピングして雑な辞書に様々なデータを格納していくことにします....
import config

CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK, CS, AT, ATS)

nizi_dic = dict()
with open("nizisanji_set.pkl","rb") as f:
    nizi_dic = pickle.load(f)

twid_list = list()
user_name_list = list()
for user , dic in nizi_dic.items():
    twid_list.append(dic["twitter_id"])
    user_name_list.append(user)

今回はTwitter API(followers/ids)を使用して該当ライバーのフォロワーidを集めていきます.一度に5000id収集でき,それを回すことで収集していきます.

url = "https://api.twitter.com/1.1/followers/ids.json"
user_follower_dic = dict()


for i in range(len(twid_list)):
    params = {"screen_name":twid_list[i]}
    user_follower_dic[user_name_list[i]] = set()
    res = twitter.get(url, params = params)
    cursor = 100
    _iter = 0
    if res.status_code == 200:
        timelines = json.loads(res.text) 
        ids = timelines["ids"]
        for id_ in ids :
            user_follower_dic[user_name_list[i]].add(id_)
        cursor = timelines["next_cursor"]
        print(cursor,len(user_follower_dic[user_name_list[i]]))
    while cursor != 0:
        time.sleep(60)
        params = {"screen_name":twid_list[i],"cursor":cursor}
        res = twitter.get(url, params = params)
        if res.status_code == 200:
            timelines = json.loads(res.text) 
            ids = timelines["ids"]
            for id_ in ids :
                user_follower_dic[user_name_list[i]].add(id_)
            cursor = timelines["next_cursor"]
        _iter += 1
        print("iter : ",_iter," cursor : ",cursor)
    print(i,user_name_list[i]+" : done")

with open("nizi_follower_dic_set.pkl","wb") as f:
    pickle.dump(user_follower_dic, f)

にじさんじの場合は大体36時間,ホロライブの場合は11時間ほどで収集が終わりました.idだけなのであまり時間がかからず取得できて満足です.

にじさんじのライバー全体で10,353,932 id,ホロライブのライバー全体で3,199,697 id集まりました.

にじさんじのライバーは平均10万6000フォロワー,ホロライブは平均11万8000フォロワーということになりますが,単純平均ではあまり違いはわかりません.

また,事務所単位で考えたい場合は重複しているidを除去する必要があります.

事務所ごとに抱えるユーザ集合を作成

先程データ収集したのは各ライバーごとに対するフォロワーidとなっています.そこで階層を1つ上げた(=事務所単位)ユーザ集合を作成し,事務所が抱えるユーザ数を調べていきます.

nizi_dic = dict()
with open("nizi_follower_dic_set.pkl","rb") as f:
    nizi_dic = pickle.load(f)

nizi_aid = set()
for user , follower in nizi_dic.items():
    follower_list = list(follower)
    for ff in follower_list:
        nizi_aid.add(ff)

with open("nizi_background_set.pkl","wb") as f:
    pickle.dump(nizi_aid, f)

にじさんじのユニークユーザー数は839,146,ホロライブのユニークユーザー数は600,787となりました.

…あれ??先程集めたデータから桁が1~2落ちてますね.

しかもユニークユーザー数が20万違うとはいえライバー数の差が3倍以上あることを考えるとにじさんじ側からすれば芳しい結果ではないかもしれません.

スポンサーリンク

VTuber事務所共通フォロワーユーザを得る

さきほどそれぞれの事務所のユニークユーザー数が取れ,setオブジェクトを用意できたのであとは積集合を計算するだけです.

holo_set = set()
with open("holo_background_set.pkl","rb") as f:
    holo_set = pickle.load(f)
nizi_set = set()
with open("nizi_background_set.pkl","rb") as f:
    nizi_set = pickle.load(f)

inter_set = set()
inter_set = nizi_set.intersection(holo_set)

結果,353,515ユーザが共通であることがわかりました.

つまり,差集合を計算することで事務所固有のファン数が推定されます.

にじさんじは485,631,ホロライブは247,272です.

固有ファンの割合がにじさんじは57.9%,ホロライブは41.15%ということですね.

所属ライバー数からなる認知の広がりやすさや広報の宣伝能力の差などもあるのかもしれませんがにじさんじのほうが固有ファンが多く,特定ライバーが好きな人が多い可能性が高いことが今回明らかになりました.

また,半数近いユーザは両方のライバーをフォローしており,複数の事務所ライバーを知っている,フォローしていることからVTuberに対する理解が深いユーザであることが推察され,このユーザ層に対してアプローチをかけることで各々の事務所は効果的な結果を得られることが期待されます.

また,固有ファンのユーザに対する分析をすすめることで事務所(=所属するライバー)にファンが求めていることが明らかになり,他の事務所と差別化を図ることや以降の新生ライバーの属性付与の参考になると考えられます.

さいごに

今回は前回集めた辞書とTwitter API(followers/ids)を使用してライバーのフォロワーのidを収集し,事務所ごとに統合することで事務所ごとのユニークユーザー数を明らかにしました.

また,それらの積集合を取ることで固有ファンの存在や共通で知っているユーザ数がかなり大きいことがわかりました.

今回いい感じのデータを取れたのでまた使い回したいと思います.

ABOUT ME
しまさん
てくてくぷれいす運営者のしまさんです. 高専→大学編入してから行動的な大学生  自身の変化を求めてブログを始める グレープフルーツと本が大好物 IT系のことやブログ,高専や編入,大学生活に関することを発信中!!詳しいプロフィールはこちら≫ 投げ銭はコチラへ YouTubeはコチラへ 質問はコチラ