公開日: 2024/03/27
最終更新: 2024/04/01
参考資料
- An Introduction to Data Densification
- Creating a Date Scaffold in Tableau
- Zen Master: You Did What to Your Data? A Deep Dive into Imputing and Densifying Data
- Katie Kilroy - What is Data Scaffolding Some Practical Examples - TFF2020
自分のブログ記事でも出てきますが、Data Densification(あえて日本語にすればデータ高密度化)というデータ件数またはマーク数を増加させる手法があります。 この手法について書かれている日本語資料が多くないため、この記事にまとめてみます。
(英語での記事や動画は本当に多いのですが...)
Data Densificationを知ることで、作成できる可視化表現や分析の幅が広がります。また作成したい可視化に必要なデータ形式についての理解が深まります。
具体例と共に、その恩恵や実装方法、制約や考慮事項を見ていきましょう。 本記事で使用したWorkbookはこちらからダウンロードできます。
また使用したサンプルデータはこちらからダウンロードできます。
注意事項
データ件数またはマーク数を元データを超えて増加させることの類義語に、Data ScaffoldingやData Paddingのような言葉があります。 Scaffoldは前処理の文脈(Tableau PrepやETLなど)、Data PaddingはBinを使った欠損値表示と表計算の文脈で使用されることが多い印象ですが、結局はデータ件数を増やすなどの高密度化処理なので、この記事では簡単のためData Densificationに言葉を統一します。
この記事では欠損値処理についての内容をData Densificationとして取り上げません。可視化の作成や分析に焦点を当てて解説します。
この記事ではRadial ChartなどData Densificationを使用した例を挙げますが、各チャートの作り方については言及しません。作成したい方はお調べください(自分もいくつか記事を書いています)。
「マーク」については以下を参考として記載しますが、Data Densificationの文脈では分かりにくいかもしれません。 ここではTableauのビュー上で選択できるデータ点、程度にご理解ください。 ビューの各部分 - マーク
2024/4/1 追記
Data Densificationについて言及されているTableauヘルプページを発見しました。 生成されたマークを使用した予測モデリング Tableau公式としてのData Densificationの定義は、欠損値表示やBin機能などによる「参照元データ ソースのレコードでサポートされていないマークであっても、Tableau によってマークが生成され、ビューに追加されるプロセス」のようです。 ただしこの記事では上記の注意事項にあるように、もう少し広い対象を指してData Densificationと呼称します。ご了承ください。
Data Densificationの概要と具体例
Data Densificationは様々な用途に使用されますが、例えば曲線やポリゴンを描画する、Waffle Chartなど数字を単位に区切る可視化を作る、開始点と終了点の間を補完するなどを行う際に使用されます。
その全てに共通していることが、最終的にはマーク数を増やすことです。
曲線やポリゴンを描画する場合は、元々は始点と終点の2点しかないためマーク数が2つのもの、または1つの集計値のためマーク数が1つしかないものについて、描画のために必要なマーク数をData Densificationにより作成します。
以下のBump Chartでは、サブカテゴリごとの2023年の売上ランクと2024年の売上ランクの変化を可視化しています。 左は直線で描いた場合、右はData Densificationにより曲線で描いています。 曲線を描画するために、2点間のマーク数が増加していることが分かります。
以下のBar ChartとRadial Chartでは、サブカテゴリごとの2024年の売上を可視化しています。
左のBar Chartでは各サブカテゴリに1マークしかありませんが、右のRadial ChartではData Densificationによりマーク数を増加させ曲線を描いています。
以下のBar ChartとWaffle Chartはサブカテゴリごとの平均割引率を可視化しています。
Waffle Chartは1つの集計値を単位に区切ります。したがって左のBar Chartのように、本来は各サブカテゴリごとに1つのマークで表されていた集計値を、必要な単位分だけ分割します。以下の例では百分率を使用しているため、100マークに分割します。
以下の例では明示的に見えにくいのですが、ホテルの宿泊履歴について、宿泊日数分だけデータ件数を増やしています。
このデータは、元々は1行につきチェックイン日、チェックアウト日、宿泊日数、人数のデータのみ持っています。 日次の総宿泊者数を可視化するため、Data Densificationにより各データ行を宿泊日数分だけ増加させています。
このようにData Densificationを使用すると、可視化表現や分析の幅を広げることが出来ます。
上記は一部の使用例です。Tableau PublicにはData Densificationを使った素晴らしい可視化が多くありますので、ぜひ色々な作品に触れてみて下さい。
Data Densificationの実装方法
大きく分けて3種類の実装方法があります。
(物理層または論理層で)データ件数をn倍に増やす
(物理層または論理層で)データ件数を2倍に増やし、その後Binを使用してマーク数をn倍に増やす
Binだけを使用してマーク数をn倍に増やす
それぞれの方法について順に見た後に、総評で各方法のPros/Consを見ていきましょう。
注:物理層と論理層について
1と2はデータソース内で、3はビュー上で実施するため、上記で括弧書きで物理層と論理層について言及しました。
ただしこの記事ではこの点について深くは触れないため、以降は物理層はJOINまたはUNION、論理層はRelationでデータ結合をしているとご理解ください。 ちなみに、基本的にはRelationを使えば良いと思います。
データ件数をn倍に増やす方法
まずは曲線を描く場合で例示します。
Radial Chartを例に、1つのマークを半円の弧にしてみましょう。
以下はSUM([Sales])を棒グラフで描画したものです。
この棒グラフを半円にするために、まずは181等分します(0度~180度までのマーク数を作るため、0度の分を含めて181等分になります)。
181等分するために、0~180までの値を持つ181行のダミーデータを結合します。
以下が181行のダミーデータを使用して181分割したSUM([Sales])です。
ここまでの流れを簡単な図にしました。 データを181倍にして読み込んだ、というだけです。
これを半円上に配置したいので、以下の計算式で縦軸と横軸を作成します。
ここで[T]には0~180の値が入ります。
X Radial Basic
COS([T]*PI()/180)
Y Radial Basic
SIN([T]*PI()/180)
ここでは半円、つまり0度~180度の間を埋めるようにマークを作成するために、0度~180度までのマークを作成するための、181行のダミーデータを使用しました。
この181個のマークを線でつなげば、典型的なRadial Chartが作成できます。
もし半円の代わりに全円なら361行、3/4円なら271行のダミーデータを使用してData Densificationを行えば良いことになります。
もう一つの例として、ホテルの宿泊者数の推移を見てみましょう。
ここではIDが0~20までの21行のダミーデータを用意し、宿泊日数がIDよりも大きいことを結合条件としてデータ結合しています。
(データ中のStay Durationの最大値が14なので、適当に21行を用意しました)
結合の結果、各データは宿泊日数分のデータが重複して作成されます。
この重複データを使用して、以下の計算式を作成します。
Date Densified
[Check In Date] + [ID]
例えばチェックイン日が5月5日、宿泊日数が3日の場合、Data Densifiedは5/5, 5/6, 5/7の3日分を返します。
いずれの場合にも、目的の可視化や分析をするために、複数行を持つダミーデータを用いたData Densificationを実施しています。
この方法はJOINまたはRelationにより実装されます。
データ件数を2倍に増やし、その後Binを使用してマーク数をn倍に増やす方法
曲線やポリゴンの描画を目的にData Densificationを行う場合、実際には2倍に増やせば十分なことが多いです。
この方法ではBin機能を活用します。
先ほどのRadial Chartを例にします。
以下のように、2行しかないダミーデータを結合します。IDの値が1と2しかありません。
この2行しかないIDから、181個のマークを作成します。 まず、以下の計算フィールドを作成します。
PATH
IIF([ID] = 1, 0, 180)
この計算フィールドからBin Sizeが1のBinを作成します。
作成したPATH (Bin)をビューに置き、欠損値を表示するオプションをオンにすると、以下のように0~180のBinが表示されます。
このBin機能と欠損値を表示する機能が重要で、データソース側では元々2倍だったデータ件数を、これら機能の組み合わせで疑似的に181倍にしています。
ただしこの方法で増やしているのはマーク数であり、データ件数ではないことに留意ください。
言い換えれば、データソース内のデータ件数は2倍である一方、その先のTableau側の処理で最終的にマーク数を181倍にしています。
また、Bin自体は計算フィールドに使用できないので、Binの値を反映する以下の計算フィールドを作成します。
INDEX
INDEX() - 1
Binと欠損値の表示の組み合わせにより、本来は0と180しか値を持たないPATHから181個のマークを作成することができました。
この181個のマークを使用するINDEXを使用して、Radial ChartのX軸とY軸を、歳ほどのTをINDEXに置き換えて修正します。
なお、INDEXの表計算はPATH(bin)に沿って計算させます。
X Radial Basic
COS([INDEX]*PI()/180)
Y Radial Basic
SIN([INDEX]*PI()/180)
マークをn分割し曲線やポリゴンをすることは、たった2行のダミーデータを使用しデータ件数を2倍にすれば実現できることが分かりました。
上記の例ではRelationを使用し、ダミーデータのフィールド(上記例の場合はID)が使用される場合においてはデータ件数が2倍になります。
ただし同様のことはJOINでもSelf-UNION(要は同じデータでUNIONし、自動生成されるTable Names列の値だけ異なるようにする)でも可能です。
ただし、この方法は主にはBinを使用したData Densificationであり、Binは計算フィールドに直接使用できない制約を意識する必要があります。
以下、ホテルの宿泊データで見てみましょう。
同様に2行しかないダミーデータを結合します。
以下の計算フィールドを作成し、Bin Sizeが1のBinも作成します。
PATH
IIF([ID] = 1, 0, [Stay Duration]-1)
Date Densified
WINDOW_MIN(MIN([Check In Date])) + INDEX() - 1
作成した計算フィールドなどを以下のように配置すると、データ件数をn倍に増やす方法と同様の結果が得られているように見えます。
ただし、ここでのData Densifiedは表計算であることに注意が必要です。
このData Densifiedは、各Reservation IDごとのCheck In Dateを取得し、それにBinの値に対応するINDEX()-1を足しています。 つまり、各Reservation IDについて目的のData Densificationを行うためには、シート上に常にReservation IDがディメンションとして使用されている必要があります。
逆に、Data Densifiedは表計算のためディメンションとして使用できません。
上記について、日次の総宿泊者数のグラフから見てみましょう。
以下のグラフはデータ件数をn倍に増やす方法を用いて、以下のように作成しています。
ここではData Densifiedはディメンションであり、またビュー中のディメンションはData Densifiedのみです。
このグラフをデータ件数を2倍に増やす方法で再現しようとした場合、以下のような積み上げ棒グラフを作成する必要があります。
n倍に増やす方法では、Data Densifiedがディメンションとして使用できたので上記例ではマーク数が91でした。
一方、2倍に増やす方法ではReservation IDとPATH(bin)の分だけ粒度が増加し、マーク数が222,104となっています。
マーク数の増加は描画パフォーマンスの低下、ビューの複雑性増加、ラベル表示など視覚的要素を追加する際の困難を招くので、一般的には好ましくありません。
また積み上げ以外で総数を表示する必要がないので、線グラフなど可視化上妥当な視覚表現を使用することが難しくなる可能性もあります。
表計算に慣れた方向けの補足
Data Densifiedごとに総数を表示するならWINDOW_SUMなどで可能では?と思われると思いますが、Data Densifiedがディメンションとしてデータを区切っていないことから、不可だと思います。
逆に可能な方法を見つけた方はぜひ教えてください。
上記のように、分析のためのData Densificationに使用する場合には、データ件数を2倍に増やす方法が妥当でない場合があります。
目的が曲線やポリゴンの描画など、可視化表現自体にあるのであれば、データ件数を2倍に増やす方法で十分なはずです。
Binだけを使用してマーク数をn倍に増やす方法
この方法はTableau Cloud/Serverにあるパブリッシュされたデータソースなど、Relation/JOIN/UNIONのいずれも使えないデータについて使用します。
実装については、データ件数を2倍に増やす方法と殆ど同じことをしますが、以下の点が異なります。
ダミーデータを必要としない
Data Densificationを行う粒度のためのLOD計算が必要 (そのため柔軟性が低下)
Sample Superstoreを使用したRadial Chartを例にしてみましょう、 ここではSub-CategoryごとにRadial Chartを作成します。
まず以下の計算フィールドを作成し、同様にPATHのBinを作成します。
Dimension
[Sub-Category]
PATH
IIF([Row ID] = {FIXED [Dimension]: MIN([Row ID])}, 0, 180)
指定したDimensionに対するLOD計算をPATHの計算フィールドの中で使用していることに注目ください。
上記の例では、データ1行ずつRow IDがそのSub-Categoryにおける最小値かどうかの判定をし、その結果をもとに0または180の値を、各Sub-Categoryに含まれるデータに対して返しています。
データ件数を2倍に増やす方法において、ダミーデータで明示的に2値を用意できるようにした(IDの2つの値を用いた)ことに対し、この方法では単一のデータソースから2値を作成します。
ここではRow IDを使用しましたが、本質的には「指定したDimensionにおいて、少なくとも異なる2値を持つことが想定される列」を使用すれば良いです。
したがってSample Superstoreで言えば、例えばSalesやProfitなどでも良いです。
(詳細と理由は後述します)
ほぼ同じ図となりますが、Data Densificationが同様にできていることを確かめておきましょう。
ちなみに上記では各Sub-CategoryごとにPATHが0と180の両方の値を担保するため、PATHの中でFIXED計算を使用しました。
要はData Densifiation前のマークにおいてPATHの値が0と180の両方を持てばいいので、Sub-Categoryがビュー内で使われない場合でも、以下のようにSub-Categoryが内包される場合は、PATHの計算フィールドの中身やDimension計算フィールドで使用される列を変更する必要はありません。
逆に、Data Densification前のマークにおいて、PATHが0と180の両方の値を持たない場合、この方法は使用できません。
例えば以下の場合です。
Dimensionで使用した列とビューのマーク粒度が一致しない
Dimensionで使用した列とビューのマーク粒度は一致するが、元々のマークに1行しかない
Dimensionで使用した列とビューのマーク粒度は一致し、元々のマークに2行以上あるが、PATHの判定に使用した列が、マークに含まれるすべての行で同一の値
1の場合、例えば以下のように、ビューの粒度にSegmentが追加されている一方、DimensionはSub-Categoryのみ使用していた場合です。
下図のように、各粒度でPATHが2値を持っていないため、正しくData Densificationができていません。
このような場合、以下のようにDimensionが2つの列の組み合わせで表現されるようにします。 もしくは、PATHの中のFIXEDに使用されるディメンションを修正します。
Dimension
[Sub-Category] + '-' + [Segment]
2の場合について、ひとつの計算フィールドで1行から2値を作成することはできません。
例えば2021年1月には、Sub-Category = Tableのデータは1行しかありませんでした。したがってこの方法ではData Densificationが出来ません。
3の場合について、条件判定でPATHが2値を持つようにしているため、2行以上あるときには2値を返せるような列を条件判定に使用しましょう。
ここまでの議論から、この方法は複雑かつ制約が多そうだと思われたかもしれません。
実際に複雑かつ制約が多いと思いますし、個人的にはデータ結合が使えないときの最終手段かなと思っています。この辺りは以下の総評で議論しましょう。
備考
PATHの計算式について、ディメンションを指定したLOD計算でなくてもData Densificationを複数マークに対して実装できる場合があります。
例:How to build a Sankey diagram in Tableau without any data prep beforehand
ディメンション指定したLOD計算を使用し、明示的に各マークにBinの最大値/最小値が現れる実装の方が直感的に理解できると思い、本記事ではそちらの方法を紹介しました。
3つの実装方法についての総評
3つの実装方法について順に見ていきました。
各方法のPros/Consをまとめましょう。
1. データ件数をn倍に増やす方法
Pros
データ件数を増やすことでData Densificationを行うので、データ構造や必要なロジックが分かりやすい
Data Densificationno結果をディメンションとして使用する必要がある場合に有効である
Cons
用途に合わせたダミーデータを用意する必要がある
データ件数が比較的大きくなるため、パフォーマンスへの影響があるかも?
2. データ件数を2倍に増やし、その後Binを使用してマーク数をn倍に増やす方法
Pros
ダミーデータが2行あれば良いので、用途ごとにダミーデータを作成する必要がない
データ件数の増加は2倍でおさまるので、相対的にパフォーマンス影響が少ないかも?
ただBinと欠損値表示でマーク数は結局増える。元データの大きさと必要なマーク数のバランスで評価する?
Cons
Bin機能と欠損値表示を使用した結果をもってData Densificationを行うので、データ構造やロジックが分かりにくくなる懸念がある
Bin機能を使用するため、Data Densificationの結果をディメンションとして使用できない
曲線やポリゴンの描画など、描画目的以外には使いにくい
3. データ件数をn倍に増やす方法
Pros
パブリッシュされたデータソースなど、リレーション等のデータ結合に制約がある場合に有効である
Data Densification用のダミーデータが不要である
Cons
Bin機能と欠損値表示を使用した結果をもってData Densificationを行うので、データ構造やロジックが分かりにくくなる懸念がある
Bin機能を使用するため、Data Densificationの結果をディメンションとして使用できない
曲線やポリゴンの描画など、描画目的以外には使いにくい
元々のマークについて、PATHが異なる2値を持つようにする必要がある。そのために...
マーク粒度に合わせたFIXED計算が必要になる場合がある
元々の各マークが2行以上を持つ必要がある
PATHの計算に使用する列を慎重に選ぶ必要がある
上記を踏まえて、以下の方針になると思います。
パブリッシュされたデータソースなど、データ結合に制約がある前提でData Densificationが必要ならば、3の方法を検討する。
もしくはパブリッシュされたデータソースの改修を検討する。
運用性などの観点から実装の分かりやすさを重視するなら、1の方法を検討する。
宿泊者分析の例など、描画ではなく分析のためのデータ加工が主目的であれば、1の方法を検討する。
描画目的である場合は、ダミーデータが簡単なので2の方法を検討する。
一つのデータソースから複数の曲線やポリゴンを描画する場合は、一つのダミーデータで複数の用途に使いまわせるので、2の方法を検討する。
余談:Dashboard Extensionsを使う手もある
ところで曲線やポリゴンを使った可視化のためにData Densificationが必要かというと、Tableau Exchangeで公開されているDashboard Extensionsで代替することも可能です。
例えば ShowMeMoreはSankey DigramをData Densificationを必要とせず作成できます。
Tableau Public連携もしているので、ご興味あればぜひお手元で試してみて下さい。
ただし分析のためのData DensificationはExchangeではなく手元で行う必要が残ること、Extensions側に作成したい可視化が用意されていない場合があること、また組織の方針によりExtensionsが使用できない場合もあるかと思いますので、Data Densificationについて知っておいた方が良いのかなとは思います。
最後に
自分の理解の整理も兼ねて、Data Densificationについてまとめてみました。
実施したいことは単純で、必要な分だけ行やマークを増やそう、というだけです。
ここまで書いて思うことは、今回の記事では簡単のためにData Densification/Padding/Data ScaffoldingをまとめてData Densificationと呼称し、Tableauの機能の中で実装する方法を紹介しましたが、本質的には以下が重要だと思いました。
異なる文脈があることを意識する
描画のためか、分析のための前処理のためか
(その意味で、PaddingやDensificationは描画の文脈寄り、Scaffoldingは前処理の文脈寄りで使われることが多いのかなと)
Tableauの中で実施した方が良いのか、Tableauの外に出した方が良いのか意識する
前処理的なことをTableauの機能でした方が良いのか、ETLやSQLの方でした方が良いのか
(描画のためのData DensificationはさすがにTableau内に留めて良いと思いますけど)
いずれにしても、目的の可視化を作成するための手法として、Tableauユーザーの方は知っておいて良いのかなと思いました。
繰り返しになりますが、ぜひTableau Publicなどで作品に触れてみて下さい。
質問などありましたら、XかLinkedinまでお願いします。