Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Apache Drill で日本語を扱ってみよう + オープンデータ解析

1,704 views

Published on

Apache Drill で日本語を扱ってみよう + オープンデータ解析

Published in: Data & Analytics
  • Be the first to comment

Apache Drill で日本語を扱ってみよう + オープンデータ解析

  1. 1. © 2014 MapR Technologies 1© 2014 MapR Technologies Apache Drill で日本語を扱ってみよう + オープンデータ解析
  2. 2. © 2014 MapR Technologies 2 自己紹介 • 梅川 真人(ウメカワマサト) • MapR Technologies セールスエンジニア • 2015/5 に MapR に それまでは SIer にいたが MapR に惚れてしまい転職 • 趣味は YOGA、でも最近さぼりぎみ。。
  3. 3. © 2014 MapR Technologies 3© 2014 MapR Technologies Apache Drill で日本語を扱う時の注意点
  4. 4. © 2014 MapR Technologies 4 ゆるい日本語のデータ No タイトル 県名 1 くまモン 熊本 2 ふなっしー 船橋 3 せんとくん 奈良 ファイル名: yuru.csv
  5. 5. © 2014 MapR Technologies 5 ロケール(1) $ echo $LANG en_US.UTF-8 $ sqlline 0: jdbc:drill:zk=drill01:5181> select * from dfs.`/tmp/yuru.csv`; +---------------------+ | columns | +---------------------+ | ["1","????","??"] | | ["2","?????","??"] | | ["3","?????","??"] | +---------------------+ 3 rows selected (0.159 seconds) ロケールがen_US.UTF-8だと文字化けする
  6. 6. © 2014 MapR Technologies 6 ロケール(2) $ echo $LANG ja_JP.UTF-8 $ sqlline 0: jdbc:drill:zk=drill01:5181> select * from dfs.`/tmp/yuru.csv`; +---------------------+ | columns | +---------------------+| ["1","くまモン","熊本"] | | ["2","ふなっしー","船橋"] | | ["3","せんとくん","奈良"] | +---------------------+ 3 rows selected (0.159 seconds) Ja_JP.UTF-8にすれば文字化けせずに表示される
  7. 7. © 2014 MapR Technologies 7 文字列リテラルのエラー 0: jdbc:drill:> select . . . . . . . > columns[0] 番号, . . . . . . . > columns[1] 名前, . . . . . . . > columns[2] 住所 . . . . . . . > from dfs.`/tmp/yuru.csv` . . . . . . . > where columns[2] = '熊本’; Error: SYSTEM ERROR: CalciteException: Failed to encode ‘熊本’ in character set ‘ISO- 8859-1’ [Error Id: 98a5ba50-81a6-4718-a274-a2b784d7d7aa on drill02:31010] (state=,code=0) デフォルトだとエラーが・・
  8. 8. © 2014 MapR Technologies 8 文字列リテラルの対策 Apache Calcite - SQL Language http://calcite.incubator.apache.org/docs/reference.html DrillはSQLパーサの部分にApache Calciteを利用しているため、 Calciteのドキュメントを見てみましょう。 データ型 説明 範囲と例 CHAR(n) CHARACTER(n) Fixed-width character string Hello’, ‘’ (空文字), _latin1’Hello’, n’Hello’, _UTF16’Hello’, ‘Hello’ ‘there’ (複数パートに分割されたリテラル)
  9. 9. © 2014 MapR Technologies 9 文字列リテラルの対策済みクエリ 0: jdbc:drill:zk=local> SELECT . . . . . . . . . . . > COLUMNS[0] 番号, . . . . . . . . . . . > COLUMNS[1] 名前, . . . . . . . . . . . > COLUMNS[2] 住所 . . . . . . . . . . . > FROM dfs.`/tmp/test.csv` . . . . . . . . . . . > WHERE COLUMNS[2] = _UTF16'熊本'; +-----+--------+-----+ | 番号 | 名前 | 住所 | +-----+--------+-----+ | 1 | くまモン | 熊本 | +-----+--------+-----+ 1 rows selected (1.543 seconds) _UTF16 をつけてみるとうまくいきました
  10. 10. © 2014 MapR Technologies 10 drill1.0 での 恒久的な対応 /** * The string property "saffron.default.charset" is the name of the default * character set. The default is "ISO-8859-1". It is used in * {@link org.apache.calcite.sql.validate.SqlValidator}. */ public final StringProperty defaultCharset = new StringProperty(this, "saffron.default.charset", "ISO-8859-1"); 毎回_UTF16をつけるのは面倒なのでデフォルトにできないか調べてみる
  11. 11. © 2014 MapR Technologies 11 drill1.0 での恒久的な対応 $ vi apache-drill-1.-.0/conf/drill-env.sh export DRILL_SHELL_JAVA_OPTS="-Dsaffron.default.charset=UTF-16LE" 「saffron.default.charset」というプロパティにUTF-16を指定すればよさそうな感じで す。 これを記載するのは、設定ファイルdrill-env.shの中の環境変数 DRILL_SHELL_JAVA_OPTSの設定をします。 文字セット名は、いろいろ試したところ、「UTF-16LE」である必要があるようです。
  12. 12. © 2014 MapR Technologies 12 まとめ  ロケールは “ja_JP.UTF-8” に  文字列リテラルに _UTF16 をつける  Apache-drill-1.0.0/conf/drill-env.sh なら export DRILL_SHELL_JAVA_OPTS=“-Dsaffron.default.charset=UTF-16LE” を追記
  13. 13. © 2014 MapR Technologies 13© 2014 MapR Technologies オープンデータから23区の人口増減率を 調べよう
  14. 14. © 2014 MapR Technologies 14 データ取得元 政府統計の総合窓口(e-Stat) URL: http://www.e-stat.go.jp/api/ 使用したデータ: 国勢調査(平成22年度) 政府統計コード: 00200521 APIを使うにはサイト上から利用登録をしてアプリケーションIDを取得
  15. 15. © 2014 MapR Technologies 15 データを取得してみる $ curl -o stats_list.json "http://api.e- stat.go.jp/rest/2.0/app/json/getStatsList?appId=XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXX&surveyYears=2010&statsCode=00 200521" 国勢調査の政府統計コード 自分のアプリケーションID
  16. 16. © 2014 MapR Technologies 16 取得したデータを見てみる 0: jdbc:drill:zk=local> SELECT * FROM dfs.`/tmp/stats_list.json` t; +--------------------+ | GET_STATS_LIST | +--------------------+ {“RESULT”:{“STATUS”:0,“ERROR_MSG”:“正常に終了しまし た。”,“DATE”:“2015-05- 21T19:01:17.540+09:00”},“PARAMETER”:{“LANG”:“J”,“SURVEY_YEA RS”:2010,“STATS_CODE”:“0 | +----------------+ 1 row selected (0.955 seconds)
  17. 17. © 2014 MapR Technologies 17 JSONデータを見てみる { "GET_STATS_LIST":{ "RESULT":{ ← 取得結果のステータス情報 “STATUS”:0, “ERROR_MSG”:"u6B63u5E38u306Bu7D42u4E86u3057u307Eu3057u305Fu3002", "DATE":"2015-05-21T19:01:17.540+09:00" }, "PARAMETER":{ ← 取得時に指定したパラメータ "LANG":"J", "SURVEY_YEARS":2010, "STATS_CODE":"00200521", "DATA_FORMAT":"J" }, “DATALIST_INF”:{ ← 統計表のリストデータ本体 "NUMBER":356, “RESULT” INF”:{ "FROM_NUMBER":1, "TO_NUMBER":356 }, “TABLE_INF”:[ ← 統計表のリスト {"@id":"0003033021",...}, {"@id":"0003033022",...}, ... ] } } }
  18. 18. © 2014 MapR Technologies 18 KVGEN()とFLATTEN()関数 KVGEN()関数: <キー>:<値>, <キー>:<値>, ... の並びを [ {"key":<キー>,"value":<値>}, {"key":<キー>,"value":<値>}, ... ] に分解 Apache Drill 特有の関数。FLATTEN()関数は配列をレコードに展開。ここで 「GET_STATS_LIST」に対してKVGEN()関数とFLATTEN()関数を使うことで、一つ下の 階層のキーと値の組がレコードとして展開されます。
  19. 19. © 2014 MapR Technologies 19 KVGEN()とFLATTEN()関数で分解する 0: jdbc:drill:zk=local> SELECT FLATTEN(KVGEN(t.GET_STATS_LIST)) FROM dfs.`/tmp/stats_list.json` t; +----------------------------------------------------------------------------------------------------------------------+ | EXPR$0 | +----------------------------------------------------------------------------------------------------------------------+ | {“key”:“RESULT”,“value”:{“STATUS”:0,“ERROR_MSG”:“正常に終了しました。”,“DATE”:“2015-05- 21T19:01:17.540+09:00”,“RESULT_INF”:{},“TA | |{”key“:”PARAMETER“,”value“:{”LANG“:”J“,”SURVEY_YEARS“:2010,”STATS_CODE“:”00200521“,”D ATA_FORMAT“:”J“,”RESULT_INF“:{},”TABLE_INF“:[]}} | |{”key“:”DATALIST_INF“,”value“:{”NUMBER“:356,”RESULT_INF“:{”FROM_NUMBER“:1,”TO_NUMBE R“:356},”TABLE_INF“:[{”@id“:”0003033021“,”STAT_ | +---------------------------------------------------------------------------------------------------------------------+ 3 rows selected (0.452 seconds)
  20. 20. © 2014 MapR Technologies 20 統計表IDを取得する 0: jdbc:drill:> SELECT. . . . . . . > d.table_inf.`@id`, . . . . . . . > d.table_inf.TITLE.$ . . . . . . . > FROM ( . . . . . . . > SELECT FLATTEN(t.GET_STATS_LIST.DATALIST_INF.TABLE_INF) table_inf . . . . . . . > FROM dfs.`/tmp/stats_list.json` t . . . . . . . > ) d . . . . . . . > WHERE d.TABLE_INF.TITLE.$ LIKE '%人口増減%'; +-------------+-----------------------------------------------------------------+ | EXPR$0 | EXPR$1 | +-------------+-----------------------------------------------------------------+ | 0003038586 | 人口,人口増減,面積及び人口密度 全国,市部・郡部,都道府県,市部・郡部,支庁,郡 計,市区町村・旧市町村,全域・人口集中地区 | +-------------+-----------------------------------------------------------------+ 1 row selected (1.465 seconds)
  21. 21. © 2014 MapR Technologies 21 地域名ビューの作成 0: jdbc:drill:zk=local> CREATE VIEW dfs.tmp.`area_info` AS SELECT . . . . . . . . . . . > t.data.`@code` code, . . . . . . . . . . . > t.data.`@name` name, . . . . . . . . . . . > t.data.`@level` level, . . . . . . . . . . . > t.data.`@parentCode` parent . . . . . . . . . . . > FROM ( . . . . . . . . . . . > SELECT . . . . . . . . . . . > FLATTEN(f.GET_STATS_DATA.STATISTICAL_DATA.CLASS_INF.CLASS_OBJ[2]. CLASS) data . . . . . . . . . . . > FROM . . . . . . . . . . . > dfs.`/tmp/stats_data_modified.json` f . . . . . . . . . . . > ) t; データをSQLで扱いやすくするために、ビューとして定義してみましょう。 ここでは地域名を取り出すためのビューと、統計データを取り出すためのビューを定義します。
  22. 22. © 2014 MapR Technologies 22 統計データビューの作成 0: jdbc:drill:zk=local> CREATE VIEW dfs.tmp.`stats_data` AS SELECT . . . . . . . . . . . > t.data.`@tab` tab, . . . . . . . . . . . > t.data.`@cat01` did, . . . . . . . . . . . > t.data.`@area` area, . . . . . . . . . . . > t.data.$ val . . . . . . . . . . . > FROM ( . . . . . . . . . . . > SELECT . . . . . . . . . . . > FLATTEN(f.GET_STATS_DATA.STATISTICAL_DATA.DATA_INF.`VALUE`) data . . . . . . . . . . . > FROM . . . . . . . . . . . > dfs.`/tmp/stats_data_modified.json` f . . . . . . . . . . . > ) t;
  23. 23. © 2014 MapR Technologies 23 地域名ビュー 0: jdbc:drill:zk=local> SELECT * FROM dfs.tmp.`area_info` LIMIT 10; +--------+--------+--------+---------+ | code | name | level | parent | +--------+--------+--------+---------+ | 00000 | 全国 | 1 | null | | 00001 | 全国市部 | 1 | null | | 00002 | 全国郡部 | 1 | null | | 01000 | 北海道 | 2 | 00000 | | 01001 | 北海道市部 | 3 | 01000 | | 01002 | 北海道郡部 | 3 | 01000 | | 01100 | 札幌市 | 3 | 01000 | | 01101 | 中央区 | 4 | 01100 | | 01102 | 北区 | 4 | 01100 | | 01103 | 東区 | 4 | 01100 | +--------+--------+--------+---------+ 10 rows selected (11.902 seconds)
  24. 24. © 2014 MapR Technologies 24 統計データビュー 0: jdbc:drill:zk=local> SELECT * FROM dfs.tmp.`stats_data` LIMIT 10; +------+--------+--------+------------+ | tab | did | area | val | +------+--------+--------+------------+ | 020 | 00710 | 00000 | 128057352 | | 020 | 00710 | 00001 | 116156631 | | 020 | 00710 | 00002 | 11900721 | | 020 | 00710 | 01000 | 5506419 | | 020 | 00710 | 01001 | 4449360 | | 020 | 00710 | 01002 | 1057059 | | 020 | 00710 | 01100 | 1913545 | | 020 | 00710 | 01101 | 220189 | | 020 | 00710 | 01102 | 278781 | | 020 | 00710 | 01103 | 255873 | +------+--------+--------+------------+ 10 rows selected (87.308 seconds)
  25. 25. © 2014 MapR Technologies 25 23区の人口増減率 0: jdbc:drill:> SELECT a.name 地域, b.val 人口, c.val 増減率 . . . . . . . > FROM (SELECT * FROM dfs.tmp.`area_info` t . . . . . . . > WHERE t.parent = '13100') a . . . . . . . > JOIN dfs.tmp.`stats_data` b . . . . . . . > ON a.code = b.area AND b.tab = '020' AND . . . . . . . > b.did = '00710’ . . . . . . . > JOIN dfs.tmp.`stats_data` c . . . . . . . > ON a.code = c.area AND c.tab = '102' AND . . . . . . . > c.did = '00710' AND c.val <> '-’ . . . . . . . > ORDER BY CAST(c.val AS DOUBLE) DESC; +-------+---------+-----------+ | 地域 | 人口 | 増減率 | +-------+---------+-----------+ | 中央区 | 122762 | 24.7594 | | 豊島区 | 284678 | 13.60536 | | 千代田区 | 47115 | 12.77467 | | 港区 | 205131 | 10.36796 | | 江東区 | 460819 | 9.49851 | | 足立区 | 683426 | 9.38194 | . | 板橋区 | 535824 | 2.43575 | | 目黒区 | 268330 | 1.61552 | | 北区 | 335544 | 1.55321 | | 中野区 | 314750 | 1.32732 | | 渋谷区 | 204492 | 0.56951 | +-------+---------+-----------+ 23 rows selected (547.958 seconds)
  26. 26. © 2014 MapR Technologies 26 Q&A @mapr_japan maprjapan sales-jp@mapr.com お問い合わせはこちらまで MapR maprtech mapr-technologies オープンデータの詳細な手順は@nagixのブログもご覧下さい http://nagix.hatenablog.com

×