可視化で rollup 関数とカーディナリティを理解する
概要
データ分析の可視化では、時間の経過に沿ったデータを要約するために集計関数を使うことがよくあります。ところが、rollup 関数と distinct/unique のカーディナリティ指標が組み合わさると、グラフが想定と合わないなど、意外な見え方になることがあります。
rollup の結果が持つ性質に合わせて期待値をそろえ、クエリを明確に設計すれば、データからより確かな洞察を得られます。本ドキュメントでは、特にカーディナリティとの関係に焦点を当てて rollup 関数の動作を解説し、可視化結果を正しく読み解くためのベスト プラクティスを紹介します。
時系列におけるカーディナリティを理解する
Web サイトの訪問ユーザーを追跡しているケースを考えます。7 日間、毎日 100 人のユーザーを観測すると、合計で 700 人だと捉えがちです。しかし、1 週間を通した ユニーク ユーザー数は 400 人程度にとどまることもあります。複数日にわたって同じユーザーが繰り返し訪問するためです。このズレは、各タイム フレーム (例: 1 日) ごとに「ユニーク」を独立に数えることで起きます。短い区切りのユニーク数を単純に足し上げると、より長い rollup 区間で 1 回だけ数える場合と比べて、合計が膨らんで見えてしまいます。
この直感に反する挙動の背景にあるのがカーディナリティです。カーディナリティとは、データセット内のユニークな要素をどう数えるか、という考え方です。時間バケットごとのカーディナリティは思った以上に複雑になり得ます。例えばユーザー分析では、「今週、各日にサイトを訪れた ユニーク ユーザーは何人か?」という問いになります。同じユーザーが 2 日にわたって訪れたなら、そのユーザーは各日でそれぞれユニークとしてカウントされます。
rollup が平均に与える影響
Rollup 関数 は、平均値の算出やグラフの見え方にも大きく影響します。
平滑化 (smoothing) 効果:
- 短い期間 (5 分ロールアップ) では、スパイクや細かな変動がはっきり見えます。
- 長い期間 (30 分ロールアップ) では、グラフがなだらかになり、全体傾向が読み取りやすくなります。
平均値の算出:
- 短い期間では、Datadog がその瞬間に観測できたユーザーに偏りやすく、平均が低めに出ることがあります。
- 長い期間では、同一ユーザーの複数回の出現 (例: 別デバイスからのアクセス) も拾いやすく、平均が高めに見えることがあります。
例: rollup がユニークなユーザー数に与える影響
可視化は区間ごとの値を合計して表示することが多いため、時間スケールを変えて合計値を比較すると混乱が起きがちです。例えば、同じメトリクスでも 5 分間隔と 30 分間隔で見たときに、グラフ上の合計が違って見える場合があります。短い窓では同じユーザーが複数回カウントされ得る一方、長い窓では 1 回にまとまるためです。
このセクションでは、rollup 関数とカーディナリティが実際にどう絡むのかを具体例で見ていきます。モバイルとデスクトップのユーザー セッションを計測している Web サイトを想定します。
モバイル上のセッション割合を平均で取り、30 分ごとにロールアップすると、グラフは滑らかになります。これは rollup 関数による自然な平滑化で、長期的な傾向を読むにはむしろ解釈しやすくなります。
ところが、users で group by すると 2 つのグラフは重なりません。30 分のグラフが 5 分のグラフより明らかに高くなります。一見すると不具合のように見えますが、これは期間の切り方によってユーザーの利用のされ方がどう見えるかを反映しているだけです。
次のグラフでは、モバイルの distinct ユーザー数と全体の distinct ユーザー数について、5 分ロールアップと 30 分ロールアップを比較しています。30 分ロールアップは 5 分ロールアップより自然に大きくなるため、このグラフでは 30 分ロールアップを 0.75 倍にスケール ダウンして表示しています。全体の distinct ユーザー数では 5 分と 30 分が概ねそろいますが、モバイルの distinct ユーザー数では 30 分ロールアップが 5 分ロールアップより大幅に高くなります。なぜでしょうか?
これは、rollup のウィンドウ内で同じユーザーが複数回現れた場合、分母では 1 回だけ数えられる一方で、分子では複数回カウントされ得るためです。
$$\text"cardinality:@usr.name[@type:session @device.type:Mobile]" / \text"cardinality:@usr.name[@type:session]" * 100$$
別の捉え方をすると、あるユーザーが同じウィンドウ内で複数回現れるたびに、その都度「分子に入るチャンス」が生まれる、ということです。時間枠が長くなるほど、1 人のユーザーが登場する回数も増え、結果として (この例では) モバイルでページを閲覧する機会も増えます。
これをより具体的にするため、日中は PC でサイトを確認し、朝夕の通勤中だけモバイルで確認するユーザー像を想像してみてください。朝の通勤で確認する人が半分、夕方の通勤で確認する人が半分、そして朝夕の両方で確認する人が半分いるとします (結果として、モバイルでまったく確認しない人が 4 分の 1 残る想定です)。
同様に、1 時間 rollup だと通勤時間帯は 10% 〜 20% 程度、非通勤時間帯は <1% 未満に見えるかもしれません。大きい時間枠より数値は小さく見えますが、それでも解釈としては正しい結果です。
参考資料