blog

データサイエンス(データ科学)のための7つのコマンドラインツール

データサイエンスとは、データを取得し、整理し、探索し、モデリングし、翻訳することです。データサイエンティストとして、特にデータの取得、整理、探索に関しては、コマンドラインを使うことに多くの時間を費やし...

Sep 4, 2013 · 13 min. read
シェア

1. jq - JSON 用 sed

JSONは、特にAPIが普及した今、ますます人気が高まっています。私はJSONを扱っていて、grepやsedを使って醜いコードを書いていたことを覚えています。jqのおかげで、やっと醜いコードを書くのをやめることができます。

2008年の大統領選挙ですべての候補者に関心があるとします。New York Timesは選挙資金に関するAPIを持っています:

curl -s '"http://..com/svc/elections/us/v3/finances/2800"/president/.json?api-key=super-secret' > .json 

sはサイレントモードを示します。そしてjqの最も単純なフォーマットであるjq '.' を使います。と書くと、醜いコードが表示されます:

{"status":"OK","base_uri":"http://..com/svc/elections/us/v3/finances/2800"/","cycle":2008,"":" (c) 2013 The New York Times Company. All Rights Reserved.","results":[{"candidate_name":"Obama, Barack","name":"Barack Obama","party":"D", 

素敵なフォーマットに変換します:

< nyt.json jq '.' | head { "results": [ { "candidate_id": "P80003338", "date_coverage_from": "2007-01-01", "date_coverage_to": "2008-11-24", "candidate_name": "Obama, Barack", "name": "Barack Obama", "party": "D", 

また、jqはJSONデータを選択し、フィルタリングすることができます:

< nyt.json jq -c '.results[] | {name, party, cash: .cash_on_hand} | select(.cash | tonumber > 1000000)' 
{"cash":"29911984.0","party":"D","name":"Barack Obama"} 
{"cash":"32812513.75","party":"R","name":"John McCain"} 
{"cash":"4428347.5","party":"D","name":"John Edwards"} 

Unixの哲学は、一つのことをうまくこなすプログラムを書くことですが、jqは強力です!json2csvの紹介です。

2. json2csv - JSONをCSVに変換します。

JSONはデータ交換には適していますが、多くのコマンドラインツールには適していません。しかしご心配なく。json2csvを使えば、JSONをCSVに簡単に変換できます。 million.jsonにデータがあるとします。

< million.json json2csv -k name,party,cash 

その後、データを変換することができます:

Barack Obama,D,29911984.0 
John McCain,R,32812513.75 
John Edwards,D,4428347.5 

CSVフォーマットでは、cut -dやawk -Fのような伝統的なツールを使うことができます。CSVは表形式で保存されるため、csvkitの作者はcsvkitを開発しました。

3. csvkit - CSV の変換と使用スイート

csvkitは単なるプログラムではなく、一連のプログラムです。これらのツールのほとんどは、CSVデータにテーブルヘッダがあることを「想定」しているので、ここにその1つを示します。

echo name,party,cash | cat - million.csv > million-header.csv 

csvsort を使って候補者を選挙資金でソートし、表示することができます:

< million-header.csv csvsort -rc cash | csvlook 
|---------------+-------+--------------| 
|  name         | party | cash         | 
|---------------+-------+--------------| 
|  John McCain  | R     | 32812513.75  | 
|  Barack Obama | D     | 29911984.0   | 
|  John Edwards | D     | 4428347.5    | 
|---------------+-------+--------------| 

MySQLのようですね。データベースといえば、以下のコマンドでCSVをsqliteデータベースに書き込むことができます:

csvsql --db sqlite:///myfirst.db --insert million-header.csv 
sqlite3 myfirst.db 
sqlite> .schema million-header 
CREATE TABLE "million-header" ( 
    name VARCHAR(12) NOT NULL, 
    party VARCHAR(1) NOT NULL, 
    cash FLOAT NOT NULL 
); 

CSVでも書式設定が可能なため、挿入後のデータは正しくなります。さらに、このスイートにはin2csv、csvgrep、csvjoinなど、他にも興味深いツールがあります。csvjsonを使えば、データをcsvからjsonに変換することもできます。

scrape - XPath と CSS セレクタによる HTML 情報抽出ツール

scrapeはPythonスクリプトで、特定のHTML要素を選択できるようにlxmlとcssselectパッケージを含んでいます。ウィキペディアには、全ての国の国土面積に対する国境言語の比率をリストアップしたページがあるので、その比率情報を抽出する方法を紹介します。

curl -s 'http://..org/wiki/List_of_countries_and_territories_by_border/area_ratio' | scrape -b -e '.wikitable > tr:not(:first-child)' | head 
<!DOCTYPE html> 
<html> 
<body> 
<tr> 
<td>1</td> 
<td>Vatican City</td> 
<td>3.2</td> 
<td>0.44</td> 
<td>7.2727273</td> 
</tr> 

bコマンドは、xml2jsonがHTMLをJSONに変換するのに必要な場合があるので、タグを含めるようにscrapeに指示します。

xml2json - XMLからJSONへの変換

その名の通り、XML(HTMLもXMLの一種)をJSON出力形式に変換するツールです。従って、xml2jsonはscrapeとjqの良い橋渡しとなります。

curl -s 'http://..org/wiki/List_of_countries_and_territories_by_border/area_ratio' | scrape -be '.wikitable > tr:not(:first-child)' | xml2json | jq -c '...tr[] | {country: .td[1][], border: .td[2][], surface: .td[3][], ratio: .td[4][]}' | head 
{"ratio":"7.2727273","surface":"0.44","border":"3.2","country":"Vatican City"} 
{"ratio":"2.2000000","surface":"2","border":"4.4","country":"Monaco"} 
{"ratio":"0.6393443","surface":"61","border":"39","country":"San Marino"} 
{"ratio":"0.4750000","surface":"160","border":"76","country":"Liechtenstein"} 
{"ratio":"0.3000000","surface":"34","border":"10.2","country":"Sint Maarten (Netherlands)"} 
{"ratio":"0.2570513","surface":"468","border":"120.3","country":"Andorra"} 
{"ratio":"0.2000000","surface":"6","border":"1.2","country":"Gibraltar (United Kingdom)"} 
{"ratio":"0.1888889","surface":"54","border":"10.2","country":"Saint Martin (France)"} 
{"ratio":"0.1388244","surface":"2586","border":"359","country":"Luxembourg"} 
{"ratio":"0.0749196","surface":"6220","border":"466","country":"Palestinian territories"} 

もちろん、JSONデータは後からjson2csvに入力することもできます。

6. サンプル - デバッグに使用します。

大量のデータを扱う場合、デバッグ・パイプラインは非常に厄介です。そんな時にsampleが役に立ちます。このツールには3つの使い方があります:

  1. データの一部を行ごとに表示します。
  2. 出力に遅延を加えるには、データが多少遅れて入ってきたり、出力が速すぎてはっきり見えないときに、これを使うととても便利です。
  3. プログラムの実行時間を制限します。

次の例は、これら3つの機能を示しています:

1
seq 10000 | sample -r 20% -d 1000 -s 5 | jq '{number: .}'

これは、各行が20%の確率でjqに与えられ、行間には1000ミリ秒の遅延があり、サンプルは5秒後に停止することを意味します。これらのオプションはオプションです。不必要な計算を避けるために、できるだけ早い段階でサンプリングして、デバッグして遊んだ後に削除できるようにしましょう。

7.リオ - 治療にRを加える

この記事はRなしでは完結しません。処理にR/Rscriptを追加しても、入力と出力が標準化されていないのであまり理解できません。

Rioは次のように動作します:まず、標準入力に与えられたCSVを一時ファイルに移動し、それをdfに読み込むようにRに指示します。その後、-eのコマンドが実行されます。***あるコマンドの出力が標準出力にリダイレクトされます。これら3つの使い方を1行のコマンドで示し、それぞれの部分を5桁の数字で要約して示します:

curl -s 'https://..com/pydata/pandas/master/pandas/tests/data/.csv' > .csv 
< iris.csv Rio -e 'summary(df)' 
  SepalLength      SepalWidth     PetalLength      PetalWidth   
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300  
 Mean   :5.843   Mean   :3.054   Mean   :3.759   Mean   :1.199  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
     Name          
 Length:150        
 Class :character  
 Mode  :character 

sオプションを付けると、sqldfパッケージが導入され、CSV形式で出力されるようになり、後で別のツールでデータを処理できるようになります。

< iris.csv Rio -se 'sqldf("select * from df where df.SepalLength > 7.5")' | csvlook 
|--------------+------------+-------------+------------+-----------------| 
|  SepalLength | SepalWidth | PetalLength | PetalWidth | Name            | 
|--------------+------------+-------------+------------+-----------------| 
|  7.6         | 3          | 6.6         | 2.1        | Iris-virginica  | 
|  7.7         | 3.8        | 6.7         | 2.2        | Iris-virginica  | 
|  7.7         | 2.6        | 6.9         | 2.3        | Iris-virginica  | 
|  7.7         | 2.8        | 6.7         | 2          | Iris-virginica  | 
|  7.9         | 3.8        | 6.4         | 2          | Iris-virginica  | 
|  7.7         | 3          | 6.1         | 2.3        | Iris-virginica  | 
|--------------+------------+-------------+------------+-----------------| 

gオプションを使うと、ggplot2が参照され、g got with dfというggplotオブジェクトが宣言されます。最終出力がggplotオブジェクトの場合、PNGが標準出力に書き出されます。

< iris.csv Rio -ge 'g+geom_point(aes(x=SepalLength,y=SepalWidth,colour=Name))' > iris.png 

このツールは、コマンドラインから R の力をフルに活用できるようにするために作りました。もちろん多くの欠点がありますが、少なくとも gnuplot を学ぶ必要はもうありません。

コマンドラインツール

twitterやハッカーニュースを通じて他の友人から勧められたツールを紹介します。

はんけつをくだす

私が日常的に使っている7つのコマンドラインツールを紹介しました。それぞれのツールにはそれぞれの強みがありますが、私はよく従来のツールと組み合わせて使っています。小さなツールを組み合わせて使うことで、大きなパイプラインを形成することができるのです。

皆さんはこのリストをどう思いますか?また、普段どんなツールを使うのが好きですか?皆さんも何か面白いツールを作ったら、遠慮なくデータサイエンス・ツールボックスdata science toolboxに追加してください。

ツールを作れないと思っても心配しないでください。今度変わったコマンドラインパイプラインを書いたら、それを#付きのファイルに入れることを忘れないでください!を付けてファイルに書き出し、引数を追加して実行ファイルに変更すれば、ツールの完成です!

ご興味のある方は、お気軽にください。

Read next

Linuxでhostapdを使ってワイヤレスAPを作成する。

現在市販されている多くのワイヤレスカードにはシミュレートAP機能があり、ワイヤレスクライアントとしてワイヤレスネットワークに接続するだけでなく、他のワイヤレスクライアントが接続できるようにシミュレートAPに切り替えることができます。この記事では Linux で hostapd を使ってワイヤレス AP を作成する方法と、それに関連する問題をまとめています。

Sep 3, 2013 · 5 min read