はじめに
これは、YouTube動画の再生パフォーマンスをデータで分析するシリーズの5本目です。
このYouTube分析シリーズの記事はこちらです。今後の記事もここに追加していきます。
- 第1回: YouTube動画はどんな要素が再生パフォーマンスに関連しているのか?
- 第2回: YouTube動画は「同じチャンネル内で当たる」のか?ロジスティック回帰で分析する
- 第3回: AIが勝手にロバスト標準誤差を入れてきたので、回帰分析コードを読んでみた
- 第4回: YouTube動画は「どのチャンネルか」でどこまで変わるのか?固定効果で回帰分析を見直す
- 第5回: この記事
- 第6回: 広告クリエイティブを個人で集めようとして分かったこと
前回は、チャンネルを個別の固定効果として解釈してモデルに入れるところまでやりました。
そこで分かったのは、チャンネル別ベースラインを入れると、モデルの説明力がかなり上がるということでした。
ただ、前回の記事を書きながら、ここで終わりではなさそうだとも思っていました。
チャンネル差を入れると説明力が上がることは分かりました。でも、そのチャンネル差の中身は、まだまだ深掘りできそうでした。
固定効果モデルでは、チャンネルごとの平均的な土台を分けます。けれども、そのチャンネル差を「58個の別々のダミー変数」として持つだけだと、チャンネル差そのものがどういう分布をしているのかはあまり見えません。
さらに、前回のモデルでは「チャンネル別ベースラインは違うけれど、動画尺などの係数は全チャンネルで共通」という扱いでした。
でも、実際には、動画尺の効き方もチャンネルによって違うかもしれません。
ここまで来ると、普通の重回帰分析からかなり離れてきた感じがあります。
正直、階層ベイズという言葉を出すだけで、自分でも「急に難しくなったな」と思います。この記事も、階層ベイズを分かった人として説明するものではありません。前回の固定効果で見えてしまった問題を、もう少しだけ丁寧に扱うために、試しに階層モデルを組んでみた記録です。
この記事に出てくる整理も、自分が最初からそう考えられていたものではありません。出てきたモデルの意味を後から確認しながら、「たぶんこういう見方をしているのか」と自分用に噛み砕いているものです。
固定効果でまだ残っていた違和感
前回の固定効果モデルは、おおまかに言うとこうでした。
log_views_per_day =
チャンネル別ベースライン
+ 動画尺の係数 * 動画尺
+ 公開後日数の係数 * 公開後日数
+ ...
このとき、チャンネル別ベースラインは別々です。
一方で、動画尺や公開後日数の係数は、全チャンネルで共通です。
ここも前回、後から教えてもらってようやく少し整理できたところです。固定効果モデルは「チャンネルごとに別々の回帰分析をしている」わけではなく、全体で1本の回帰式を作りながら、チャンネルごとの平均的な高さだけを変えている、という理解でよさそうです。
ここを押さえておかないと、結果の読み方がずれそうです。
ただ、ここで次の疑問が出ます。
「チャンネル別ベースラインは、完全に別々のものとして扱っていいのか」
「動画尺の係数も、チャンネルごとに少し違うと考える方法があるらしい」
こうなると、固定効果だけでは少し足りない感じが出てきます。
階層ベイズで何を変えるのか
今回やったことを、教えてもらった説明を借りてかなりざっくり言うと、こうです。
固定効果:
チャンネルAのベースライン
チャンネルBのベースライン
チャンネルCのベースライン
...
を、それぞれ別々に推定する
階層ベイズ:
チャンネル別ベースラインは、
「チャンネル全体の分布」から生まれたズレとして考える
固定効果では、チャンネルごとの差を、そのまま個別に持つ、という理解です。
階層ベイズでは、どうやら「チャンネル別ベースラインには、全体としてこれくらいのばらつきがある」という分布を置くらしいです。そのうえで、各チャンネルのベースラインを推定します。
ここで教えてもらって腑に落ちたのが、完全に別々でも、完全に同じでもないという点です。
チャンネルごとに十分なデータがあれば、そのチャンネル自身の情報が強く反映されます。一方で、動画数が少ないチャンネルでは、推定が全体平均の方に寄ります。
この「寄る」感じが、固定効果とは違うところらしいです。
固定効果だと、動画が2本しかないチャンネルでも、そのチャンネル専用のベースラインをかなり素直に持ってしまいます。階層モデルでは、「いや、2本だけでそのチャンネルの個性を強く言い切るのは怖いよね」という方向に自然に寄せられます。
たぶん、ここが今回いちばん見たかったところでした。
ベイズ統計学、マジで優秀ですね。
何を計算しているのか
階層ベイズと言われると急に難しく感じます。そこで、計算イメージを自分用に図にするとこうなりました。
まず、動画ごとの log_views_per_day という観測データがあります。
次に、それぞれの動画は「そのチャンネルのベースライン」と「動画尺などの係数」から生まれたものだと考えるようです。
ただし、チャンネル別ベースラインを完全にバラバラに置くのではなく、全チャンネルに共通する分布から生まれたものとして扱います。
流れをかなり単純化すると、次のような感じです。
チャンネル全体の分布を仮定する
↓
各チャンネルのベースラインを推定する
↓
各動画の再生パフォーマンスを説明する
↓
データに合うように、全体分布と各チャンネルの値を更新する
今回のコードでは、この更新をGibbsサンプラーで繰り返しています。
ただ、Gibbsサンプラーの中身はそれだけで別テーマになりそうです。今回はそこまで追い切れないので、いったん脇に置きます。ここでは、階層モデルを入れるとチャンネル差の見方がどう変わるのかに絞ります。
なので、出てくる結果は「係数はこの1点です」ではなく、「このくらいの範囲にありそうです」という形になります。ここも、ベイズっぽさとして自分にはまだ新鮮でした。
今回のモデル
目的変数は、これまでと同じ log_views_per_day です。
今回は、チャンネルごとに次の2つが違うかもしれない、というモデルにしました。
- チャンネル別ベースライン
- 動画尺の係数
式っぽく書くと、こういう形です。正直、ここはまだ「完全に手になじんでいる」というより、モデルの形を見ながら意味を追っている段階です。
log_views_per_day_i =
alpha_channel[i]
+ beta_duration_channel[i] * duration_z_i
+ beta_duration2 * duration_z2_i
+ beta_days * days_z_i
+ beta_evening * evening_z_i
+ beta_weekend * weekend_z_i
+ error_i
alpha_channel[j] ~ Normal(mu_alpha, sigma_channel_intercept)
beta_duration_channel[j] ~ Normal(mu_duration, sigma_channel_duration_slope)
alpha_channel[j] が、チャンネル別ベースラインにあたる部分です。
beta_duration_channel[j] が、チャンネルごとの動画尺の係数にあたる部分です。
一方で、動画尺の二乗、公開後日数、夜公開、週末公開は、全チャンネル共通の係数にしています。
登録者数やジャンルは入れていません。理由は前回と同じで、チャンネル単位の情報とかなり重なるからです。チャンネル差をモデルに入れているのに、そこへさらにチャンネル単位の変数を入れると、何を読んでいるのかかなり分かりにくくなります。
チャンネル別ベースラインとは何か
ここでいうチャンネル別ベースラインは、前回まで「チャンネルごとの基準値」と呼んでいたものです。ただ、基準値という言い方だけだと、正直少し分かりにくいです。
この記事では、同じものをチャンネル別ベースラインと呼ぶことにします。この言い方も、正確な専門用語というより、自分が読みやすくするための言い換えです。
今回の目的変数は log_views_per_day です。つまり、総再生回数そのものではなく、1日あたり再生数をログ変換したものを見ています。
チャンネル別ベースラインとは、動画尺、公開後日数、夜公開、週末公開などの条件を平均的な位置にそろえたときに、そのチャンネルの動画がどれくらいの log_views_per_day になりやすいか、という値だと理解しています。
もっと雑に言えば、次のようなものです。
同じくらいの動画尺で、
同じくらいの日数が経っていて、
同じような公開タイミングだったとして、
そのチャンネルの動画は、平均より再生されやすいのか
なので、これは登録者数そのものでも、総再生回数そのものでもありません。
「チャンネルの強さ」と言いたくなりますが、そこまで言い切ると少し強すぎそうです。ここで見ているのは、あくまで今回のデータとモデルで見た1日あたり再生数の土台です。ブランド力、固定ファンの熱量、企画力、サムネイルの強さなどが混ざった結果として見えている可能性はありますが、それらを直接分解して測っているわけではありません。
たとえば、あるチャンネルのベースラインが全体平均より高いなら、平均的な条件で比べたときに、そのチャンネルの動画は1日あたり再生数が高めに出やすい、と読むのがよさそうです。
逆に、ベースラインが全体平均より低いなら、同じ条件で比べても、1日あたり再生数が低めに出やすい、という読み方になります。
ここで自分がつまずいたのは、これは平均との差として読むものだ、という点でした。
図の横軸も、「そのチャンネルの動画がチャンネル内でどれくらい散らばるか」ではありません。ここも最初は混乱しました。そうではなく、「そのチャンネルの平均的な土台が、全体平均との差としてどこにありそうか」を見ています。
このベースラインはログ尺度なので、差は倍率として読む方が直感的です。今回のチャンネル別ベースラインのチャンネル間ばらつきは標準偏差で 1.466 でした。倍率に直すと、だいたい exp(1.466) = 4.3 倍くらいです。
ただし、これはあくまでチャンネル間のばらつきの目安です。「このチャンネルは別のチャンネルより因果的に4.3倍強い」という意味ではありません。
データ
データはこれまでと同じです。取得方法や前処理の詳しい説明は、第1回のYouTube動画はどんな要素が再生パフォーマンスに関連しているのか?に書いています。
| 項目 | 内容 |
|---|---|
| 動画数 | 1,204本 |
| チャンネル数 | 58チャンネル |
| チャンネルあたり動画数の中央値 | 24本 |
| チャンネルあたり動画数の最小値 | 2本 |
| チャンネルあたり動画数の最大値 | 30本 |
最小が2本というのは、やはり気になります。
固定効果でチャンネル別ベースラインをそのまま持つと、2本しかないチャンネルにも専用の推定値がつきます。階層モデルでは、こうしたデータが少ないチャンネルほど全体平均に寄りやすくなります。
なので今回の階層ベイズは、「チャンネルごとの差を見たいけど、チャンネルごとに完全にバラバラに見るのは不安」という状況に合っていそうです。
分析に用いた技術スタック
今回の分析では、主に以下を使っています。
- Python
- pandas
- NumPy
- SciPy
- Matplotlib
- 自前のGibbsサンプラー
重回帰分析の回では statsmodels を使っていましたが、今回はチャンネルごとの階層構造を少し追ってみたかったので、正規階層モデル用のGibbsサンプラーをPythonで書いています。
ただし、これは「この実装が実務的に一番よい」という意味ではありません。今回は、モデルの中で何が更新されているのかを見たい、という学習目的でこうしています。
結果
主要な結果は次の通りです。ここから先は、出力された数値を見ながら、自分なりに読んでいきます。
| parameter | posterior mean [95% credible interval] |
|---|---|
| Bayesian R2 | 0.804 [0.786, 0.819] |
| チャンネル別ベースラインのチャンネル間ばらつき | 1.466 [1.218, 1.763] |
| 動画尺係数のチャンネル差 | 0.592 [0.437, 0.782] |
| 残差のばらつき | 0.759 [0.728, 0.792] |
| 動画尺係数の全体平均 | -0.062 [-0.262, 0.132] |
Bayesian R2 は 0.804 でした。
前回の固定効果モデル A4 の R² は 0.805 だったので、かなり近い値です。
もちろん、OLSのR²とBayesian R2は完全に同じ指標ではありません。ただ、今回の階層モデルでも、チャンネル差が大きな情報を持っていそうだ、くらいには読んでよさそうです。
チャンネル別ベースラインの差
まず、チャンネル別ベースラインの差です。
横軸は、全体平均との差です。
0より右にあるチャンネルは、平均的な条件で比べたときに、1日あたり再生数が全体平均より高めに出やすいチャンネル、と読めそうです。
0より左にあるチャンネルは、平均的な条件で比べたときに、1日あたり再生数が全体平均より低めに出やすいチャンネル、という読み方です。
チャンネル名は出していません。ここでやりたいのは、どのチャンネルが強いかランキングを作ることではなく、チャンネル別ベースラインがどれくらい違いそうかを見ることだからです。
この図で、点は各チャンネルのベースライン差の推定値です。
横線は、その推定値の95%信用区間です。
普通の回帰分析では信頼区間という言い方をよくしますが、今回はベイズ推定なので、ここでは信用区間と呼ぶそうです。直感的には「このチャンネルのベースライン差は、このあたりにありそうだとモデルが見ている範囲」と考えると、自分には少し分かりやすくなりました。
ここは少し注意が必要です。
この横線は、「そのチャンネル内の動画がこの範囲にばらつく」という意味ではありません。
そうではなく、「そのチャンネルのベースライン差は、このあたりにありそうだ」という推定の不確実性を表している、と理解しています。
たとえば、横線が短いチャンネルは、そのチャンネルのベースライン差を比較的狭い範囲で推定できている。横線が長いチャンネルは、データだけではベースライン差をまだ広めにしか言えない。そういう読み方だと教えてもらいました。
見ると、点自体はかなり散っています。
チャンネル別ベースラインのチャンネル間ばらつきは、標準偏差で 1.466 でした。目的変数がログなので、これはかなり大きい差に見えます。
ここを見ると、やはり「動画単体の特徴だけで再生パフォーマンスを説明する」のは無理がありそうです。どのチャンネルの動画なのか、という情報が相当大きそうです。
これは前回と同じ方向の結果です。
動画尺の係数はどうか
次に、動画尺の係数です。
動画尺については、前回までの分析でもすでに見てきました。動画尺と再生パフォーマンスの関係は、最初の重回帰分析でも扱っています。
今回はその続きとして、動画尺の効き方をチャンネルごとに少し変えるとどう見えるのかを見ています。
図を見ると、チャンネルごとの推定値は散っています。
ただし、区間も広いです。
なので、ここでは「動画尺の効き方をチャンネル別に分けて読むには、まだ不確実性が大きい」と受け取る方がよさそうです。
動画尺係数の全体平均は -0.062 で、95%信用区間は -0.262 から 0.132 でした。
一方で、動画尺係数のチャンネル差の標準偏差は 0.592 でした。
ここは少し難しいです。動画尺の話自体は、前回までの流れで見る意味がありました。ただ、今回の主役は動画尺そのものではなく、チャンネル別ベースラインの差です。
なので、この図は前回までの動画尺の話を置き換えるものではなく、「係数までチャンネルごとに変えると、こういう見方もできる」という補助的な結果として見ています。
投稿時間などの係数はどうか
今回のモデルでは、動画尺以外にも、いくつかの係数を見ています。
ただし、これらはチャンネルごとに変えていません。全チャンネル共通の係数として入れています。
見ているのは、動画尺の二乗、公開後日数、夜公開、週末公開です。
この中で一番はっきりして見えるのは、公開後日数です。係数は -0.413 で、95%信用区間は -0.477 から -0.352 でした。
これは、公開から日数が経つほど、1日あたり再生数が低くなりやすい、という結果に見えます。ここはかなり自然な結果だと思いました。
一方で、夜公開と週末公開は、信用区間が0をまたいでいます。
| coefficient | posterior mean [95% credible interval] |
|---|---|
| 公開後日数 | -0.413 [-0.477, -0.352] |
| 夜公開 | -0.013 [-0.077, 0.052] |
| 週末公開 | -0.031 [-0.080, 0.017] |
| 動画尺の二乗 | 0.029 [-0.081, 0.142] |
なので、今回のモデルだけを見る限り、「夜に公開すると伸びる」「週末に公開すると伸びる」とは言いにくいです。
もちろん、投稿時間は本当はジャンルやチャンネルごとに効き方が違うかもしれません。
ただ、それをやるには、夜公開の係数や週末公開の係数もチャンネルごとに変えるモデルにする必要があります。今回はそこまではやっていません。
ばらつきの大きさを並べる
最後に、ばらつきの大きさを並べます。
こうして見ると、チャンネル別ベースラインのチャンネル間ばらつきが一番大きく見えます。
残差もまだあります。つまり、チャンネル差を入れても、動画ごとの違いを全部説明できるわけではなさそうです。
ここでいう残差は、同じチャンネルの中でも、動画ごとにまだ説明しきれない違いが残っている、という意味だと理解しています。
動画尺係数のチャンネル差もありますが、チャンネル別ベースラインの差と比べると小さいです。
今回の結果をかなり雑に言うなら、
平均条件で見たチャンネル別ベースラインの差はかなり大きい。
動画尺そのものは前回までと同じく見る意味がある。
ただ、今回の主役はチャンネル別ベースラインの差だった。
という感じです。
固定効果との違いをどう受け止めるか
固定効果は、チャンネルごとの差を吸収するには分かりやすい方法でした。C(channel_id) と書けば、チャンネル別ベースラインをモデルに入れられます。
ただ、固定効果では、その差を「どれくらいのばらつきを持つ分布なのか」として見る感じにはなりません。
階層ベイズでは、チャンネル差を完全にバラバラなものではなく、全体のばらつきから生まれたものとして扱う。この違いが、今回いちばん納得したところです。
今回わかったこと
前回の固定効果モデルでは、チャンネル別ベースラインを入れると、説明力が大きく上がりました。
今回は、そのチャンネル差を、階層ベイズで「全体の分布から生まれたズレ」として扱う方法を試してみました。
結果として、チャンネル別ベースラインのチャンネル間ばらつきはかなり大きそうで、Bayesian R2 も前回の固定効果モデルに近い値になりました。
ただし、ここで新しく分からないものも残りました。
チャンネル別ベースラインの差は大きそうです。でも、それが何によって生まれているのかまでは、今回のモデルだけでは分かりません。
今回見えたチャンネル別ベースラインの差は、動画尺だけで説明するものではなく、もっとチャンネル側の文脈を含んでいそうです。固定ファンの強さなのか、企画の型なのか、サムネイルやタイトルなのか、ジャンルの中のさらに細かい違いなのか。そこはまだ見えていません。
なので、今回の分析で答えが出たというより、「分からないものがどこに残っているか」が少し見えた、という感じです。
ここまでやってみて思うのは、動画単体だけを切り出して「何が伸びる要因か」を読むのは危うそうだ、ということです。動画はチャンネルの文脈の中にあります。
次に見るなら、このチャンネル別ベースラインの差を、チャンネル単位の変数でどこまで説明できるかだと思います。登録者数、投稿頻度、過去動画の中央値、タイトル傾向、ジャンルの中のさらに細かい違いなどを入れると、この「分からない差」が少し分解できるのかもしれません。
まだ扱いきれている感じはしません。ただ、少なくとも「チャンネル差をどう扱うか」を曖昧にしたまま、動画特徴の効果だけを読むのは危ない、という感覚はかなり強くなりました。




