The Database Management Systems, Chapter 3: The Relational Model

インターネットとかしてるうちに 4:50. コーヒー淹れる時間はなし。

Database Management Systems, 3rd Edition: Ramakrishnan, Raghu, Gehrke, Johannes

なんかもうちょっとモダンな教科書がないかと探したけれど、大学の授業では今でもこれが指定されていたのであきらめて再購入。(この Ullman らのやつも気になるけど、Standford でしか使われていない。 )

そして 3 章はベーシックすぎで、自分が探していたのは Chapter 4 Relational Algebra and Calculus だった。引き続き読む。

昔読んだときは SQL とか興味なくて前半ぜんぶすっ飛ばして後半の実装編だけ読んだけど、今はストレージとか興味なくて relational model とか読んでる。年取ったな。

Relational Algebra の完了。さすがに四半世紀プラスを経て Codd のオリジナルよりはだいぶ洗練されているが、これじゃ全然 SQL 実装できないじゃん?と思ったら、最後に query optimizer では a variant of relational algebra を使うよ、chapter 15 を読んでね、と書いてあるので明日は chapter 15 を読みます・・・。

余った時間で Chapter 5 SQL: Queries Constraints, Triggers をパラパラめくると nested query (subquery) は relational algebra にはないけど、頑張って変換できるよ chapter 15 を見てね、とあるのでやはり chapter 15 を読むしかない。ただその前にこの Chapter 5 を読んだ方がよさげ。


ところで自分は SQL の select <何らかの式> というやつは projection だと思ってたんだけど、projection は columns を選ぶだけである。Chapter 5 の例も column を選ぶ (あるいは aggregate する) 以上のことをしていない。<何らかの式> があるとすごい表現力変わっちゃうと思うんだけど、大丈夫なのかねえ。


ついでに目次をパラパラやると OLAP の章があるね。これもあとで読もうかな。一方 OLAP はあるのに columnar がない!まじで。この教科書が 2003 で C-Store が 2005 なので、そうか・・・。ところで C-Store も Stonebraker なのか。PG よりよっぽどインパクトあるねアカデミックには。そりゃ Turing Awards もとるわ。

The POSTGRES next generation database management system

XX 活動とつけるのはめんどくさいので割愛。The Red Book を冷やかしつつ Stonebraker の出世作として Postgres も一本くらい読んでおくかということで:

まあしかしなんというか、何が novel なのかよくわからないな。システム論文なわけだが Implementation のセクションで “POSTGRES contains a fairly conventional parser, query optimizer and execution engine” と言われてしまうとどうにもならない。novel なところとしては plugin みたいのがあるところと言っているが、個人的にはそういう拡張性を高めた話は割とどうでもいいのだよなあ。

とはいえおかげで PG には色々な拡張が施されているのも事実なので appreciate すべきなのだろうけれど、この論文は high-level すぎてそのへんは伺いしれないのであった。

読譜活動 – ZetaSQL – Algebrizer

さて間が空いてしまったが続けます。04:07. ベッドから直行してしまったが、あとで着替えコーヒー休憩が必要。

  • evaluator.h および evaluator_base.h を見ると、評価は PreparedStatement という形で API になっていることがわかる。Execute() というメンバ関数がある。
  • そして internal::Evaluator という非公開クラスに移譲される。
  • このクラスは SQL を Prepare() のち ExecuteAfterPrepare() する。
  • Prepare() は要するに Analyzer すなわち resolved AST を作るんでしょ・・・と思いきや、それに加えて Algebrizer というのがあるな。
  • Algebrizer::AlgebrizeQueryStatementAsRelation() という関数が呼ばれているので見てみるとジャンプ先の algebrizer.cc は突然 5000 具合あってギャーっとなる。関係代数に変換するということなのだろうか・・・。
  • 関数の出力は RelationalOp クラス。これは operator.h に定義されている AlgebraOp のサブクラスで、Yet another tree を構成している。そういえば Duck にも Logical op だの physical op だのがあったね。つまり Algebrizer はいわゆる planner なのだな。
  • で Resolved AST を traverse して Algebra tree に変換していく。たとえば ResolvedTableScan は TableScanOp になる by AlgebrizeTableScan() この辺の方のデザインは duck もだいたい同じで duck と zeta が互いをコピーするのはタイミング的にどう考えても不可能なので、なんか元ネタというか系譜があるな。どこから来たのだろうねこのデザイン/アーキテクチャ。

ここから先は自分の関係代数というかデータベースリテラシ不足で読んでもわからん感。修行して出直す必要がありそう。

肝心の Evaluation はまだ読んでないけど、理解のない状態でこれ以上読み進めても不毛なので Zeta Reading はここまで。

読譜活動 – ZetaSQL – AST, Expression Resolution

05:03. 雨。

さて expression の評価は大物なので、その前にパースの最初のほうをチラっと見て置くべし。

  • gen_parse_tree.py AST はやはり自動生成で, 8000 行。AST への type-safe access (this->_field = (FieldType*)this->children[i] みたいな boilerplate を省く) のと、あとは Visitor の visit を生成している。こういうの Chrome とかだとマクロで頑張ってた気がするけど、生成なのだね。二周目、三周目ならではの過剰感。
  • bison_parser.y – 9800 行! あとちょっとだ! なお duck の y は複数ファイルに分割されているのでてっきり bison にそういう機能があるのかと思っていたが、これは Python で連結しているだけらしい。しかも libpg_query ではなく duck 勢の仕業。どっちがいいのかわからんな。普通に C preprocessor くらいでいいんじゃないか・・・。
  • なお bison_parser.py のコメントは文法の曖昧なケースをきちんと解説している。全体にコメントの質の高さは特筆すべきだね Zeta. 一方 shift-reduce conflict が何だったか完全に忘れているわたくし。
  • それにしても Modern C++ を受け入れると semantic action を割と綺麗に書けるのだね。Bison never dies (in C++ land)…

まあ AST を python で生成している以外は概ね普通の作りであった。Expression の resolution に戻りますかね・・・ resolver_expr.cc

  • Proto をネイティブサポートしており、それがかなりの複雑さを積み増している。型システムの解釈には proto の descriptor が直接使われており、大変ですね感。
  • ResolveFunctionCallImpl: 関数呼び出しを眺めます。なんか flatten といのが特別扱いされているね。
  • named argument あんの?ほんとに?ほんとだ!Zeta 活動が終わったころには BQ マスターになれるかもしれないわたくし。しかし “=>” かよ・・・。
  • ResolveExpresssionArguments – そして引数の解決を見ます。これは変数の解決となんか違うのだろうか・・・というと余計なチェックが入って、あとは変数の解決である。
  • Lambda あんの?BQ にはないっぽいが、そもそも lambda を引数にとれる higher-oder function (“こうかい” が変換できない MS IME) というのは SQL の世界にあるのだろうか・・・そして SQL をパースするのはいいとしてそれを database は実装するのだろうか・・・。やばいな。まあ CREATE FUNCITON とかで作った pure SQL の関数だったらバックエンドの手前でいろいろできるのかもしれないが。
  • 全体的に警告やエラーメッセージにかなりの行数を割いていて引き続きえらいね、というかんじ。他の真面目な静的型言語のパーサも一度ちゃんと読んでみるべきだろうな。
  • 関数は overload できるので signature がある(FunctionSIgnature)。Catalog の Function は list of signatures を持っている。
  • とにかくめちゃめちゃエッジケースがあって厳しい。もはやエッジケースというレベルじゃない。だいたいこういう雑な言語は実行時(実際の評価時)にエラーを出して済ませる動的型の言語であることが多いし、世の中の SQL もそういう実装がそれなりにあるはずだが、Zeta はパースだけするというデザインの都合からそれを静的に解決しようとして複雑さを高めている。その複雑さの集積がこの 8000 行のファイルなわけだな・・・。
  • そしてこの手の巨大なファイルを読むのに VS Code は向いてないな。IDE でクラスの構造化情報が左側の pane に必要。これは VS Code のせいというよりクソデカファイルのせいだが、そういうのと戦う道具というのも必要なのだよ・・・。ただほぼ何も設定してないのに Jump to definition がなんとなく動くのはすごいよね vs code. これは traditional VS C++ toolchain の資産だよな。

はー今日はここまで。式の resolution はもうこのくらいでいいかな。無限の細部があるけど SQL 詳しくないので appreciate できる気がしない。次回は式の評価の参照実装でも覗いてみますわ。

あと宿題としてはドキュメントに目を通すというのもあるね。

読譜活動 – ZetaSQL – SELECT

顔洗ってひげ剃ってコーヒー淹れて 5:10. 読んでくぞ。

  • まず FROM を解決するらしい。主要な入力である NameScope と主要な出力である ResolvedScan を覗いてみるべし。
  • NameScope は基本的には column (ResolvedColumn) を参照するものらしい。まあそうですね。ただ column の field (proto, struct) を参照できるのが特徴的といえる。Duck は field とかどうしてたっけな。
  • ResolvedColumn は globally unique な column_id を持っている。これで何を lookup できるのだろうか、というとテーブルとかなはずだが、あとで出てくることでしょう。
  • ResolvedScan は ResolvedColumn のリストである。
  • ResolveFromClauseAndCreateScan(). いやーコードはクリーンだしエラーメッセージは丁寧だしたいしたもんだわな(エラーメッセージの国際化はゼロだが)。むしろ初代 Dremel SQL がどのくらい雑だったのかに興味が出てくるが、そういうものはオープンソースではないのだった。Dremel はともかく世の中のオープンソースな SQL 実装を比べていくのはパーサーソムリエ的な楽しみがあるかもしれない。
  • FROM clause から現れる “scan” は何種類かあり、代表的なのは “array scan” と “table scan”. あとはサブクエリとか table value function とか。
  • “array scan” はその名の通り array を FROM に指定できるらしい (BQ のリファレンス)。Array の扱い超難しいね・・・そしてここではまだ catalog が出てこない。Catalog どこいった。
  • ResolvePathExpressionAsTableScan() – catalog_->Find() しているね。しかしその周辺が複雑であることよ・・・。ところで ResolvedColumn::column_id は Resolver が (catalog の) Column を lookup するのに使っており、この関数の中で ID が割り振られている。つまり実際の Column の identity を保証するものではなく、FROM にテーブルが出てくるたびにその column に新しい ID が与えられる。(それは catalog のオブジェクトが担保する。)
  • コードのクリーンさを SQL という言語の魔窟さが打ち消しており、すごいね・・・。
  • まあ FROM でテーブルから ResolvedColumn や ResolvedScan が作られるところは見届けたので、次は select list の解決でも眺めていくかな。関心は column name の解決と、式。
  • ResolveSelectColumnFirstPass() – こういうのを読んでて思うこととして, select list は式を評価する仕事と評価結果に名前を付ける仕事を同時にやっており、しかし名前を付ける方は割と SQL が勝手にやっているということだよな。たとえば t.col1 とかやった場合の alias は col1 になることが多いが、こういう naming の挙動は標準化されているのだろうか。とてもそうとは思えないのだが・・・というのも式だけ書いた場合の alias とか GetAliasForExpression() が勝手につけてるんだけど、すごい恣意的じゃない?
  • 式を解決するぞ! ResolveExpr() … は resolve_expr.cc で定義されており、これは 7000 行です。式の解決が 7000 行あるのは特に驚きはないが、これとは別に resolve_query.cc が 8000 行なところに SQL のヤバさがあると言えよう。
  • といったところで時間切れ。ラップトップをでかい画面につなぎたくなってきた。あとメモリ・・・。

読書活動 – Information Dashboard Design Ch 4, Ch 5.

Chapter 4: Fundamental Considerations

Dashboard を作るときって色々気にすべきことあるよね

  • Update frequency – daily, hourly, realtime
  • User expertise – novice to expert
  • Audience size – one person, sharing the same purpose, having different purposes
  • Technology platform – Web, etc.
  • Screen Type – Large to small
  • Data Type – Quantitative Non-Quantitative

だからどうしろという話はこの章にはナシ。

Chapter 5: Tapping Into The Power of Visual Perception

  • The limits of working emory
  • Encoding data for rapid perception
  • Gestalt principles of visual perception

人間の知覚の特性を議論する。たとえば working memory みたいなよく知られた概念・・・がある故に、なぜスクロールがダメかを議論したり、データのエンコード先を分類し、それぞれが何に適しているかを議論したりする。

  • Color – hue, intensity
  • Form – line length, line width, orientation, size, shape, added marks, enclosure
  • Position
  • Motion

これらのうち人間が際を正しく判断できるのは line length と position だけであり、色、大きさ、角度とかは「違う」というのはわかっても「どのくらい違う」は誤解しがち (だから bar chart はダメ)だそうな。たしかに。countour とか色でがんばってるけど、あれは連続的に変化しているからなんとかなっているのだろうか。

Gestalt principle:

  • Proximity
  • Similarity
  • Enclosure
  • Closure
  • Continuity
  • Connection

Gestalt principle は、要するに見えないはずのものが見える人間の知覚の特徴みたいな話。こういうのを生かすと arrangement が subtle でも表示に意味を与えることができる。たとえばわざわざ枠を書かなくても距離を調節することでグルーピングを表現したりとか。

この章はよかった。どう現実に適用していくのか後の章が楽しみ。

読譜活動 – ZetaSQL – execute_query

朝起きるとコンパイラが死んでいた。昼休みにちょこちょことなんとかする試み。

  • メモリが足りないのでしょう、ということで wsl.config で 6GB だったキャップを 12GB に拡大したところビルドは成功。メモリ買うかな・・・。
  • execute_query のバイナリができたので README にあるとおり execute_query “select 1 + 1” を実行したら、なにかが返ってきた。
$ bazel-bin/zetasql/tools/execute_query/execute_query "select 1 + 1"
+---+
|   |
+---+
| 2 |
+---+
  • execute_query –helpfull をするといろいろフラグがある。最近の ABSL flags はフラグを定義しているファイル名が表示されるようになっており、ちょっと便利。 
$ bazel-bin/zetasql/tools/execute_query/execute_query --mode=explain "select 1 + 1"
RootOp(
+-input: ComputeOp(
  +-map: {
  | +-$col1 := Add(ConstExpr(1), ConstExpr(1))},
  +-input: EnumerateOp(ConstExpr(1))))
  • –mode=explain するとこのような実行計画的なのが表示されるのだが、SQL のパーサなのに実行計画とは?というかそもそもなぜ SQL を評価できるのか、不思議といえば不思議。なんらかの参照実装的なのが入っているんだろうけれど。
$ bazel-bin/zetasql/tools/execute_query/execute_query "create table hello (foo integer)"
ERROR: INVALID_ARGUMENT: Statement not supported: CreateTableStatement [at 1:1] [type.googleapis.com/zetasql.execute_query.ParserErrorContext='\n create table hello (foo integer)']
  • テーブル定義すらできないが、そもそも式を評価できる時点で不思議なので別にいいといえばいいです。はい。

次回はもうちょっとコード読みます。

誤読活動 – A layered grammar of graphics

A layered grammar of graphics

というわけで ggplot2 論文。これは…素晴らしいね。本家 GOG で曖昧だった部分をすべて明らかにしたのみならず(たとえば transformation のよくわからなかった部分は丁寧に解説されている)、整理しなおし拡張している。そして可視化の best practice のようなものにも言及している (ex. “In practice, many plots have (at least) three layers: the data, context for the data, and a statistical summary of the data.”)。コードもある。

一方、当然なら本家 GOG を参照しているのであれを読んでいないと割と意味不明ではある。そういう意味で GOG は Hadley のこの論文を読むための税金だったのだと思えば許せる。

そして読んでいて気付いたが、ggplot2 にあるのに Altair にない機能が普通にあるね。Contour とかないじゃん。これ超欲しいんですけど。

これに限らず、Hadley の可視化に関する知見を学ぶためにこの人の書いた本を読むのは意味がある気がする。

心の積読にしておこう。

さて、これで星空日記から始まった可視化入門の旅は終わった。次にやることを考えないとな。まあ dashboard の本は読むとして、あれだけだと若干退屈なのでもうちょっと他にないか考えようではないか。イメージとしては dashboard の本は私用 laptop にアクセスできない会社の昼休みとかで読み、家ではもうちょっと手を動かす感じにできないかなあ。まあ無理に手を動かさなくてもいいんだけど、画面でないとできない活動、同じ読むでもコード読みとか、そういうかんじの何かをやりたい。Notion にでも書き出して考えるべし。

誤読活動 – The Grammar of Graphics

The Grammar of Graphics | SpringerLink

というわけで一通り読んだが・・・わけがわからん。

ハイレベルな主張はそれなりに理解できる。つまり、データの可視化というのは以下のようなステップからできていて、それぞれのステージの仕様を指定の上データをつっこめばグラフができるんだよ、というはなし。 *

  • まず入力は Data. これがなんなのかははっきりしないが、最初のステップ “Variable” ではこのデータを “Varset” というやや奇妙なモデルに変換する。これは雑に Pandas の indexed Series だと思えば良い。つまり、基本的には配列だが、ここの要素に index (ID) がついている。この index のおかげで他の Varset と Join できる。
  • 次のステップは “Algebra” で、ここで実際に join したりする。つまりこの Algebra は関係代数みたいなものである。なんか微妙に関係代数とは違うっぽいが、なぜなにが違うのかもその動機もはっきりしない。実際 Polaris では「我々はオリジナルを無視して関係代数に寄せます」といっている。
  • 次のステップは “Scale”. たとえば線形だったのを log scale に map したりする。
  • 次のステップは “Statistics”. ここで何らかの aggregation を行う。しかしどうやって group by 相当のことができるのかはナゾ。
  • 次は ”Geometry”. Point, Line, Area, Bar, Histobar, Tile, Contour とかを選びます。ここまでパインプラインの上を流れてきたのは Varset だったけど、この出力は Graph です。何が違うのかはナゾ。
  • 次のステップは “Coordinates” です。座標系を選びます。表示したいデータの次数が二次以上なら projection とかもします。
  • 最後が Aesthetics です。これはデータをどの見た目にマップするかを選びます。 x, y, color … このステップを通るとデータは ”Graph” から “Graphics” になります。これで無事描画できます。よかったですね。

よくねえええー。

この論文から Altair 的なものの面影を見ることは、頑張ればできなくもないが、これを読んでなにか可視化システムを実装できる気が全くしない。あまりに細部や具体性がかけている。Polaris paper を読んだ瞬間に「これ我々が使ってるダッシュボードの祖先じゃん!」と全てを理解してショックを受けたのとはだいぶ違う。

この論文が(回顧論文であることを差し引いても)2012 に出ていることを考えると、ひどくない?なんか引用されてる話題も 2002-2004 あたりで止まってるしさあ。を読むともう少し理解が深まる可能性はゼロではないが。個人的には「この著者はイマイチ」ということで打ち止めにしておきたい。重要な(かもしれない)アイデアを、ひどく不可解な形で公開してしまった Research Debt だと言えよう。$30 は無駄だった気もするが, GOG (as its original form) は overrated と結論できたのは良かった。Let’s move on.

こんな意味不明なものから GUI 側では Polaris/Tableau を生み出した Pat Hanrahan, API 側では ggplot2 を生み出した Hadley Wickham はマジ神。


そういうムカついた気分はさておき振り返ると、なぜ BQ でひっこぬいたデータを Altair で可視化する作業にもどかしさがるのか、またなぜ内製の可視化ツールはイマイチに感じるのか、理解が進んだ。

まず BQ+Altair のイマイチさは、Altair の ”Statistics” 機能の足りなさが一つの理由だと言える。GoG の世界において statistics すなわち aggregation はパイプラインの一要素である。SQL でデータを扱う我々は SQL で aggregate したいが、Altair の可視化は SQL から分断されたオンメモリの世界で起こる。オンメモリどころかデータを JSON で直列化する必要から 5000 件みたいなデータサイズの制限がある。aggregate するのは大量のデータから特徴を読み取りたいからなのに、その「大量」が 5000 件で cap されちゃうと厳しい。あと Altair というか Vega 側が色々な aggregation を実装しなおさないといけないのもムダ感がある。

よりハイレベルには, visualization と statistics は切り離せないというのが GoG の洞察なのに、Altair/Vega-Lite はそれを切り離してしまっている。これは R の世界で全てが閉じている ggplot2 にはなさそうな問題に見える。しらんけど。

個人的にはオンメモリで頑張るより Polaris みたいに可視化仕様から SQL を生成して必要なデータ整形を全部済ませるアプローチが Python の世界に来てほしい。Vega-Lite のレイヤを JS じゃなくて Python 側に持ってくるのが一つの方向性だろうけど、そういうことは起こらないだろうなあ・・・。

つぎに社内 dashboarding tool のイマイチさだが、これは可視化仕様の指定に GoG 的な composability が足りてないからだろうね。内製ツールの話をここに書いても仕方ないので細部は省略するけど、もうちょっと頑張ってほしかった。

以上。

運営活動 – m.g.i

昨晩は寝る前にダラダラと YT クッキング動画を見てしまい、結果として朝もシャキッと起きられずダラダラしてしまい、顔も洗ってないのにもう 4:35. 6:15 から走らないといかんので今日は読書はなし。Message Passing の原稿整理でもやります。なお最近観ているのは Pro Home Cooks, Joshua Weissman, Ethan Chlebowski, あとたまに J. Kenji López-Alt です。

終了。月末なことだしお手紙活動でもするか・・・。

終了。もうほとんど時間ないけど、昨日会社で印刷してきた論文のつづき読もうかな。

The Grammar of Graphics | SpringerLink

を買ったのだよ。$30 だから $1/page くらいしているが、この厚い本は読みたくないなということで。

  • 代数系を作るといっているが、ほんまかいな感。いろいろサンプルも怪しい。
  • たとえば 1980 年の人口をあらわす pop1980 という集合と 2000 年の pop2000 という集合を “blend” します、これは UNION 相当です。その結果を可視化するとこうなります、というチャートが pop2020 と pop1980 で別の列の pane に facet されているが、なんで UNION したあとなのに年代で group by できるんだよ!元のデータは year みたいな column なくて pop1980 も pop2000 も別の column じゃん!みたいな。
  • そのあとも scale のところでデータを指数表現に transform しますとかいっているが、可視化の legend がどうやって指数表現に transform された事実を知りえるのかまったくわからない。雑すぎる。まったく実装できる気がしない。可視化の dataflow pipeline をトラバースして検出するの?それとも dataflow の上を流れるデータに metadata つけとくの?

といったところで時間切れ。進まん。

読書活動 – Information Dashboard Design Ch 2, Ch 3.

朝起きて顔洗ってコーヒー淹れて着替えて 4:37.

Chapter 2: Thirteen Common Mistakes In Dashboard Design

  • Exceeding the Boundaries of a Single Screen.
    まあこれはわかりやすいね。なお画面を分けるのも、drill down は別にしてやめとけという主張。
  • Supplying Inadequate Context for the Data
    比較すべき数字が含まれていない(平均、目標など)。良い悪いだけでなく、どのくらい良い・悪いのかがわからないとだめ。
  • Displaying Excessive Detail o Precision
    逆に細かすぎる、みたいなの。ビジュアルが伴わない場合はなおさらそうだよな。というか table はイマイチな気がするな。自分の dashboard もちょっと table を混ぜちゃってるけど、あれは細部として切り離したほうがよさげ。
  • Expressing Measures Indirectly
    伝えたいことが伝わらない指標を使っている。例では予実の時系列チャートを挙げており、予実の額自体をプロットするのをダメとしている。かわりに予算を定数とし、予算に対する実際の出費の % をプロットしたほうが良いとしている。予算超過しているかどうかがわかりやすいから。なるほど。なお仕事ではもっとあからさまにダメな indirect measure が問題になったことがある。それは直したけど、他にもこういうのありそう。”Indirect” という語彙があると指標を殺したいときの説得には役立つげ。
  • Choosing Inappropriate Display Media
    Bar chart はやめておけ、まして 3D は最悪だ。あと二種類くらいダメなチャートが乗っており、かつ後の章でも詳しくやるらしい。仕事、社内ベータユーザの OS ビルドの分布を pie chart で出しちゃってるけど、だめかな・・・。エントリが多いと bar chart はかさばるのだよなあ・・・。後の章に期待。
  • Introducing Meaningless Variety
    無意味に使う chart の種類を増やすのはやめなさい、boring とか気にしないで consistency 大事にしなさい、という話。
  • Using Poorly Designed Display Media
    単一のチャートのダメさについて、いくつか例を示しながら議論している。詳しくは Show Me thee Numbers という別の本を読んでねとのこと。はい
  • Encoding Quantitative Data Inaccurately
    グラフはゼロベースにしろよなとか。はい。
  • Arranging Information Poorly
    重要な数字は prominent に、注意すべき数字は stand out させ、比較すべきものは隣に置く。
  • Highlighting Important Information Ineffectively or Not at All
    後の章で詳しくやるよ。
  • Cluttering the Display with Visual Effects
    謎の装飾はやめろ、みたいなの。これは自分にはさすがに関係ないが, vendor がつくる昔ながらの dashboard ではたしかによくあったかもしれない。例示される screenshot が厳しい。
  • Misusing or Overusing Color
    無駄に関心を引く色を使っちゃうとか。こういうの dashboarding tool がデフォルトの palette をまともにしてくれればいいんだけど、なんか無駄に赤とか入れてくるよな・・・。その点モダンなチャーティングライブラリはえらい。
  • Designing an Unattractive Visual Display
    過剰な装飾はダメとはいえ ugly すぎるののも困るから aesthetics も気にしような、あとの章で教えてやるかんな、という話。はい。

今や自明なものもあるし、なるほどというものもあるし、よくわからんから後の章に期待というものもある。コンテクストの不足、情報の過剰、Arrangement の工夫、一画面に収める、とかはできてないときもあるので次からはちゃんとやりましょう自分。

Chapter 3: Assessing What’s Needed

  • 要件定義ちゃんとしような、という章。
  • Begin With a Definition
    “It is an information display that will keep them aware of what’s going on in their specific realm of concerns”. EDA とかのツールじゃないからね、という話。
  • Focus on the Goals, Not on the Means
    エンドユーザからの fancy にして欲しいという要望は無視し、彼らの必要とするものを作ってあげなさいね、という話。はいはい。
  • Get into People’s Heads
    Dashboard を読む人のメンタルモデルに沿って画面をデザインしてあげようね、読み手のメンタルモデルをインタビューするときはホワイトボードに図を描いてもらって、いろいろ質問しながら図に矢印とかを書き足してもらおうね、初心者はそもそもメンタルモデルがないときもあるから育ててあげようね。という話。
  • 最後は余計なお世話というか出過ぎた主張だと思うが、Dashboard はさておきメンタルモデルや問題意識の共有というのは必要で、しかし自分はしばしばさぼりがちである。PM とかこういうの話し合うの好きで、話が長くなって仕事が進まないのでイヤだなーといつも思っているが、数字を中心とした design doc 的なものを書いてそれを dashboard という形で実装する、というフローは必要なのだろうなあ。business objective の定義みたいな。まあ business ってほどじゃない性能上の指標なんだけど。
  • Ask the Right Questions
    • Dashboard の更新頻度は?
    • 誰が読むの?
    • 何をモニタするの? なんの目的で?
    • どういう疑問にこたえたいの?
    • Dashboard をみてどんなアクションをとりたいの?
    • 具体的に表示したい項目は? それぞれ何がわかるの? 詳細が必要なのサマリが必要なの?
    • 目的のために一番重要なのはそのうちどの数字なの?
    • どういう logical grouping があるの? 各数字はどの group なの?
    • どの数字とどの数字を比べたいの? 互いにコンテクストを提供できる数字たちはどれ?
  • このリストは comprehensive ではないといってるが、良いリストだね。耳が痛い。Dashboard design doc があるとしたらこういう質問には答えてしかるべきだな。作ってみないとわからないものもありそうだけど。
  • Identify Information that Really Matters
    上の質問リストに出てきた数字のうち、実際に性能に影響を与えるものだけを dashboard に含めなさい。人々は実際には使わない数字を念のためと入れたがるけど、空間や関心を無駄遣いするのでやめなさい。入れたがり屋さんには「あんたその数字をみてどう行動するわけ?」と聞きなさい。そうですねー。EDA してた名残でなんとなく入れちゃうチャートとか、割とあるよね。
  • Identify Useful context for Measures
    それぞれの数字を読むにあたって役立つ context が何か identify しなさい。たとえば “targets, standards, measures of the norm, or the past data.” – “Compared to What?” – これ全くその通りだけど一方で内製の dashboarding tool はチャートにこういう情報を埋め込む支援が全くない、というか不可能。Altair も支援といえるものはないけど、コードを書けば任意の線を埋め込めるのでなんとかなる。むしろ dashboarding tool 側ではなくそいつの参照する SQL の側にこういう指標を埋め込んで、可視化用のデータを生成を生成すべきなのだろうな。

短いがなかなか有用な章だった。読書はここまで。

読書活動 – The Food Lab

The Food Lab: Better Home Cooking Through Science

夜は眠くてやる気なくても読める本を寝る前にちょっとだけ読むことが多い。その記録もつけてみる試み。

Chapter 2: Soups, Stews, and the Science of Stock

  • Collagen/Gelatin は connective tissue である。legs, wing, back and skin に豊富。
  • Meat only stock -> flavor. Bone only stock -> body. Carcasses -> Both
  • carcasses は food processor で砕いたのちに simmer する。Flavor が短時間 (45min) でよく出る。Gelatin は摘出されないがそれは市販の gelatin を足せばよい。

移行活動、読書活動

夢。仕事帰り、広尾の築四十年家賃七万円のアパート、屋外の小汚い共用洗濯機で隣人と雑談しつつ服を洗いながら、そろそろ親も年だし実家の近くに引っ越して、家賃ももうちょっと金かけて小ぎれいなところに住むかなどと考える。その汚い洗濯機を使うなコインランドリーにしておけ!と動揺して目が覚める。隣人との雑談がなぜか英語である。そしてあのアパート、洗濯機は自分で持ち込んだ気がするな。

さてブログを公開しないと。

一目にさらすのが憚られるエントリをドラフトに戻し、ドラフトのうち今みると別に公開してもいいかと思えるものを公開に切り替え、気づいた範囲でタイポを直し、git commit -u && git push. Netflity の設定が死んでいなければ公開されることでしょう。Netlify にしてあるよね?なんかいろいろ mess なのだよな・・・と Netflity の dashboard を見たところ、ファイル名不正とかで失敗していた。修正。

はい、無事公開されました。よかったね: steps to phantasien

というわけで code-server を動かしていた VM も停止。

はーこれで “steps to phantasien” というブログも終了。この名前はもはや四半世紀くらい使っているはずだな・・・と Web Archive を確認すると・・・。あった中二病が痛すぎてリンクをするのに躊躇するが、この URL を思い出すのに一分くらいかかったので記憶から消え去る前に記録しておく。それにしても 20 世紀からブログ(という名前ではなかったが)書いてるとかすごくね?お前が東村山で書いてるそのウェブサイトは 23 年後に Mountain View で終わるぞ。黒歴史になりそうなとこは消しとけ、と教えてあげたい。


さて活動記録をつけるにあたりやりたいことや読みたい本を整理するとか Notion を再セットアップするとかをやりたい気もするが、そういうメタ活動に時間を使いすぎるのもアンチパターン感があるので、適当に積読から一冊選んで読み始めます。

Information Dashboard Design: The Effective Visual Communication of Data – 仕事で dashboard を作る機会が増えたものの、それらの dashboard が良いとは思えない(良し悪しの判断すらできない)という足元の覚束なさから買ったまま積んでいた本。

Chapter 1: Clarifying The Vision

  • 世の中の dashboard のダメさ。物理的な “dashboard” の skeuomorphism はゴミという話。へー昔はそういう dashboards がいろいろあったのだねー・・・。
  • Vendor が製品を fancy にみせるためにつけた pre-defined な dashboard のダメさ。へー(同上)。
  • 歴史。90 年代に OLAP や BI がもてはやされ始め、ゼロ年代初頭に Enron のスキャンダルがあってビジネスにおける監視の重要性が見直され花開いたという話。それとは別に工場とかの機器が電子化・ネットワーク化されて画面がつき、その監視のためにエンジニアが考えたゴミのような監視 UI がつくようになった。はあ。
  • Dashboard とは何か:

A dashboard is a visual display of the most important information needed to achieve one or more objectives, consolidated and arranged on a single screen so the information can be monitored at a glance.

P.26
  • スクロールが必要なものはもはや “a dashboard” ではない。一目みてわからないから。
  • Dashboard は用途に応じてカスタマイズするのが大前提である。つまりインフラチームとかが作ってくれているお決まりの可視化ツールは、カスタマイズの支援の程度によってはゴミ化する可能性がある。
  • Dashboard は以下のものではない:

– A display that is used for data exploration and analysis
– A portal
– A scorecard
– A report that people use to look up specific facts

p.30
  • なるほど…
    • EDA を混ぜがち、というは自分の感じていたすわりの悪さを説明している。
    • Portal を混ぜがち(なせいでちゃんとした Portal がない) という問題も同じ。
    • Scorecard は一緒なのでは、と思ったが、そっちには決まったやり方というのがあるらしい。
  • Dashboard は “Situation Awareness” を高める。つまり alert が発生する前からなんとなく全体の状況を把握するのを助ける。のでいざ alert が発生しても慌てなくて済む。
  • Situation Awareness を update する -> 注意の必要なものがあるか判断する -> あれば詳しく見て、対処の必要性を判断する -> 対処するならする。
  • Dashboard は “need to leverage people’s visual capabilities” ということで次章につづく。

今日はここまで。読書は椅子に座ってやるよりタンスとかの上に本を置いてストレッチとかしながら読むほうが眠くらななくてよいね。