TVチューナの視聴時間帯と連続視聴時間調査

TVチューナの視聴開始時間帯と連続視聴時間調査

概要

  1. 弊社のTVチューナの利用履歴を用いて視聴開始時間帯と連続視聴時間を調査しました
  2. モバイルとPCで利用状況が異なるのではないかという推測からその違いを確認してみました

方法

  1. TVチューナの操作履歴から視聴開始数を抽出
  2. 視聴開始する時間帯と連続視聴時間を可視化

制限事項

  1. 1分未満の視聴時間の操作に関してはザッピングと判断して除外しています
  2. モバイルの利用履歴の方がPCよりも10倍近く多いです
  3. 祝日は考慮していません

モジュール読み込み

In [1]:
import pandas as pd
from IPython import display
from matplotlib import pyplot as plt
%matplotlib inline

plt.rcParams['font.family'] = 'IPAPGothic'

pandasのデータフレームに読み込み

  • 利用履歴のデータベースから必要なデータを抽出して使用します(csvデータは非公開です)
  • play_count_time.csv : [曜日、時間帯(00-23時)、モバイルかどうか、視聴カウント]のデータ
  • play_count_duration.csv : [連続視聴時間(min)、モバイルかどうか、視聴カウント]のデータ
In [2]:
play_tm_df = pd.read_csv('play_count_time.csv', encoding='shift-jis')
play_dr_df = pd.read_csv('play_count_duration.csv', encoding='shift-jis')

共通のグラフ表示関数

In [3]:
def set_one_graph(x, y, x_ax_label, y_ax_label, title):
    if isinstance(x, pd.core.indexes.multi.MultiIndex): 
        x_vals = [val[0] for val in x]
        x_labels = [val[1] for val in x]
        plt.bar(x_vals, y)
        plt.xticks(x_vals, x_labels)
    else:
        plt.bar(x, y)    
    
    if x_ax_label is not None:
        plt.xlabel(x_ax_label)
    if y_ax_label is not None:
        plt.ylabel(y_ax_label)
    if title is not None:
        plt.title(title)

def compare_mobile_vs_pc(x_mb, y_mb, x_pc, y_pc, x_ax_label, y_ax_label):
    plt.figure(figsize=(14, 5))

    plt.subplot(1, 2, 1)
    set_one_graph(x_mb, y_mb, x_ax_label, y_ax_label, 'mobile')

    plt.subplot(1, 2, 2)
    set_one_graph(x_pc, y_pc, x_ax_label, y_ax_label, 'pc')

    plt.show()

時間帯別の視聴開始数

  • 単純に合計数で割ったものをグラフ化
  • モバイル、PC共通で19-21の時間が最大で、3時が最小となる
  • モバイルの特徴としては6,7,8,12時の視聴開始が多く、23-4時の視聴が少ない
In [4]:
mb_tm_df = play_tm_df.loc[play_tm_df['is_mobile'] == 1].sort_values('period_of_time').reset_index(drop=True)
pc_tm_df = play_tm_df.loc[play_tm_df['is_mobile'] == 0].sort_values('period_of_time').reset_index(drop=True)
In [5]:
mb_count = mb_tm_df.groupby('period_of_time')['play_count'].sum()
pc_count = pc_tm_df.groupby('period_of_time')['play_count'].sum()
mb_count = mb_count.div(mb_count.sum())
pc_count = pc_count.div(pc_count.sum())
compare_mobile_vs_pc(mb_count.index, mb_count.values, pc_count.index, pc_count.values, '時間帯', '視聴開始数 / 総数')

曜日別の視聴開始数

  • モバイル、PCともに日曜日が多いがpcの方がより顕著
In [6]:
mb_count = mb_tm_df.groupby(['dw', 'day_of_week'])['play_count'].sum()
pc_count = pc_tm_df.groupby(['dw', 'day_of_week'])['play_count'].sum()
mb_count = mb_count.div(mb_count.sum())
pc_count = pc_count.div(pc_count.sum())
compare_mobile_vs_pc(mb_count.index, mb_count.values, pc_count.index, pc_count.values, '曜日', '視聴開始数 / 総数')

モバイルの各曜日の時間帯別視聴開始数

  • 6,7,8,12時の視聴開始が多いのは平日のみの傾向と考えられる
In [7]:
plt.figure(figsize=(15, 10))
for x in range(1,8):
    tmp = mb_tm_df.loc[mb_tm_df['dw'] == x].reset_index(drop=True)
    tmp_count = tmp.groupby('period_of_time')['play_count'].sum()
    tmp_count = tmp_count.div(tmp_count.sum())
    plt.subplot(3, 3, x)
    plt.bar(tmp_count.index, tmp_count.values)
    plt.title(tmp['day_of_week'][0])
plt.show()

モバイルの各曜日の時間帯別視聴開始数

  • 特に曜日による違いは見られない
In [8]:
plt.figure(figsize=(15, 10))
for x in range(1,8):
    tmp = pc_tm_df.loc[pc_tm_df['dw'] == x].reset_index(drop=True)
    tmp_count = tmp.groupby('period_of_time')['play_count'].sum()
    plt.subplot(3, 3, x)
    plt.bar(tmp_count.index, tmp_count.values)
    plt.title(tmp['day_of_week'][0])
plt.show()

連続視聴時間の分布(上限2時間)

  • 前処理で1分未満の履歴は除去しています
  • チャンネルを変えずに視聴した時間
  • 2時間未満に限定して確認
  • 1-2分が多いので長時間同じチャンネルを少るというより、少し見るという使い方が多いのかもしれない
In [9]:
mb_dr_df = play_dr_df.loc[(play_dr_df['is_mobile'] == 1) & (play_dr_df['duration_min'] < 120)].sort_values('duration_min').reset_index(drop=True)
pc_dr_df = play_dr_df.loc[(play_dr_df['is_mobile'] == 0) & (play_dr_df['duration_min'] < 120)].sort_values('duration_min').reset_index(drop=True)
In [10]:
mb_count = mb_dr_df.groupby('duration_min')['play_count'].sum()
pc_count = pc_dr_df.groupby('duration_min')['play_count'].sum()
mb_count = mb_count.div(mb_count.sum())
pc_count = pc_count.div(pc_count.sum())
compare_mobile_vs_pc(mb_count.index, mb_count.values, pc_count.index, pc_count.values, '視聴継続時間(分)', '視聴開始数 / 総数')

30分以下で表示

In [11]:
mb_count = mb_count.loc[mb_count.index <= 30]
pc_count = pc_count.loc[mb_count.index <= 30]
compare_mobile_vs_pc(mb_count.index, mb_count.values, pc_count.index, pc_count.values, '視聴継続時間(分)', '視聴開始数 / 総数')

連続視聴時間の期待値

  • 1分単位なので中央を階級値としています
  • モバイルの方が短いため視聴停止、もしくはチャンネル変更までの時間が短いと考えられます
In [12]:
mb_ex = ((mb_dr_df['duration_min'] * 60.0 + 30.0) * (mb_dr_df['play_count'] / mb_dr_df['play_count'].sum())).sum()
pc_ex = ((pc_dr_df['duration_min'] * 60.0 + 30.0) * (pc_dr_df['play_count'] / pc_dr_df['play_count'].sum())).sum()
print('連続視聴時間の期待値(秒) : %f'%(mb_ex))
print('連続視聴時間の期待値(秒) : %f'%(pc_ex))

まとめ

  • モバイル視聴の特徴として平日の12時に視聴開始数が多い傾向が見られました
  • 推測になりますが、昼休憩でモバイルのチューナを利用するシーンが多いのかもしれません
  • また、連続視聴時間もモバイルの場合は短めなので長時間というよりも短時間で利用するシーンが多いと推測しています