(2021/5/15 追記: Tableau Prepで視覚的にLOD計算を理解するための記事を書きました。こちらも併せてお読みいただくと理解が深まると思います)
前回の表計算解説記事に続き、今回はLODを体系的に解説します。
(LOD計算:Level Of Detail計算。詳細レベル計算とも日本語では呼ばれます。)
今回の記事は「LOD計算を使用したことがあるが、仕組みを体系立てて説明できない」方への説明を目的としています。
したがってLOD計算の使用上の基本および基本的な使用例は割愛します。
といいつつも、今回取り上げるのは「動作原理」に近いものですので、初学者の方も流し読み程度でぜひ。
本記事では極力SQLの言葉を使わず、SQL知識を前提としない文章としております。
そのためSQLご存じの方には冗長な文章となるかもしれません。ご了承ください。
今回使用したWorkbookは以下にあります。
以下を参考としました。
Youtube
WhitePaper
LOD計算の基本概念
まずはLOD計算の構造を見てみます。
LOD計算には3種類あり、それぞれでディメンションを指定(未指定もOK)し、使用する集計関数を指定します。
それぞれがどのように動作するかは後述するとして、次に全てのLOD計算に共通する概念、イメージを以下に述べます。
LOD計算は「Tableauが裏でLOD計算用の集計テーブルを作り、それをSheet上で結合させている」イメージで理解できます。
上記の例ではSheet上でCategory、SegmentごとのSalesの合計値を表示させています。
ここにLOD計算のひとつであるFIXEDで「CategoryごとのSalesの合計値」を表示させているのが、左側の「Sheet上で見えるもの」です。
ところでFIXEDでは「CategoryごとのSalesの合計値」を計算させますので、このときTableauは裏側で「Categoryで集計したSalesのテーブル」を裏で作成します。
これが上図右側の「LOD計算で作られるテーブル」に対応します。
そして「LOD計算で作られるテーブル」を、今回のケースでは「Category」ごとに結合します。
つまり、もしSheet上でのデータがCategory = Furnitureならば、「LOD計算で作られるテーブル」のCategory = Furnitureのデータが結合されます。
ここまでの話をまとめます。
TableauがLOD計算をSheet上に表示する際に行っていることは以下です。
LOD計算の結果を出すために、LOD計算の結果作成に使用されるディメンションによる集計テーブルを裏側で作成
LOD計算の結果作成に使用されたディメンションを用いて、Sheet上のテーブルと1の結果を結合
ここで、上記までの議論について以下の注意点を述べておきます。
「LOD計算の結果作成に使用されるディメンション」とは、基本概念中の「LOD計算に使用するディメンション」とは概念として異なります。
上記の点はINCLUDEとEXCLUDEで解説しますが、現在は「LOD計算で作る集計テーブルの、粒度としてのディメンション」としてご理解下さい。
ここまでの議論において「集計」は考慮していません。
集計はSheet上で最終的に実行されるものであり、こちらも後述します。今のところは「テーブルがくっついて数値が得られるんだな」くらいの理解でお願いします。
ちなみに、FIXEDでディメンション未指定の場合は以下のようになります。
ところで、上記の例ではSheet上でもLOD計算で作られるテーブル上でも「Category」は集計に用いられていました。
少し難しい話をします。もしSheet上でCategoryが使用されていない場合、どのように理解するべきでしょうか。
順に見てみましょう。
まず最初に、Tableauは「LOD計算で作られるテーブル」を「LOD計算で使用されているディメンション」で結合します。
またSheet上ではCategoryは見えていませんが、データとして各Segmentには各Categoryが含まれています。
したがって、Tableau上では裏側で以下のステップを踏みます。
さて、各Segmentに含まれる { FIXED [Category]]: SUM([Sales]])} の値が分かりました。
それでは、これら値は最終的にSheet上でどのように表示されるべきでしょうか?
ここで考えるべきが「集計」です。
上図のように「Sheet上で見えるもの」に使われるテーブルでは、各Segmentに対して3行もっています。
この3行を「集計」して、各Segmentに対するLOD計算の結果の集計値を表示させます。
上図では、それぞれSUM、AVG、MAX、MINの集計値を出しています。
前述のように「Sheet上で見えるもの」の粒度(いわゆるViz-LOD)の中に、裏側で作成されるテーブルの複数行が入ってくる場合には、特に集計を意識する必要があります。
逆に最初の例のように、Sheet上のディメンションが、裏側テーブルのディメンションと対応しているのであれば、裏側の集計テーブルからSheetへ送られるレコードは1つのため、どの集計をしても結果は同一のはずです。
(とはいえSheet上で何の集計をするべきかは常に意識するに越したことはありませんが)
余談:FIXEDのみディメンションとして使用できる
ここまで集計についてお話しましたが、FIXEDのみディメンションとしても使用できるので、必ずしも集計しなくても良い場合もある、ということだけ言及しておきます。
(そしてディメンションにもなるということは、Binが作れます。便利ですね。)
ちなみにINCLUDE、EXCLUDE、集計、表計算がディメンションにできない理由もこの辺りから垣間見えますが、それはまた別の機会に。
ここまでのまとめ
長くなりましたが、もう一度まとめます。
TableauがLOD計算をSheet上に表示する際に行っていることは以下です。
LOD計算の結果を出すために、LOD計算の結果作成に使用されるディメンションによる集計テーブルを裏側で作成
LOD計算の結果作成に使用されたディメンションを用いて、Sheet上のテーブルと1の結果を結合
必要に応じてLOD計算の結果をSheet上で集計する
このイメージを常に持ち、かつFIXED・INCLUDE・EXCLUDEそれぞれが「どのような裏側のテーブルを作るのか」を理解すれば、LOD計算は必ずマスターできます。
ということで、それぞれのLOD計算を見ていきましょう。
FIXEDが作る裏側のテーブル
FIXEDは「LOD計算の中で指定されたディメンションを用いた集計テーブル」を作成します。
INCLUDE、EXCLUDEの解説に先立ち、FIXEDの重要な性質を述べます。
FIXEDを用いたあるLOD計算の計算結果は、Sheet上のディメンションに依存せず、常に同じ結果を保証します。
言い換えればLOD計算の中でFIXEDのみ、Sheetに対して独立しています。
この点はINCLUDE、EXCLUDEを解説した後に改めて言及します。
また「Sheetに対して独立でない/Sheetの作りに依存する」とは、どういうことでしょうか。
INCLUDEが作る裏側のテーブル
INCLUDEは「LOD計算の中で指定されたディメンションを、Sheet中のディメンションに追加して集計したテーブル」を作成します。
INCLUDEの基本概念は、INCLUDE計算で作られる裏側テーブルのディメンションが「Sheetのディメンション + INCLUDE計算式内のディメンション」ということです。
ここが先ほどの「Sheetに対して独立なLODかどうか」に関するポイントです。
FIXEDでは裏側テーブルが必ず指定されたディメンションで作成されるのに対し、INCLUDEでは裏側テーブルのディメンションはSheetに依存します。
例として、全く同じINCLUDE計算式を2つのSheetで用意します。
上図のように、INCLUDEが使用されるSheet上のディメンションが何かによって、INCLUDEで作成される裏側テーブルの形が変わります。
そして最終的に裏側テーブルの数値はSheetに結合→集計されるので、最終的にSheet上で見える集計値も異なってきます。
したがって「Sheetの作りに寄らず、常に同じLOD計算結果を出したい」のであれば、FIXEDを使用する必要があります。
一方でFIXEDはディメンションの指定が必要なため、もしディメンションを多めに使うSheetでLOD計算をするのであれば、INCLUDEの方が実装が簡潔という場合もあります。
または「その他のディメンションはあってもなくても良いが、いつも特定のディメンションを含めるLOD」という場合もINCLUDEで十分かもしれません。
FIXEDを使うべきかINCLUDE/EXCLUDEを使うべきかという議論は、正直なところ「やりたいこと次第」という点が否定できません。
それぞれの特性を理解した上で考えるという姿勢が良いのかなと思います。
(後述しますがTableau操作の順序も加味する必要がありますよね)
EXCLUDEが作る裏側のテーブル
EXCLUDEは「LOD計算の中で指定されたディメンションを、Sheet中のディメンションから除外して集計したテーブル」を作成します。要はINCLUDEの逆ですね。
解説するべき事項は、既にINCLUDEの項でお話ししました。
集計粒度が粗くなるので、ある集計値に対して「より粒度が粗い場合の集計値」を併せて使いたい場合に重宝します。
Tableau操作の順序でみるLOD計算の違い
最後に、Tableauの操作の順序について言及します。
最初に今回の解説ポイントを述べます。
FIXEDはディメンションフィルターの前に来る
INCLUDEとEXCLUDEはディメンションフィルターの後に来る
以下に例を一つご用意しました。
ここではFIXEDとEXCLUDEを用いて、どちらも「CategoryごとのSUM(Sales)」を計算させています。
またディメンションフィルターとして「Segment」を使用しています。
ここでSegmentのフィルターを変えてみます。
ご覧のように、FIXEDでは数値変化がありませんが、EXCLUDEでは数値変化がみられます。
理由はFIXEDはディメンションフィルターの前に計算が走るのに対し、EXCLUDEの計算時では既にディメンションフィルターが適用され、EXCLUDE計算により作成される裏側テーブルの時点で「Segment = Home Office」のデータがフィルターされているからです。
言い換えれば以下となります。
FIXED計算による裏側テーブルは、ディメンションフィルター適用前に作成される。
INCLUDE/EXCLUDE計算による裏側テーブルは、ディメンションフィルター適用後に作成される。
上記の例を少し膨らませます。
下記のような「全体に対するSales合計の割合」を見せるVizを作るとします。
左側はパーセントの分母にFIXED計算が用いられており、右はEXCLUDE計算です。
左は「フィルターされているSegmentも加味したパーセント」を表示させているのに対し、右は「残ったSegmentのみを加味したパーセント」を表示させています。
前述のとおり、FIXEDかそれ以外かは「やりたいこと次第」です。
集計のタイミングが異なり、したがって見えるべきものも異なってきます。
最終的に何が見たいかを考えた上でどちらを使うかを選択する必要があると思います。
ところでEXCLUDE版のグラフについて「表計算で同じものは作れる」という考えもありますが、こちらも注意が必要です。
INCLUDE/EXCLUDEはメジャーフィルターの前に計算しますが、表計算はメジャーフィルターの後です。
以下に表計算を併せて見るVizを作りました。
ディメンションフィルターにSegment、メジャーフィルターにSUM([Sales])を使用しています。
まずSegmentでフィルターをかけます。
(ディメンションフィルター)
EXCLUDEも表計算もディメンションフィルターの後なので、結果は同じですね。
次にSUM([Sales]) > 250,000でフィルターをかけます。
(メジャーフィルター)
EXCLUDEと表計算で結果が変わりました。
したがってFIXED vs EXCLUDEの議論と同様に、Vizをどのように設計するか、どのようなことがしたいのかに合わせて適切な計算方法を選択しなければいけません。
過去何度か自分のブログでTableauの操作の順序について言及していますが、Tableauでダッシュボード開発をする方は必ず理解することを強くお勧めします。
そうでなければ、フィルター操作の際に想定していない数値が表示される可能性があります。
正しく設計するために、この操作の順序の理解は必須です。
最後に
長くなりましたが、今回の記事ではLOD計算について解説しました。
以下にポイントを列挙します。
LOD計算は「Tableauが裏でLOD計算用の集計テーブルを作り、それをSheet上で結合させている」イメージ。
FIXEDは「LOD計算の中で指定されたディメンションを用いた集計テーブル」を作成する。
INCLUDEは「LOD計算の中で指定されたディメンションを、Sheet中のディメンションに追加して集計したテーブル」を作成する。
EXCLUDEは「LOD計算の中で指定されたディメンションを、Sheet中のディメンションから除外して集計したテーブル」を作成する。
FIXEDはSheetに対して独立。INCLUDE/EXCLUDEはSheetに依存。
FIXEDとINCLUDE/EXCLUDEでは計算の実行タイミングが異なる
Tableauの操作の順序は理解しておいた方が良いです
また表計算記事と同じように、あくまでも考察記事であることをご了承ください。
各種実験、ケーススタディからLOD計算の動作原理を説明する取り組みでした。
(本当はTableauの技術チームとお話して確認したいところですが)
したがって技術的側面や実際のTableauの仕様との齟齬はあるかもしれませんが、むしろ技術的アプローチから今後議論が進んでいけば幸いです。
ご質問等はTwitterまたはLinkedinまでよろしくお願いします。 それでは。