オープンデータやビッグデータの可視化するための手法の勉強メモ
windows(7 pro)環境でelasticserch(2.2.0)+kibana(4.4.1)を使ってデータを可視化します。
CSV⇒jsonへの変換にはpowershell(4.0)を使います。
#要約
- 必要なソフトをインストール
- 可視化するCSVファイルをjson形式に変換
- json形式のファイルをelasticsearchのbulk APIで読み込む
- kibanaでグラフを作成
- kibanaでダッシュボードを作成
必要なソフトをインストール
Javaのインストール
入ってなければJAVAをインストール
合わせて環境変数のJAVA_HOMEを設定
コントロール パネル⇒すべてのコントロール パネル項目⇒システム⇒システムの詳細設定⇒詳細設定⇒環境変数
JAVA_HOMEに「C:\Program Files (x86)\Java\jre1.8.x_xx」(実際にインストールしたバージョン、場所を設定)
elasticsearchとそのプラグインのkibanaのインストール
ここからダウンロードして、適当なフォルダに解凍
bin/elasticsearch.bat を実行
ここからダウンロードして、適当なフォルダに解凍
bin\kibana を実行
適当にバッチファイルにまとめておいてもいいかも。
start C:\elasticsearch-2.2.0\bin\elasticsearch
C:\kibana-4.4.1-windows\bin\kibana
powershellのインストール
こちらの記事を参照してインストール
また、powershellを管理者権限で起動して、以下のコマンドを実行
Set-ExecutionPolicy RemoteSigned
curlのインストール
ここから「Win64 - Generic」をダウンロードして適当な場所に解凍
環境変数のPATHにダウンロードした場所を設定
可視化するCSVファイルをjson形式に変換
ファイルダウンロード
PM2.5やNOX(窒素酸化物)などの大気汚染物質の濃度を可視化してみます。
神戸市大気汚染常時監視結果の確定値ダウンロードからいくつかファイルをダウンロードします。
この記事では、2012年~2015年の灘大気測定局の「1時間値測定データ」をダウンロードします。
- 2012_0103_hour.csv
- 2013_0103_hour.csv
- 2014_0103_hour.csv
- 2015_0103_hour.csv
powershellで読み込むために、文字コードをUTF-8に変換しておいたほうが便利です。
json形式に変換
目標は、elasticsearchのバルクAPIで取り込めるjsonデータを作ることです。elasticsearchのコマンド行とデータ行を交互に書くようです。
{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "1" } }
{ "field1" : "value1" }
{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "2" } }
{ "field1" : "value2" }
ファイル全体が一つのオブジェクトではなく、一行一行がオブジェクトのようです。
powershellのimport-csvとConvertTo-Jsonというコマンドレットを使用します。
import-csvでCSVを読み込んでオブジェクトに変換し、そのオブジェクトをconvertTo-Jsonでjson形式に変換します。
#神戸市大気汚染常時監視結果の一時間測定データのCSVを読み込んで
#elasticsearchのbulk APIで読み込める形式にする関数
#エラー処理はまったくしていないので注意
function read_air($importFilePath , $resultFilePath, $term , $id){
$esCmd = @{ index = @{ _index = "air"; _type = "" ; _id = "" } } #elasticserchコマンド用のオブジェクトを格納する変数
$count = 0
$result = "" #出力を格納する変数
$delim = ""
$csv = Import-Csv $importFilePath | Where-Object { $_.'測定項目名称' -like $term}
$csv | ForEach-Object {
$esCmd.index._type = $_.'測定項目名称';
$esCmd.index._id = $id + $count++;
$result = $result + $delim + ($esCmd | ConvertTo-Json -Compress);
$delim = "`n"
#elasticsearchで使いやすいように年月日時を一つの項目にまとめる
$_ | Add-Member TimeStamp ($_."年" + $_."月" + $_."日" + "-" + $_."時");
#括弧やスラッシュがあるとelasticsearchで読み込んだ時の挙動がおかしいのでアンダーバーに置換
$_.'測定項目名称' = $_.'測定項目名称' -replace '[\(\)\/]','_'
$result = $result + $delim +($_ | ConvertTo-Json -Compress);
}
$result | out-file -filepath $resultFilePath -encoding UTF8 -Append;
}
#全部変換すると結構な時間がかかるので注意
#read_air "C:\work\data\2012_0103_hour.csv" "C:\work\data\test.json" "*ppm*" "2012"
#read_air "C:\work\data\2013_0103_hour.csv" "C:\work\data\test.json" "*ppm*" "2013"
#read_air "C:\work\data\2014_0103_hour.csv" "C:\work\data\test.json" "*ppm*" "2014"
#read_air "C:\work\data\2015_0103_hour.csv" "C:\work\data\test.json" "*ppm*" "2015"
#read_air "C:\work\data\2012_0103_hour.csv" "C:\work\data\test.json" "pm2.5*" "20121"
#read_air "C:\work\data\2013_0103_hour.csv" "C:\work\data\test.json" "pm2.5*" "20131"
#read_air "C:\work\data\2014_0103_hour.csv" "C:\work\data\test.json" "pm2.5*" "20141"
read_air "C:\work\data\2015_0103_hour.csv" "C:\work\data\test1.json" "pm2.5*" "20151"
出力結果はこんな感じになります。
{"index":{"_index":"air","_type":"NO(ppm)","_id":"20120"}}
{"年":"2012","月":"04","日":"01","時":"01","市町村名":"灘区","測定局名称":"灘大気測定局","測定項目名称":"NO_ppm_","測定値":"0.002","管理主体":"神戸市","局種別":"一般局","TimeStamp":"20120401-01"}
{"index":{"_index":"air","_type":"NO(ppm)","_id":"20121"}}
{"年":"2012","月":"04","日":"01","時":"02","市町村名":"灘区","測定局名称":"灘大気測定局","測定項目名称":"NO_ppm_","測定値":"0.001","管理主体":"神戸市","局種別":"一般局","TimeStamp":"20120401-02"}
{"index":{"_index":"air","_type":"NO(ppm)","_id":"20122"}}
{"年":"2012","月":"04","日":"01","時":"03","市町村名":"灘区","測定局名称":"灘大気測定局","測定項目名称":"NO_ppm_","測定値":"0.001","管理主体":"神戸市","局種別":"一般局","TimeStamp":"20120401-03"}
{"index":{"_index":"air","_type":"NO(ppm)","_id":"20123"}}
{"年":"2012","月":"04","日":"01","時":"04","市町村名":"灘区","測定局名称":"灘大気測定局","測定項目名称":"NO_ppm_","測定値":"0.001","管理主体":"神戸市","局種別":"一般局","TimeStamp":"20120401-04"}
{"index":{"_index":"air","_type":"NO(ppm)","_id":"20124"}}
・・・
json形式のファイルをelasticsearchに読み込む
この記事を参照しながら作業しました。
データの各項目の型を設定するマッピングが必要なようなので、適当にmap.jsonを作成。
自動生成されるマッピングのtimestampの値だけstringから以下に修正
"TimeStamp" : {
"type":"date",
"format":"YYYYMMdd-HH"
}
あとはマッピング用のファイルとデータファイルを取り込めば準備完了
REM curl -XDELETE "localhost:9200/*"
curl -XPUT localhost:9200/air --data-binary @map.json
curl -XPUT localhost:9200/_bulk --data-binary @test.json > nul
kibanaでグラフを作成
http://localhost:5601/へアクセス
index nameに「air」、time-field nameに「timestamp」を設定。
右上のlast 15 minutes を last 2 year なり、読み込んだデータ範囲に変更します。
上のvisualizeメニューをクリックして、グラフの種類を選択。
左側のメニューに適当に入力するとグラフの完成。
エリアチャート
nox(窒素酸化物系)とox(光化学スモッグ系)の大気汚染物質の濃度推移を上下で比較。それぞれ、種類ごとに色分けして積み上げしたグラフです。
折れ線グラフ
円グラフ
光化学スモッグ系の大気汚染物質の濃度を月別集計(内側)、さらに月ごとのoxiとoxの割合を表示(外側)
月ごとにも、oxiとoxの間にもほとんど差がなくてグラフとしてはあまり意味がないですね。。。