はじめに
これは、YouTube動画の再生パフォーマンスをデータで分析するシリーズの4本目です。
このYouTube分析シリーズの記事はこちらです。今後の記事もここに追加していきます。
- 第1回: YouTube動画はどんな要素が再生パフォーマンスに関連しているのか?
- 第2回: YouTube動画は「同じチャンネル内で当たる」のか?ロジスティック回帰で分析する
- 第3回: AIが勝手にロバスト標準誤差を入れてきたので、回帰分析コードを読んでみた
- 第4回: この記事
- 第5回: 固定効果の次に、階層ベイズで「チャンネル差」をもう少し丁寧に見る
- 第6回: 広告クリエイティブを個人で集めようとして分かったこと
第1回では、YouTube Data APIで取得した公開メタデータを使って、動画の再生パフォーマンスを重回帰分析しました。
登録者数、動画尺、公開後日数、公開時刻、公開曜日、ジャンルなどを入れて、「どの変数が再生パフォーマンスと関係していそうか」を見ました。
ただ、そのあとでずっと引っかかっていたことがあります。
それは、「結局、チャンネルが強いだけなのでは?」ということです。
登録者数を入れても、ジャンルを入れても、チャンネルごとの違いはまだ残りそうです。同じ登録者数でも、ファンの熱量、企画の型、出演者、編集スタイル、シリーズ性、過去の積み重ねは違います。
そこで今回は、チャンネルを個別の固定効果として解釈してモデルに入れる形で、回帰分析を見直します。
ただ、これは自分が最初から「よし、個体固定効果でいこう」と設計したものではありません。AIが分析の流れの中で「こうするといいですよ」という感じで C(channel_id) を入れてきました。コードは動きます。結果もそれっぽく出ます。便利ではあります。
でも、あとから見ると、自分の理解より先に専門用語とコードが進んでいました。
「固定効果って、結局何を固定しているのか」
「チャンネル別のダミー変数を入れることと、チャンネルごとに別々の回帰分析をすることは同じなのか」
このあたりを曖昧にしたままだと、結果の読み方も曖昧になります。
なのでこの記事は、固定効果を分かった人として解説する記事ではありません。AIが入れてきた C(channel_id) が何をしているのかを、後追いで確認する記録です。
個体固定効果とは
個体固定効果とは、個体ごとの平均的な違いをモデルの中で吸収する考え方です。
企業データなら企業固定効果、学校データなら学校固定効果、と呼ばれるようです。今回の個体はYouTubeチャンネルなので、チャンネルを個別の固定効果として扱うことになります。
いったん自分の理解で言うと、「チャンネルごとの平均的な強さを、モデルの中で補正する」ということです。
たとえば、登録者数やジャンルを入れても、「このチャンネルはそもそも強い」「固定ファンが多い」「企画の型がある」といった差は残ります。そういうチャンネルごとの差を、それぞれのチャンネル専用の基準値として持たせるイメージです。
イメージとしては、こうです。
第1回の見方:
チャンネル間の違いも含めて、動画の再生パフォーマンスを見る
今回の見方:
チャンネルを個別の固定効果として扱い、基礎的な強さを補正したうえで、
同じチャンネル内で動画ごとの違いを見る
「登録者数が多いチャンネルだから伸びた」というような差をどこまで吸収できるのか。そのうえで、モデル全体の説明力がどう変わるのかを見ます。
今回のモデル
今回は、第1回で使った代表的なモデルA3と、チャンネルを個別の固定効果として扱うモデルA4を比較します。
A3は、第1回で使った「ジャンルまで入れたモデル」です。
log_views_per_day ~
duration_min_c
+ duration_min_c2
+ log_subscriber_count
+ log_channel_video_count_in_sample
+ days_since_publish
+ C(published_hour_jst)
+ C(published_weekday_jst)
+ C(genre)
A4では、チャンネルを個別の固定効果として解釈します。コード上は、channel_id をカテゴリ変数として入れます。
log_views_per_day ~
duration_min_c
+ duration_min_c2
+ days_since_publish
+ C(published_hour_jst)
+ C(published_weekday_jst)
+ C(channel_id)
statsmodels のFormulaで C(...) と書くと、その変数をカテゴリ変数として扱います。つまり、channel_id を数値の大小ではなく、「どのチャンネルか」という分類として読むわけです。
今回のデータには58チャンネルあります。
通常のOLSでは切片が入るため、カテゴリ変数を入れると、基準カテゴリを1つ残し、それ以外のカテゴリに対応するダミー変数が作られます。今回なら、イメージとしては57個のチャンネル用ダミー変数が追加されます。
C(channel_id)
-> channel_id[T.チャンネルB]
-> channel_id[T.チャンネルC]
-> channel_id[T.チャンネルD]
-> ...
基準になるチャンネルとの差として、それぞれのチャンネル固有の平均的なズレを推定している、と考えると少し整理しやすくなりました。
すべてのチャンネルについてダミー変数を作るわけではありません。切片と全チャンネルのダミーを同時に入れると完全に重複するため、いわゆる「ダミー変数トラップ」を避ける形で基準カテゴリが1つ落とされます。
ここで気をつけたいのは、これがチャンネルごとの個別回帰と同じではない、という点です。
| 見方 | チャンネルごとの切片 | 動画尺や公開タイミングなどの係数 |
|---|---|---|
今回の C(channel_id)
|
チャンネルごとに違う | 全チャンネルで共通 |
| チャンネルごとの個別回帰 | チャンネルごとに違う | チャンネルごとに違う |
つまり、今回の C(channel_id) は、「チャンネルごとに別々の回帰式を作る」というより、「全体で1本の回帰式を作りつつ、チャンネルごとの平均的な高さだけ補正する」ものです。
ここが混ざると、「チャンネルごとに別々の回帰分析をしているのかな」と読まれてしまいます。今回やっているのは、チャンネルごとの基準値の違いを吸収して、そのうえで動画単位の変数を見ることです。
もし本当に「動画尺の効果も、公開タイミングの効果も、チャンネルごとに違うはずだ」と考えるなら、今回のように基準値だけを補正するモデルでは足りません。そこまで扱うなら、交互作用を入れるか、階層ベイズのような考え方が必要になりそうです。
ここで、A4からは log_subscriber_count と C(genre) を外しています。
理由は、チャンネルを個別の固定効果として扱うと、チャンネルごとにほぼ固定されている情報がかなり吸収されるからです。
登録者数やジャンルはチャンネル単位の情報です。C(channel_id) と一緒に入れると、どちらが何を説明しているのかがかなり読みにくくなります。今回は、まずチャンネルごとの基準値を補正したモデルとして見たいので外しました。
データ
データは第1回と同じです。
| 項目 | 内容 |
|---|---|
| 動画数 | 1,204本 |
| チャンネル数 | 58チャンネル |
| ジャンル数 | 6ジャンル |
| チャンネルあたり動画数の中央値 | 24本 |
| チャンネルあたり動画数の最小値 | 2本 |
| チャンネルあたり動画数の最大値 | 30本 |
チャンネルを個別の固定効果として扱うので、チャンネルあたりの動画数は重要です。
中央値は24本ありますが、最小は2本です。2本しかないチャンネルで「そのチャンネル内の違い」を安定して見るのは、かなり無理があります。
なので、ここも注意が必要です。このモデルにすれば全部解決する、というものではありません。
モデルの説明力
まず、モデル全体の説明力を比較します。
| model | nobs | R² | adj.R² | AIC | BIC |
|---|---|---|---|---|---|
| A3_genre | 1204 | 0.611 | 0.598 | 3652.2 | 3850.8 |
| A4_channel_fe | 1204 | 0.805 | 0.790 | 2916.6 | 3370.0 |
チャンネルを個別の固定効果として扱うと、R²は0.611から0.805まで上がりました。差分は約0.195です。
ここは、かなり大きく変わりました。
ただ、これを見て「固定効果すごい」とだけ言うのは少し危ない気もします。チャンネル用のダミー変数をたくさん入れているので、説明力が上がること自体はある程度自然です。
それでも、AICやBICも改善しているので、少なくとも今回のデータでは、チャンネルごとの基準値をモデルに入れる意味はかなりありそうです。
今回の一番大きな結果はここです。
ただし、「動画単体の細かい特徴より、チャンネルごとの違いの方が大事だ」と言い切るのも、少し強すぎる気がします。少なくとも今回のモデルでは、チャンネルごとの基準値を補正すると説明力が大きく上がった。そこまでは言えそうです。
何が分かったのか、というより何を考え直したのか
今回の結果を見て、最初に思ったのは、YouTube動画の再生パフォーマンスは「どのチャンネルの動画か」にかなり左右されていそうだ、ということでした。
ここから考えると、「YouTube動画に一般的に効く特徴は何か」という問いは、少し危うく見えてきます。
もちろん、動画の作り方にベストプラクティスがまったく存在しない、と言いたいわけではありません。分かりやすいタイトル、視聴者の期待に合う企画、冒頭で離脱されにくい構成には、おそらく意味があります。
ただ、それらがどのチャンネルでも同じように効くかというと、かなり怪しいです。
チャンネルには、ジャンル、視聴者層、固定ファン、投稿の歴史、企画の型、演者への信頼、シリーズ性があります。そうした文脈を無視して「YouTubeではこうすれば伸びる」と一般化するのは、少し乱暴なのかもしれません。
むしろ見るべきなのは、「YouTube一般に効く特徴」ではなく、「そのチャンネルの文脈の中で、どんな動画が相対的に伸びるのか」なのかもしれません。
チャンネルを個別の固定効果として扱うと、問いが変わります。
チャンネルを固定効果として扱わない:
チャンネル間の違いも含めて、動画特徴と再生パフォーマンスを見る
チャンネルを個別の固定効果として扱う:
同じチャンネルの中で、動画ごとの違いを見る
第1回のモデルは、公開メタデータ全体で再生パフォーマンスを説明するモデルでした。今回のモデルは、チャンネルの基礎的な強さを補正したうえで、動画単位の違いを見るモデルに近いです。
分析が失敗したというより、分析を進めたことで問いの立て方が変わってきた、という感じです。
最初は動画単体の特徴を探していたつもりでした。しかし数字を見ると、先にチャンネルという単位の強さが見えてきました。
ここで、「じゃあ動画単体の特徴は意味がない」とまでは言えません。ただ、少なくとも今回のデータでは、チャンネル差を無視して動画特徴だけを見るのは、かなり雑だったのかもしれないと思いました。
このあたりは、分析手法の問題というより、自分の問いの出し方の問題でもあります。
「チャンネルの強さをどう扱うのか」をちゃんと決めないまま、動画特徴だけを見ようとしていた。そこにAIが固定効果という方法を入れてきて、私はあとからそれを追いかけて理解した。今回の記事は、かなりその順番に近いです。
次にやりたいこと
次に見たいのは、チャンネルごとの違いをもう少し丁寧に扱う方法です。
今回の分析では、チャンネルを個別の固定効果として扱うとR²が大きく上がりました。これは、チャンネルごとの基礎的な違いが、再生パフォーマンスをかなり説明していることを示していそうです。
ただし、固定効果は「チャンネルごとの差がある」ことを吸収してくれる一方で、その差がどのような構造を持っているのかまでは、あまり教えてくれません。
どのチャンネルがどれくらい違うのか。その違いはどの程度ばらついているのか。似たチャンネル同士で何か共通点があるのか。
そこはまだ残っています。
次にやるなら、階層ベイズ回帰を試してみたいと思っています。
と言いつつ、ここもまだ「分かっているから使う」というより、「今回の問題を考えるなら、たぶん避けて通れなさそうだから勉強する」に近いです。
今回の固定効果モデルでは、チャンネルごとの差をダミー変数として入れました。一方で、階層ベイズでは、チャンネルごとの差を「全体の分布から生まれたズレ」として扱えるようです。さらに、うまく設計すれば、チャンネルごとに係数が少しずつ違う、という見方にも近づけるのかもしれません。
正直、この時点でだいぶ難しくなっています。ただ、今回のモデルで「基準値だけをチャンネルごとに変える」ことと、「係数までチャンネルごとに違うと考える」ことは別だと分かったので、次に進むならそこをちゃんと扱いたいなとは思っています。

