エンビジョン集計

エンビジョンでのデータ集計


ホーム » コマース分析 » このページ

データ集計は、“アグリゲータ”という特別な関数で複数の表の行を結合するプロセスです。合計、平均、カウントまたは中央値が関与しているときはいつでも、アグリゲータを介した計算が行われています。アグリゲータは、異なる表から発生したデータを合成する方法も提供します。エンビジョンは、そのようなすべてのシナリオをサポートする豊富な構文を備えています。このページでは、エンビジョンでのアグリゲータの動作について詳述します。

作図スクリプト

本ページでは、再度、アカウントの/sample1パスからアクセス可能なデータセットサンプルを使用します。下に示すスクリプトは中程度の複雑さですが、エンビジョンで利用可能ないくつかのデータ集計のパターンを示しています。データ集計はタイルの外側とタイルの内側の両方で行うことができます。本ページの内容を理解しやすくするためにも、先に エンビジョンで計算を行うを読んでください。

read "/EnvisionSamples" all
expect Orders.Quantity : number

show label "Filtering data with Envision" a1f1 tomato

totalPurchased := sum(PurchaseOrders.NetAmount)
totalSold := sum(Orders.NetAmount) when date >= end - 365
show table "Total purchased{$}" a2c2 with totalPurchased
show table "Sold over 1 year{$}" d2f2 with totalSold

VolumeSold = sum(Orders.NetAmount)
UnitSold = median(Orders.Quantity)
show table "Top sellers" a3f4 tomato with \
  Name, \
  VolumeSold as "Sold{$}", \
  UnitSold as "Median" \
  order by VolumeSold desc

avgRet := avg(distinct(Orders.Date) by Orders.Client)
avgQty := avg(sum(Orders.Quantity) by (Orders.Client, Orders.Date))
show table "Average client returns" a5c5 with round(avgRet)
show table "Average backet quantity" d5f5 with avgQty

Orders.Brand = Brand
show table "Top Suppliers" a6f7 tomato with \
  Supplier, \
  distinct(Category) as "Categories", \
  sum(Orders.NetAmount) as "Sold{$}", \
  mode(Orders.Brand) as "Most frequent brand sold" \
  group by Supplier \
  order by sum(Orders.NetAmount) desc

このスクリプトをLokadアカウントにコピー&ペーストし、一度実行してからその結果のダッシュボードを見ることから始めてみましょう。うまく動作すれば、以下のようなダッシュボードが表示されます。

Image

単一値集計のためのスカラー

エンビジョンの「項目」と親和性を持っていない変数(Item表のどの行にも属さない変数)は、スカラー変数と呼ばれています。エクセルの類似性を考慮すると、エンビジョン変数はデフォルトではエクセルの列に類似していて、つまり、これらの変数はベクトルであり、同時に多くの値を保持しています(実際には1つの項目につき1つの値)。しかし、エクセルの単一のセルのように機能する変数や、単一の値のみを保持する変数を持つことも可能です。このような変数がスカラー変数です。上記のスクリプトは、2つのスカラー変数がどのように計算されるかを示しています。分かりやすくするために、関連する行を以下にコピーします。

totalPurchased := sum(PurchaseOrders.NetAmount)
totalSold := sum(Orders.NetAmount) when date >= end - 365
show table "Total purchased{$}" a2c2 with totalPurchased
show table "Sold over 1 year{$}" d2f2 with totalSold

いくつかのアスペクトが、これらのコード数行で強調することができます。まず、1行目と2行目での2つの割り当ては、スカラー代入演算子である:=を用いて行われています。演算子:= が普通の代入演算子=の代わりに使用されているときは、集計の結果が項目とは無関係な単一値になることを意味します。 次に、変数totalPurchasedtableSold小文字の名前で始まっています。エンビジョンでは変数名の大文字小文字は区別されませんが、この2つの変数名のスペルについてはこの場合ではありません。コーディングの実践では、スカラー値を含む変数の最初の文字は小文字にすることをお勧めします。対照的に、表名とコラム名は大文字で始める必要があります。このガイドラインに従うことで、スクリプトを読みやすく、かつデバックが容易になります。3つ目に、表が1列しかない場合は、スカラー集計はデフォルトでshow table 文内で実行されます。例えば、1行目と3行目は、以下に示されるように1行に結合することができます。

show table "Total purchased{$}" a2c2 with sum(PurchaseOrders.NetAmount)

スカラー数値変数は、エンビジョンの数値変数のように任意の計算にも使用することができます。例えば、-ビジネスの観点からは意味を成さないが- totalPurchasedtotalSoldが一度定義されれば、次の計算をエンビジョンスクリプトの末尾に追加することができます。

mySum := (totalSold - totalPurchased) / 2
show table "My Sum" with mySum

多値集計

エンビジョンは、一般的に表のデータ集計や別の表の結果を投影するなどの多値集計を実行する可能性もサポートしています。したがって、集計は、異なる表のデータを結合する最も頻繁な手法です。具体的には、多く使用されるケースとして、過去の表、つまり、Date列がインデックスされた 表の取得と、Items 表に整列したベクターにこの表を集約があります。

冒頭のスクリプトは、主力商品を表示する表を使ってこのパターンを示しています。つまり、商品は、それぞれの販売量に応じて注文され、その最高値がスクリプトの上部に記入されます。分かり易くするために、スクリプトの該当行を以下にコピーします。

VolumeSold = sum(Orders.NetAmount)
UnitSold = median(Orders.Quantity)
show table "Top sellers" a3f4 tomato with \
  Name, \
  VolumeSold as "Sold{$}", \
  UnitSold as "Median" \
  order by VolumeSold desc

1行目と2行目は前章で検証したスカラー集計に非常に類似した方法で集計を行っています。ただし、スカラー集計で使用された:=演算子の代わりに、等号=で割り当てが行われています。その結果、VolumeSoldUnitSold の双方が表の一部であるベクトルとなります。その結果として、これらの変数はエクセルの列と同様に1項目につき1つの値が含まれています。 summedianはどちらも、アグリゲータというエンビジョンにおいて特別な関数です。 エンビジョンには他にもavgminmaxfirstlastなどのアグリゲータ関数があります。便宜上、このページではエンビジョンのすべてのアグリゲータを検証してはいませんが、詳細はアグリゲータ全リストにて確認できます。

これら二つの集計の結果は3〜7行で定義された表に表示されます。通常、バックスラッシュ\は、単に読みやすさの目的で複数行に分割するために使用されます。さもなければ、スクリプトは非常に長く、読みにくくなるからです。VolumeSoldUnitSoldの2つのベクトルはwithキーワードの後に引数として表示され、またその値は表内に表示されます。最後の7行目のorder by文は その表がVolumeSoldの最高値で降順にソートするよう示しています。

SQLのGROUP BY構文に精通している読者は、1行目のsum計算で使用するグループをエンビジョンがどのようにして分かったのかを疑問に思われるかもしれません。エンビジョンは、デフォルトで、割り当ての右側で「キー」として機能する列を使用してグループ化を行います。Item表-名前が陰関数の表-に属している変数の場合は、(プライマリ)キーとして作用する列がId列です。このように、=記号を使用して項目ごとの集計が行われます。

byを使った明示的な集計グループ

これまで、私たちが実行した集計は、エンビジョンの内在的な集約パターンに依存していました。しかし、すべてのアグリゲータの挙動は、適用グループの指定を明確にするときに使用されるオプションキーワードbyを使って変更できます。では、どのようにbyキーワードが使用されるかを説明していきましょう。

VolumeSold = sum(Orders.NetAmount)
SameVolumeSold = sum(Orders.NetAmount) by Id // 同じ!

2行目はSameVolumeSoldという2つ目のベクトルに割り当てていますが、このベクトルの値は、1行目のVolumeSoldベクトルの値と全く同じです。実際には、暗黙的にも関わらず、by Idも1行目で使用されています。 直感的に、byオプション が使用されるときは、最初はグルーピングターゲットに沿ってグループ化されたかのようになり、次に、アグリゲータが各グループに別々に計算されたかのようになります。本ページの冒頭のスクリプトに示されるとおり、byオプションはかなり複雑な集計を構成する可能性を提示しています。byオプションを使用して集計を行うスクリプトの2行を見てみましょう。

avgRet := avg(distinct(Orders.Date) by Orders.Client)
avgQty := avg(sum(Orders.Quantity) by (Orders.Client, Orders.Date))

distinctアグリゲータは各グループで観察された異なる値の数をカウントします。1行目において、Orders表の行がそれぞれのClient 値にそって最初にグループ化されます。そして、各クライアントごとに個別の注文日の数をカウントします。直感的には、この集計は各クライアントが戻った回数をカウントするものと解釈できます。そして、この結果は、内部のdistinct 集計を含むavgアグリゲータを使って、単一スカラー値に再集計されます。 avgQtyスカラーはカゴごとの購入物の数として解釈できます。計算はsum() by文で始まりますが、by オプションの後は、1つではなく、(Orders.Client, Orders.Date)のように括弧内にコンマで分けられた2つの変数を持つことになります。この構文は、ClientDateでペアのグループを作る、という考え方です。ビジネスの観点で考えると、これはすべてのモノが同じ日に同じカゴで購入されたように扱っており、これが大概の状況への合理的な近似値となります。最後にavgの外部呼出しをし、そのすべてのペアごとに計算されたsum 集計の最終平均値を生成します

より一般的には、byオプションはsum(foo) by (arg1, arg2, …, argN)構文で後続する変数について、任意の数に対応しています。しかしながら、実際には、一度に4つ以上の変数からなるグループに遭遇することの方が稀です。また、引数の順序も集計の計算に使用されるグループには何の影響もありません。

group byを使った表内の明示的な集計

時に、集計を通して、集計されていない原型のダッシュボード内での使用に適している新しい表を生成することができます。したがって、エンビジョンは、タイルの宣言文から直接データを集計することも可能にしてくれます。エンビジョンの性能を可視化する最も直接的な方法は、表内に表示されるデータを集計することです。これはまさに本ページ冒頭のスクリプトで行われています。では、下記にコピーされた関連行をもう一度見てみましょう。

Orders.Brand = Brand
show table "Top Suppliers" a6f7 tomato with \
  Supplier, \
  distinct(Category) as "Categories", \
  sum(Orders.NetAmount) as "Sold{$}", \
  mode(Orders.Brand) as "Most frequent brand sold" \
  group by Supplier \
  order by sum(Orders.NetAmount) desc

show table文は2行目から8行目で記述され、より具体的にみていくと、7行目で、前章で検証したby オプションと全く同じ意味を持つgroup by 文によって集計が指定されています。この時点で、同じ意味を持つのであれば、なぜエンビジョンがgroup by の代わりにby を使っていないのか疑問に思うかもしれません。

答えは簡単です。与えられたタイルにwithに続いて使用される式一覧内であれば、by オプションを使用することは可能です(ここではそのような状況は示されていませんが)。このようにして、group by は、タイルに渡された式の一部であるby 文と、タイル全体して適用するgroup by文との差別化を許可しているのです。言い換えれば、局地的な影響しか持たないby 文とは対照的に、group bywithキーワードに続くタイルに渡されるすべての式に適用しているのです。

group by が使用されるときは、with キーワードに続くタイルに渡されるすべての式が集計されている可能性を提供する必要があります。例えば、下記の1行スクリプトは誤りです。なぜなら、group by Supplierが指定されている一方で、Nameが集計パターンを提供していないからです。

show table "WRONG!" with Name group by Supplier

しかしながら、例えばdistinct などのアグリゲータを導入してこのスクリプトを修正するなら、エンビジョンスクリプトは有効になります。
show table "CORRECT!" with distinct(Name) group by Supplier

このルールの唯一の例外は、ターゲット自体の集計です。本章の最初のスクリプトでは、7行目にgroup by Supplier 文があります。3行目では、Supplier 変数がアグリゲータ無しに記述されていますが、スクリプトは有効のままです。なぜなら、まさにグループ化はSupplier変数に応じて行われるためです。

アグリゲータを置く必要性も8行目のorder by に適用しています。実際、この表は最初に製造者によって集計され、―他のソート順が指定されていない限り―Id 列でソートされています。結果的に、エンビジョンはこれらのグループをソートするためにグループごとに1つの値を計算する必要があります。これがまさにgroup by sum(Orders.NetAmount)文での処理なのです。

tableタイルでgroup byを示してきましたが、この構文は tableタイルに限らず、同じパターンが他のほとんどのタイルで使用できます。例えば、Brandで集計したbarchartタイルを使って本ページの冒頭のスクリプトを拡張することもできます。

show barchart "Sales by brand" with sum(Orders.NetAmount) group by Brand

group by は、前述したbyオプションの一つと同等の構文を使い、複数のベクトルまたは複数の式でグループ化されるマルチグループ化にも対応しています。

FORMATTER ERROR (Transcluded inexistent page or this same page)