Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@mypsychology0

全力回避フラグちゃん!の動画を再生回数と高評価でスコアリングしてランキング化してみた【正規化】【ランキング】

はじめに

今まで動画の再生回数や高評価をプロットしてきたが,これらを使って勝手に動画のスコアを定義してランキング化したい欲が急に出てきたので,公式も含め誰かにされる前に記事を作成してみた.今回は正規化なる手法を用いてみる.

今まで書いた記事はこちら↓↓
- 「全力回避フラグちゃん!」チャンネルの動画をグラフ化するとどうなるのか?【Python】【グラフ化】
- 全力回避フラグちゃん! の動画再生数の分布を調べてみた【Python】【グラフ化】
- 全力回避フラグちゃん!の動画の再生数と評価/コメント数をグラフにしたらどうなるのか?【Python】【グラフ化】
- 全力回避フラグちゃん!で少しわかるYouTube Data API Channels リソースから取得できる主な情報
- 全力回避フラグちゃん!のチャンネルの人気は本当にほぼフラグちゃんで成り立っているのか?【検証】【可視化】

注意事項

2021/1/13 18:30時点で取得した情報を利用しています.
ランキングはあくまでも用いたデータの中でのランキングです.
異論は存在します.

用いたデータセット/手法

YouTube Data API のVideos リソースを使用し,2021/1/13 18:30時点において,全力回避フラグちゃん! のチャンネルにアップロードされている全227本の動画再生回数と高評価数を取得し,それらの数値を用いてスコアリングをします.

スコアリングする際に,再生回数と高評価数を最小値0,最大値1の範囲で正規化を実施します.

ちなみに,データセットをグラフ化したものは以下の図になります.
あとで再生回数と高評価数が多い動画をリストアップします.このグラフで山になっている部分がリストアップされると思ってください.

2021-01-13_flag_videos_statistics_graph.png

数値の正規化

今回は、再生回数と高評価の2つのデータを使用します.しかし,再生回数と高評価の最大値,最小値,平均値,中央値は以下のようになっており,これらの数値をそのまま使用したのではいくら高評価が高くても,再生回数がその差を吸収してしまい,高評価を用いる意味が薄れてしまいます.1

データ 最大値 最小値 平均値 中央値
再生回数 3,279,627 8,568 784,836 650,006
高評価 28,272 1,069 8,509 7,524

そこで,双方の値を最小値は0,最大値は1とするよう正規化を実施することで値の差による影響を吸収します.2

再生回数と高評価を正規化した値同士を掛け合わせ,最後に100をかけたものを動画に対するスコアと定義します.
どちらの値も最小値が0,最大値は1なので,掛け合わせた数値も最小値は0,最大値は1となります.すなわち,スコアの値域は0~100となり,これで100点満点で動画をスコアリングできます.
ある動画$i$の再生回数は$v_i$,高評価数は$l_i$,それぞれの値の正規化を$v_{n_i}, l_{n_i}$とすると,その動画のスコア$S_i$は,

$$ S_i = v_{n_i} \times l_{n_i} \times 100, \ 0 \leq S_i \leq 100.$$

ただし,

$$v_{n_i} = \frac{v_i - v_{min}}{v_{max} - v_{min}}, \ 0 \leq v_{n_i} \leq 1$$

$$l_{n_i} = \frac{l_i - l_{min}}{l_{max} - l_{min}}, \ 0 \leq l_{n_i} \leq 1$$

です.ここで,添え字のmax, min はそれぞれの値の最大値,最小値を指しています.
また,$1 \leq i \leq N$であり,$N$は動画の本数で現時点で$N = 227$です.

候補となる動画

では,上記の式を用いて動画をスコアリングしていきます.その前にまずは上位に位置付けられそうな動画たちをピックアップします.
以下の表は,2021/1/13 18:30 時点での再生回数のトップ10の動画のタイトルと,その再生回数,高評価数です.

順位 (再生回数) タイトル 再生回数 高評価数 順位 (高評価数)
1 【無痛症】痛みを感じなくなった男の末路…【アニメ】【漫画動画】 3,279,627 28,272 1
2 【アニメ】整形中毒になるとどうなるのか…生まれ変われるってホント!?【漫画動画】 3,267,978 21,745 4
3 【漫画】もしも小人になったらどうなるのか?…あんなコトやこんなコトが…??【アニメ】【漫画動画】 2,964,358 26,078 2
4 5億年ボタンを押したらどうなるのか?【アニメ】【漫画動画】 2,256,964 18,486 6
5 【アニメ】冗談で告白した相手から恐怖の手紙が…→意外な真実が【漫画動画】 2,141,762 16,364 11
6 混浴風呂で知り合いと出会うとどうなるのか?【アニメ】【漫画動画】 1,978,827 18,107 7
7 服が透けて見えるメガネを手にした男の夢ある行動とは…【アニメ】【漫画動画】 1,932,898 14,076 17
8 【漫画】お風呂で寝ると失神する!?お風呂に入るうえで注意した方が良いこと【アニメ】【漫画動画】 1,892,814 15,558 12
9 もし性別が入れ替わったらどうなるのか?【アニメ】【漫画動画】 1,795,945 15,390 14
10 【漫画】糖尿病の本当の恐怖…あなたは大丈夫…?【アニメ】【漫画動画】 1,788,351 13,947 18

過去の動画が多く,最近の動画はないですね.やはり,再生回数は時間の積み重ねということでしょうか.

次に,2021/1/13 18:30 時点での高評価数のトップ10の動画のタイトルと,その再生回数,高評価数です.

順位 (高評価数) タイトル 再生回数 高評価数 順位 (再生回数)
1 【無痛症】痛みを感じなくなった男の末路…【アニメ】【漫画動画】 3,279,627 28,272 1
2 【漫画】もしも小人になったらどうなるのか?…あんなコトやこんなコトが…??【アニメ】【漫画動画】 2,964,358 26,078 3
3 死亡フラグの1DAYルーティン【アニメ】【漫画動画】 925,564 21,923 68
4 【アニメ】整形中毒になるとどうなるのか…生まれ変われるってホント!?【漫画動画】 3,267,978 21,745 2
5 【究極の選択】金と人の命はどちらが大事なのか…?【アニメ】【漫画動画】 393,835 21,713 194
6 5億年ボタンを押したらどうなるのか?【アニメ】【漫画動画】 2,256,964 18,486 4
7 混浴風呂で知り合いと出会うとどうなるのか?【アニメ】【漫画動画】 1,978,827 18,107 6
8 【ストーリー編】第1話「修行のはじまり」【アニメ】【漫画動画】 1,505,448 17,433 18
9 【新キャラ】ガンになるとどうなるのか…最強のフラグが!?【漫画動画】 1,580,870 16,936 15
10 首都直下地震が起きたらどうなるのか【アニメ】【漫画動画】 1,655,101 16,901 12

こちらには,最近公開された動画もちらほらあります.再生回数の面で不利になりますが,どこまで高いスコアがつけられるか...

上記の表の中にある動画から,本記事のスコアリングによるトップ10の動画が出るはずです.

ランキング結果

それでは,上記スコアリングによるランキング結果です.
トップ10を表にしました.スコアは,小数点以下第二位まで有効数字です.

順位 (スコア) タイトル スコア 再生回数 高評価数
1 【無痛症】痛みを感じなくなった男の末路…【アニメ】【漫画動画】 100.00 3,279,627 28,272
2 【漫画】もしも小人になったらどうなるのか?…あんなコトやこんなコトが…??【アニメ】【漫画動画】 83.31 2,964,358 26,078
3 【アニメ】整形中毒になるとどうなるのか…生まれ変われるってホント!?【漫画動画】 75.74 3,267,978 21,745
4 5億年ボタンを押したらどうなるのか?【アニメ】【漫画動画】 44.01 2,256,964 18,486
5 混浴風呂で知り合いと出会うとどうなるのか?【アニメ】【漫画動画】 37.73 1,978,827 18,107
6 【アニメ】冗談で告白した相手から恐怖の手紙が…→意外な真実が【漫画動画】 36.67 2,141,762 16,364
7 【漫画】お風呂で寝ると失神する!?お風呂に入るうえで注意した方が良いこと【アニメ】【漫画動画】 30.68 1,892,814 15,558
8 首都直下地震が起きたらどうなるのか【アニメ】【漫画動画】 29.30 1,655,101 16,901
9 もし性別が入れ替わったらどうなるのか?【アニメ】【漫画動画】 28.77 1,795,945 15,390
10 服が透けて見えるメガネを手にした男の夢ある行動とは…【アニメ】【漫画動画】 28.13 1,932,898 14,076

思ったよりもスコアが低くなってしまった.式の定義が甘かったか...
ちなみに,スコアの平均値は8.71,中央値は4.76です.
上記のランキングに載っている動画たちは平均の3倍以上の数値は持っているので,再生回数も高評価数も十分高い人気動画であるといえます.もう少し高いスコアが出るように定義してやるべきだった...

簡単な解説

各動画を簡単に解説していきます.なお,著作権に配慮して動画のURLは載せますが,サムネイルは載せません.ご了承ください...3
はてなブログのほうに補完記事という意味合いで埋め込み使って紹介しています.

1位: 【無痛症】痛みを感じなくなった男の末路…【アニメ】【漫画動画】

ランキングする前から,再生回数,高評価数ともに1位だったので,ランキングする前からスコア100で1位になるは目に見えていましたね.
動画の内容もとても良いので,まだ見てない人がいたら,今すぐリンクから動画を視聴してください.

2位: 【漫画】もしも小人になったらどうなるのか?…あんなコトやこんなコトが…??【アニメ】【漫画動画】

再生回数は300万回を下回るものの,高評価数で2位につけたため,本ランキングでも再生回数の差をはねのけて2位につけました.サムネイルと本編の内容が一致しており,好評??

3位: 【アニメ】整形中毒になるとどうなるのか…生まれ変われるってホント!?【漫画動画】

再生回数では300万越えで2位につけていましたが,高評価数の影響で3位になりました.少し前まで再生回数1位だったような...サムネイルと本編の内容が一致しており,好評??

4位: 5億年ボタンを押したらどうなるのか?【アニメ】【漫画動画】

再生回数が4位で,再生回数と同じ順位となりました.14:14 という珍しい長編となっており,内容もよいので素晴らしい動画です.ほかのYouTuber もこの手の内容の動画は再生回数多いですよね.

5位: 混浴風呂で知り合いと出会うとどうなるのか?【アニメ】【漫画動画】

再生回数6位で,高評価数7位です.2日前の動画に高評価数抜かれていましたが,人気の動画です.サムネイルと本編の内容が一致しており,好評??

6位: 【アニメ】冗談で告白した相手から恐怖の手紙が…→意外な真実が【漫画動画】

再生回数は5位,しかし高評価数は11位で,高評価数の影響により順位が微減しました.
サムネイルと本編の内容が一致しており,好評??

7位: 【漫画】お風呂で寝ると失神する!?お風呂に入るうえで注意した方が良いこと【アニメ】【漫画動画】

再生回数8位,高評価数12で,同じく高評価数で順位微減です.
こちらも,サムネイルと本編の内容が一致しており,好評??

8位: 首都直下地震が起きたらどうなるのか【アニメ】【漫画動画】

ランキングに入っている動画の中では,一番最近(2020/9/19)の動画です.
再生回数12位,高評価数10ですが,ランキング上位に入ってきました.
この動画の内容はためになる上に,最後が感動的でよかったです.
そのあたりが上位の入賞への原動力だったのかな...

9位: もし性別が入れ替わったらどうなるのか?【アニメ】【漫画動画】

こちらは,2020/9/1 公開で次に最近の動画ですね.
再生回数9位,高評価14位でした.
サムネイルが好評??

10位: 服が透けて見えるメガネを手にした男の夢ある行動とは…【アニメ】【漫画動画】

最後です.再生回数が200万回近くで7位,高評価数は17位です.
こちらも,サムネイルと本編の内容が一致しており,好評??

基本は,再生回数が上位の動画ほどランキング上位に来ますが,その中で高評価数により,順位が再生回数と異なる,という結果になりました.

最近公開された動画で特に高評価数が高い死亡フラグの1DAYルーティン【アニメ】【漫画動画】と,【究極の選択】金と人の命はどちらが大事なのか…?【アニメ】【漫画動画】が,もう少しして再生回数が高評価数に追いつくほど増えてきたら,ランキングがどう変わってくるのか興味があります.(各々スコアは現時点で21.498.94でした.前者はもう少しかも...)

簡単なまとめ

  • 勝手にスコアを定義してランキング付け面白かった
  • 正規化も正しくしてあげないと,見栄えが微妙になる
  • 高評価でランキング付けると最近の動画が出てきて面白かった
  • やっぱNo. 1は【無痛症】痛みを感じなくなった男の末路…【アニメ】【漫画動画】だった
  • ランキング上位の動画はサムネイルと本編の内容が一致していることが,人気の秘訣っぽい

今後の予定

他にも気になることがあったら,記事を作成していきます.

今回紹介した動画

上に書いたので,省略します.

おわりに

公式でも視聴者に対して人気投票を1周年記念 の際に実施していましたが,その結果が本記事の結果とどれくらい異なってくるのか,楽しみです.一応今回のランキング上位に来た動画は投票の際にはすでに公開されていた動画なので,すべて見比べることができるはずです.
公式の投票は視聴者の主観的なランキング,今回実施したのは再生回数と高評価数という2つの数値によるランキング,どう異なってくるのか非常に楽しみです.

ここまで読んでいる人はいないと思いますが,もしいたらまずは,以下のリンクから全力回避フラグちゃん! チャンネルとフラグちゃんのTwitter をフォローしてください.この記事を読むより大切なことです.
大事なことなのでもう一度,チャンネル登録Twitter のフォローをよろしくお願いいたします.

関連リンク

おまけ

再生回数と高評価をプロットしているプログラムに,スコアを計算する記述を追加しています.

スコア計算プログラム
import os
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import matplotlib.dates as mdates
import matplotlib.patches as mpatches
from matplotlib.path import Path
import matplotlib
from matplotlib.font_manager import FontProperties
from matplotlib import rcParams
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

#データセット対象のCSV ファイル
file = sys.argv[1]
output_file = sys.argv[2]
#Date, 再生回数
num_play = pd.read_csv(file, header=0, encoding='UTF8', usecols=[3, 5], parse_dates=[0])
num_play = num_play.dropna(how='all')
#Date, Like
num_like = pd.read_csv(file, header=0, encoding='UTF8', usecols=[3, 6], parse_dates=[0])
num_like = num_like.dropna(how='all')
#Date, DisLike
num_dislike = pd.read_csv(file, header=0, encoding='UTF8', usecols=[3, 7], parse_dates=[0])
num_dislike = num_dislike.dropna(how='all')
#Date, コメント数
num_comment = pd.read_csv(file, header=0, encoding='UTF8', usecols=[3, 8], parse_dates=[0])
num_comment = num_comment.dropna(how='all')

#Plot するグラフ
#Date
x = num_play[num_play.columns[0]]


#x = pd.date_range(x[0], x[218], freq='D')
#再生回数
y1 = num_play[num_play.columns[1]]
#Like
y2 = num_like[num_like.columns[1]]
#DisLike
y3 = num_dislike[num_dislike.columns[1]]
#コメント
y4 = num_comment[num_comment.columns[1]]

#########################################
#Score
vn = []
ln = []
score = []

for i in range(len(num_play)):
    vn.append((y1[i] - min(y1)) / (max(y1) - min(y1)))
    ln.append((y2[i] - min(y2)) / (max(y2) - min(y2)))
    score.append(vn[i] * ln[i] * 100)

df = pd.DataFrame(score)
df.index = np.arange(1, len(df) + 1)
df.to_csv("flag_videos_score.csv", header=False, index=True)
##########################################


#フォント設定
#plt.rcParams['font.family'] = 'Times New Roman'
font_path = '/usr/share/fonts/truetype/takao-gothic/TakaoPGothic.ttf'
font_prop = FontProperties(fname=font_path)
matplotlib.rcParams['font.family'] = font_prop.get_name()

fig = plt.figure(figsize=(20.0, 12.0), dpi=300)
ax1 = fig.add_subplot()

# グラフプロット
## 再生回数を棒グラフでプロット
play = ax1.bar(x, y1, width=1.0, bottom=None, color="lightblue")

## Like, Dislike, Commnetを折れ線でプロット
ax2 = ax1.twinx()
like, = ax2.plot(x, y2, color='r')
dislike, = ax2.plot(x, y3, color='b')
comment, = ax2.plot(x, y4, color='k')

##### Story #################################################################################
s1, = ax2.plot(x[59], y2[59], marker='*', markersize=20, color='#ff7f00', linestyle='None')
s2, = ax2.plot(x[74], y2[74], marker='*', markersize=20, color='#ff7f00', linestyle='None')
s3, = ax2.plot(x[95], y2[95], marker='*', markersize=20, color='#ff7f00', linestyle='None')
s4, = ax2.plot(x[125], y2[125], marker='*', markersize=20, color='#ff7f00', linestyle='None')
s5, = ax2.plot(x[195], y2[195], marker='*', markersize=20, color='#ff7f00', linestyle='None')
s6, = ax2.plot(x[228], y2[228], marker='*', markersize=20, color='#ff7f00', linestyle='None')
##############################################################################################

# 軸の範囲
ax1.set_xlim('2019-11-01', x[len(x) - 1])
ax1.set_ylim([0, 3500000])
ax2.set_ylim([0, 30000])

print("Sum of likeCount:" + str(sum(y2)))
print("Max likeCount:" + str(max(y2)))
print("Average likeCount:" + str(num_like.mean(axis=0)))
print("Median likeCount:" + str(num_like.median(axis=0)))
print("Max comment count:" + str(max(y4)))
print("Average comment count:" + str(num_comment.mean(axis=0)))
print("Median comment count:" + str(num_comment.median(axis=0)))

# グラフタイトル
ax1.set_title("全力回避フラグちゃん! 再生回数と評価数", fontname="TakaoPGothic", fontsize=20)

# 軸メモリ
ax1.tick_params(axis='x', labelsize=20, labelrotation=45)
ax1.tick_params(axis='y', labelsize=20)
ax2.tick_params(axis='y', labelsize=20)

# ラベル名
ax1.set_xlabel("動画公開日", fontsize=20, fontname="TakaoPGothic")
ax1.set_ylabel("再生回数", fontname="TakaoPGothic", fontsize=20)
ax2.set_ylabel("評価/コメント数", fontname="TakaoPGothic", fontsize=20, rotation=270, labelpad=30)

# 凡例
play_title = "再生回数"
like_title = "高評価"
dislike_title = "低評価"
comment_title = "コメント"
s_title = "ストーリー編"

plt.legend([play, like, dislike, comment, s1], [play_title, like_title, dislike_title, comment_title, s_title], bbox_to_anchor=(1.0, 1.0), prop={"family":"TakaoPGothic", 'size':20}, markerscale=3)

#画像保存
plt.savefig(output_file, bbox_inches="tight", pad_inches=0.0)

  1. まあ,最近公開された動画は高評価数が多くても,再生回数は少ないので,結局スコアは低くなります.また時間をおいてから実施すると結果が違ってきて面白いかも. 

  2. この方法がどれほど適切なのかは不明.なので,今回結果をまとめてみた. 

  3. 調べたけど,埋め込みも使えないらしい...はてなにも上げようかな... 

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What is going on with this article?