データのためのGit(およびGithub)
2014年3月31日 in Featured, Special
(訳注:この記事は本家OKFn.org記事の日本語訳です)
データのために「バージョン管理」を行う能力は重要な関心事です。様々な選択肢がありますが、最も魅力的なもののひとつは、Git やMercurial のように、コード用の既存ツールを再利用することです。この投稿では、私たちが暫くの間使用してとても効果的だということが分かったツールを利用する、データの格納とバージョン管理のための単純な「データ・パターン」について記述しています。
序章
行われた変更を格納し、それを他の人と共有する、データのバージョンとリビジョンを管理する能力、とりわけ分散的な手法は(オープン)データ・コミュニティにとって大きな便益となるでしょう。私はその理由を以前(こちらの初期の記事を参照)議論しましたが要約すると:
- 効率的な分散型の共同作業が可能です。私のデータセットを取り出し、変更し、それを再び私と(同時に他の人とも!)共有することができます。
- 出所をより良く(つまり、どの変更がどこから来たのか)追跡することが可能です。
- シンプルで効率的なやり方で、更新内容を共有し、データセットを同期させることができます。例えば、ファイル全体を再取得しなくても過去数か月のGDPや雇用データを取得する自動的なやり方で。
「データのためのリビジョン管理」問題に取り組む方法はいくつかあります。ここでのアプローチは、私たちがGit とMercurial のようにコードのために設計された既存の強力な分散型バージョン管理システムを利用し、データにそれらを適用することができるということを意味する形式でデータを取得することです。そのため、データのための最良のGithubは、実際のところGithub それ自身かもしれません。もちろん、Git(hub)の上にデータ特有のインターフェースを重ね表示したいかもしれません。 これは私たちがhttp://data.okfn.org/で行っていることにほかなりません。
このアプローチには制約があり、私は、これらといくつかの代替モデルについて以下に論述します。これは特に、「小さな(あるいはミクロな)データ」、例えば10MB あるいは100K行以下の場合に最適です。(ひとつの代替モデルはマックス・オグデンが最近始めた非常に面白いDatプロジェクトで見つけることができます- 彼とは、この話題について何度も話し合いました。)
しかしながら、ツール類に成熟と力があってますます発展しそうであり、そして多くのデータは小さいという事実から、私たちはこのアプローチは非常に魅力的であると考えています。
パターン
パターンの本質は次のとおりです:
- 行指向のテキスト、および特にCSV(*1)(コンマ区切り変数)ファイルとしてデータを格納すること。「行指向のテキスト」は、テーブルの列(あるいは個別のセル)のようなデータの個々の単位が1行(*2)に相当することを単に示します。
- データを格納し管理するのにGit やMercurial のように最適な種類(すなわちコード)のバージョン管理を使用してください。
Git とMercurial のような強力な分散型バージョン管理ツールがそれによって有効に(なぜなら、それらのツールはたいてい行(ライン)指向のテキストであるコードのために構築されるからです)動作することができるので、行指向のテキストは重要です。しかしながら、それは単なるバージョン管理ではありません:これらの種別のファイル(grepからエクセルまで!)を管理し操作するためのツールには多数の、こなれたセットがあります。
基礎的なパターンに加えて、追加できる、いくつかの特別オプションがあります:
- GitHub(やGitorious、あるいはBitbucket等々)にデータを格納する。下記の全ての例はこのアプローチをとっています。
- datapackage.jsonファイルを加えて、集めたデータをSimple Data Format のデータ・パッケージに変えます。これはライセンス、出所およびスキーマ(このカラムは数字、これは文字列)といった不可欠な情報の小さなセットを提供します。
- データの処理と管理に使ったスクリプトを加えてください。このようにして、あらゆるものがひとつのリポジトリにうまくまとまります。
このアプローチの何が良いのでしょうか?
行指向のファイルの管理および操作のために存在する、ツールのセットは巨大で成熟しています。特に、Git やMercurial のような強力な分散バージョン管理システムは、既にコード周りの分散型でピア・ツー・ピアの共同作業を行うための非常に堅牢な方法であり、このパターンはそのモデルをとり、それをデータに適用可能にします。ここに、なぜそれが良いのか、いくつかの具体的な例があります。
出所のトラッキング
Git とMercurial はコミットメッセージとdiff(差分)によって、個々の貢献の完全な履歴を提供します。

コミットメッセージの例
ピア・ツー・ピアの共同作業
データをフォーク(分岐)したり、プル(取り込み)することは、個々の貢献者がそれに関して同時に作業することを可能にします。

プル・リクエストのタイムライン
データのレビュー
Git やMercurial の使用によって、コードレビュー用ツールは、データ調査のために転用することができます。

プル・スクリーン
シンプルなパッケージング
リポジトリ・モデルは、単一の場所にデータ、コードおよびメタデータを格納する、シンプルな方法を提供します。

データ用のリポジトリ
アクセシビリティ
このようなデータ格納および、バージョン管理手法は非常にローテクなものです。フォーマットとツールは両方とも非常に成熟していてユビキタスです。例えば、すべてのスプレッドシートおよびすべてのリレーショナル・データベースはCSVを扱うことができます。すべてのunixプラットフォームにはこれらの種類のファイルに使えるgrep、sed、cut のようなツール一式があります。
例
私たちは、このアプローチと共に長い間使用しています:2005年、私たちは最初にSubversion そして次にMercurial にCSVを格納しました。次に、3年前にGit(そしてGithub)に切り替えた時、私たちはそこに格納し始めました。2011年に、私たちは上記のパターンによって管理されたデータセットの全体のリストを含んでいるGithub 上でデータセットの組織化を始めました。ここに、いくつか具体例があります:
- 国、地方、そして世界のGDPが世界銀行から集められ、そして標準化されたCSVへと変わりました。データをクリーンにするために使用されるPython のスクリプトは、scripts に含まれています。
- スタンダード・アンド・プアーズの500種株価指数(米国のトップ500の公にリストされた株価のインデックス)中の会社の一覧。データを処理するためのPython スクリプトと出典からクリーンにされたデータを複製する方法に関する手順を含んでいます。このデータセットは、悪い差分(例えば再アレンジされたカラム)を含めて、差分がどのように見えるかという面白い事例を提供します。
メモ:ほとんどのこれらの例はGithub 内で管理されているCSVを示すだけでなく、同時にシンプル・データ形式のデータ・パッケージです。-その中にあるdatapackage.json を参照してください。
付録
制限と選択肢
行指向のテキストおよびそのツールはもちろんデータ保存およびバージョン管理に対する完全な解決策からはほど遠いものです。それらはすべての形およびサイズのデータセット用には動作しません。また、いくつかの点で、それらは、表形式のデータへの変更を追跡しマージするには厄介なツールです。例えば:
- 行指向のテキストとして保存されたデータ上の単純な操作が非常に大きな変更セットにつながる場合があります。例えば、2つの項目(=カラム)の順序の入れ替えはすべての行の変更につながります。diff(差分)、マージ等が行指向だとすれば、これは不幸なことです(*3)。
- それは、小さめのデータ(例えば<100k の列、<50mb のファイル、最適なのは<5mb のファイル)に対していちばんうまく動作します。Git とMercurial は、大きなファイルの扱いはさほどうまくなく、diffのような機能はより大きなファイル(*4)ではさらに厄介になります。
- それは、多くの同じ記録(理想的には表形式のデータ)から構成されたデータにとっていちばんうまく動作します。行指向のストレージと適切なツールのためには、行指向のCSV構造に適したデータのレコード構造を必要とします。あなたのCSVがあまり行指向で無い(例えば、項目内に多数の改行がある)場合、diffやマージで問題を引き起こすので、パターンはそれほどよくありません。
- CSVは多くの情報、例えば項目(全て文字列です)の種別についての情報を欠いています。
その単純性を危険にさらしたり、純粋なデータとしての利用がもはやできなくなることを犠牲にせずに、メタデータをCSVに加える方法はありません。しかしながら、個別のファイル内にこの種の情報を追加することができます。それこそデータ・パッケージ標準がそのdatapackage.jsonファイルで提供するものです。
最も基本的な制限は、とりわけ行指向のdiff とマージの、その原子単位が行でない(それはセル、あるいは何らかの2カラムを入れ替えるような変換)構造データへの適用で発生します。
下記で議論されている最初の問題は、テーブルへのシンプルな変更がファイルの全行への変更として扱われる、明確な事例です。完璧な世界であれば、便利な構造とそれをサポートする強健なツールの全体セットの両方があるでしょう。例えばCSVの2カラムの入れ替えをシングルの単純な変更と認識する、あるいは個々のセルのレベルで機能するツールです。
基本的に、リビジョンシステムはdiff フォーマットおよびマージプロトコルの周辺に構築されます。これらを正しくすれば、残りの多くは後からついてきます。基本的な3つの選択肢は次のとおりです:
- 行指向のテキストにシリアライズしてGit のような偉大なツールを利用(上述の通り)。
- 原子構造(例えば文書)を識別し、そのレベル(CouchDB やRDBMS のための標準的な列レベルでの copy-on-write(書き込みの都度コピーする)を考えてください)でdiff を適用する。
- 変換を記録する(例えば、リファイン)。
オープン・ナレッジ財団では、私たちは、2.のラインに沿ったシステムを構築しました、また2.と3.の両方の調査および研究に関係しています – dataprotocols.org 上のデータのための変更および同期を参照してください。これらの選択肢は絶対に詳しく調査する価値があります – また、例えば、マックス・オグデン(彼と私はこの話題に関して多くの大きな議論をしています)は、Dat と呼ばれる刺激的なプロジェクト(「スリープ」プロトコルを使用する共同的なデータ・ツール)に現在取り組んでいます。
しかしながら、ここまでの私たちの経験は、行指向のアプローチがそれらの他の行(少なくともより小さなサイズのファイル用の!)に沿ったどんな現在利用可能なオプションにも打ち勝つということです。
data.okfn.org
数年間このようにGithubにデータを格納してきて、私たちは最近 http://data.okn.org/ をローンチしました。それは明示的にこのアプローチに基づいています:
- データは https://github.com/datasets のGitHub上のGit リポジトリに格納されたCSVです。
- データセットはすべてdatapackage.json のメタデータを持つデータ・パッケージです。
- フロント・エンド・サイトは、非常に単純です – 単にカタログとAPIを提供し、Githubからデータを直接プルします。
なぜ、行指向なのか
行指向のテキストはコードの自然な形式で、したがって巨大な数の優れたツールがサポートしています。しかし、行指向のテキストは、一般的なレコード指向のデータを格納するための最もシンプルで簡潔な形式であり、たいていのデータはレコードになることができます。
最も基礎的な構造化データには、項目用の区切り文字およびレコード用の区切り文字が必要です。コンマまたはタブ区切り値(CSV、TSV)ファイルはこの符号化の非常に単純で自然な実装です。それらは、スペース、改行に加えて最も自然な区切り文字でレコードを区切ります。項目区切り文字として、スペースはあまりに一般的すぎるので、自然とコンマまたはタブに頼ることになります。
バージョン管理システムには、動作の原子単位が必要です。データ用のバージョン管理システムは、とても有効に原子単位としてレコードを扱うことができます。行指向のテキストをレコード指向のデータの符号化に使用することで、私たちはレコード指向のコードのバージョン管理のために構築された既存ツールの形式でバージョン管理システムを自動的に得られます。
- (*1)ファイル中の区切り文字は必ずしもコンマである必要はないので、CSVという場合に、実際は「DSV」を意味するということに注意してください。しかしながら、列終端は改行(あるいはキャリッジリターンと改行)であるべきです。
- (*2)CSVにはひとつの行にひとつの列があるとは限りません。引用符のある項目に改行があることがあります。しかしながら、ほとんどのCSVはひとつの列にひとつの行です。CSVは入手可能な中では、可能な限り単純な構造化データ形式です。
- (*3)具体的な例として、マージ機能は、レコードの様々なセット、すなわち行に影響する2つの変更セットの調和においておそらくとてもうまく動作するでしょう。しかしながら、各々カラムを移動させる2セットの変更はうまくマージしないでしょう。
- (*4)より大きなデータについては、私たちは、Git(そして例えばGitHub)をs3のような単純なファイル記憶装置と交換することを提案します。s3が基礎的なcopy-on-writeのバージョン管理をサポートできることに注意してください。しかしながら、copy-on-writeであるため、それは相対的にかなり非効率です。
原文(2013/7/2 Open Knowledge Foundation Blog 記事より):
Original post Git (and Github) for Data / Rufus Pollock, licensed under CC BY 3.0.