サイトアイコン てくてくぷれいす

にじさんじのチャンネル登録者数とTwitterのフォロワーの相関を見るまで[Python]

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

そろそろYouTube Data APIを雑に触りたいので練習がてらソーシャルメディアをまたいだ関係分析をしてみたいと思います.

今回はVTuber事務所の1つであるにじさんじに所属するVTuberのYouTubeチャンネル登録者数とTwitterのフォロワー数に相関があるか雑に分析します.

にじさんじ所属のライバー一覧。プロフィールやソーシャル情報など。
にじさんじ ライバー一覧 | にじさんじ 公式サイト – にじさんじ 公式サイト

公式ページを見ると9x人弱いるのでTwitter,YouTubeのAPIを叩くための名前を取得するのもしんどいです.

なので公式ページからスクレイピングして雑な辞書に様々なデータを格納していくことにします.

追記:別のVTuber事務所であるhololiveについても行っています.

環境

スポンサーリンク

ライブラリのインポート

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

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

スポンサーリンク

各ライバーのページリンクを取得

url = 'https://nijisanji.ichikara.co.jp/member/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}

r = requests.get(url,headers=headers)
soup = BeautifulSoup(r.text,"lxml")

member_link_list = list()

for aa in soup.find_all("a"):
    link = aa.get("href")
    name = aa.get_text()
    mem_link = re.search("member/.+",link)
    if mem_link:
        member_link_list.append(link)

ライバーページからソーシャルメディアのid取得

先程のコードで各ライバーのページリンクを取得したのでそこからTwitter,YouTubeのリンクを取り出し,APIを叩くのに必要なidを辞書に格納していきます.

なお,緑仙さんはYouTubeのリンクが2つあり,サブの方が取得されてしまうのでそこは修正するかそのままにします.私は修正しました.

nizi_dic = dict()

for userlink in member_link_list:

    u = userlink
    ur = re.search("member/.+",u)
    ur = ur.group()
    ur = re.sub("member/","",ur)
    ur = re.sub("/","",ur)

    r = requests.get(userlink,headers=headers)
    soup = BeautifulSoup(r.text,"lxml")
    
    for aa in soup.find_all("a"):
        link = aa.get("href")
        t_link = re.search("twitter.com/.+",link)
        if t_link:
            tlink = t_link.group()
            tlink = re.sub("twitter.com/","",tlink)
            tlink = re.sub("/","",tlink)
            if not nizi_dic.get(ur):
                nizi_dic[ur] = dict()
            nizi_dic[ur]["twitter_id"] = tlink
        y_link = re.search("channel/.+\?",link)
        if y_link:
            ylink = y_link.group()
            ylink = re.sub("\?","",ylink)
            ylink = re.sub("channel/","",ylink)
            ylink = re.sub("/","",ylink)
            if not nizi_dic.get(ur):
                nizi_dic[ur] = dict()
            nizi_dic[ur]["youtube_id"] = ylink
            
    time.sleep(1)

スポンサーリンク

Twitter APIを叩く

config.pyに以下の値を埋めておきます.

CONSUMER_KEY = ""
CONSUMER_SECRET = ""
ACCESS_TOKEN = ""
ACCESS_TOKEN_SECRET = ""

Twitter APIの中からusers/showを使います.得られたデータからfollow数,follower数を取り出します.

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)

url = "https://api.twitter.com/1.1/users/show.json"

for user , dic in nizi_dic.items():
    params = {"screen_name":dic["twitter_id"]}
    res = twitter.get(url, params = params)
    time.sleep(5)
    if res.status_code == 200:
        timelines = json.loads(res.text) 
        follow = timelines["friends_count"]
        follower = timelines["followers_count"]
        nizi_dic[user]["follow"] = follow
        nizi_dic[user]["follower"] = follower

YouTubeのチャンネル登録者数を取得

GCP上でプロジェクトを作成し,YouTube Data APIを有効にしてAPI KEYを取得しておきます.

今回は雑にコード上にKEYを書きます.

API_KEY = ""
API_SERVICE_NAME = "youtube"
API_VERSION = "v3"
youtube = build(API_SERVICE_NAME, API_VERSION, developerKey=API_KEY)

for user , dic in nizi_dic.items():
    search_response = youtube.channels().list(id=dic["youtube_id"],part="statistics").execute()
    time.sleep(1)
    try:
        nizi_dic[user]["channelSub"] = search_response["items"][0]["statistics"]["subscriberCount"]
    except:
        print(user)

辞書を保存

前のプログラムの名残でsetという名前で保存してますがdicですね.

with open("nizisanji_set.pkl","wb") as f:
    pickle.dump(nizi_dic, f)

散布図をプロット・相関係数を計算

では必要なデータも得られたので散布図をプロットしていきます.

tw_follower_list = list()
yt_sub_list = list()
label_list = list()

for user,dic in nizi_dic.items():
    try:
        tw_follower_list.append(dic["follower"])
        yt_sub_list.append(int(dic["channelSub"]))
    except:
        print(user)
    label_list.append(user)

plt.figure(figsize=(16, 10), dpi=60)
plt.ylabel('Twitter Follower',fontsize = 24)
plt.xlabel('YouTube Subscriber',fontsize = 24)
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)
plt.scatter(yt_sub_list,tw_follower_list,color="#76c7bf")
plt.savefig("nizi_corr.png")
plt.show()

x軸はYouTubeのチャンネル登録者数,y軸はTwitterのフォロワー数です.

プロットされた結果を見るだけで正の相関がありそうなのはわかります.

ではとりあえずPearsonの相関係数を計算してみましょう.

import pandas as pd

s1=pd.Series(yt_sub_list)
s2=pd.Series(tw_follower_list)
res=s1.corr(s2,method="pearson")
print(res)

結果としては「0.9547178296315119」で強い相関があることがわかりました.

因果ではなく,相関があることがわかっただけですが….

まぁ個人的にはこの散布図で外れ値になってるユーザが気になるんですよね.

ということでplotlyを使用してグリグリ動かしながら確認したところ以下のユーザが確認されました.

  • Mikoto-Rindo
  • ars-almal
  • lulu-suzuhara
  • Utako-Suzuka
  • Ryushen

これらのユーザはYouTubeのチャンネル登録数に対して他のライバーよりもTwitterのフォロワーが少ないです.

これは以下の2つの理由が考えられます.

1つ目はそもそも該当ライバーがデビューしてから日数が浅いので認知が足らない可能性,2つ目はソーシャルメディア(Twitter)における活動頻度が低いもしくは告知ツイートが多く,通常のツイートが少ないのでフォローされていない可能性があります.

ですがこれはYouTubeのチャンネル登録数を軸に考えているだけで逆(Twitterのフォロワー数)から見るとYouTube上の活動が魅力的であり,ソーシャルメディアの活動の主がYouTubeにあるということもいえます.

Hololive(ホロライブ)の場合

上記と同様の手順でホロライブについてもデータを収集し,散布図をプロットしました.

ライバーの数は27人です.

相関係数は0.957と正の相関がにじさんじの場合と同様に得られています.層が3層っぽく別れているのが面白いです.

さいごに

今回はスクレイピングを使ってソーシャルメディアのAPIを叩く用意をし,データを取得してから散布図をプロットしました.

外れ値ユーザにはYouTubeにおいてコラボ等における認知の結果が強い可能性もあり,追加分析をする価値はあると思います.

APIを叩く練習を積んでいってもっと穿った目線から分析していけるようになりたいなと思います.

モバイルバージョンを終了