蛇ノ目の記

技術のことも。そうでないことも。

PyCon APAC 2018 Day 2

前回の更新からだいぶ時間が経ってしまった。

この一ヶ月の間にPyQブログとgihyo,jpでPyCon APAC 2018記事が公開された。 あとstapy#36BPLL#22でPyCon APAC 2018行ってきたよ報告LTをした。stapyは帰国からの直行だったので抜群の鮮度だった思い出。

blog.pyq.jp

gihyo.jp

PyQブログ書いてるし、gihyo.jpに寄稿してるので実はブログ書いていたのでは。

では、PyCon APAC 2018 カンファレンス2日目に聴いたトークのまとめ。

Opening Keynote

Talk

Detecting offensive messages using Deep Learning: A micro-service based approach

by Alizishaan Khatri, Machine Learning Engineer at Pivotus Ventures

資料: alizishaan-khatri-detecting-offensive-messages-using-deep-learning.pdf - Google ドライブ

What are you doing to control abusive content on your platform? Can your current solution tell the difference between "fking awesome" and "fking loser"? Can it detect racist and sexist content? In this talk, you will learn how to build a deep learning based solution and deploy it as a micro-service.

訳:

自分(自社)のプラットフォーム上での攻撃的な言動に対してどのように対応しているでしょうか。今の解決策はf**king awesomeとf**king looserの違いを認識できますか?差別的な表現や性的な表現の検知は?このトークでは、深層学習ベースの解決策とマイクロサービスとしてデプロイする方法をお伝えします。

Pumping up Python modules using Rust

by Vigneshwer Dhinakaran, Mozilla TechSpeaker

資料: vigneshwer-dhinakaran-pumping-python-modules-using-rust.pdf - Google ドライブ

Learn to build high performance and memory safe Python extensions using Rust. Discover this and more tips to boost up your Python application.

訳:

パフォーマンスでメモリセーフなPython拡張をRustで作る方法や、Pythonアプリケーションの性能を上げるtipsをお伝えします。

How to understand user behaviour using Multiple Linear Regression?

by Sarthak Deshwal, Associate Software Engineer at Expedia Group

資料: sarthak-deshwal-how-to-understand-user-behavior-using-multiple-linear-regression.pdf - Google ドライブ

Studying the user behaviour on app/website is one of the most hot topics among product companies. Multiple linear regression exactly helps you to find out the most important factors about your user and deliver the most important features to them. We will discuss the process, and the pros and cons of it.

訳:

アプリケーションやWebサイト上のユーザの振る舞いを知ることは今、企業の間で最も熱いトピックになっています。重回帰分析はユーザについての要素を見つけたり、ユーザーに最も重要な機能を提供するのにとても役立ちます。この発表では重回帰分析を使うプロセスと、その長所と短所をお伝えします。

Elements of Programming Interviews in Python

by Tsung-Hsien Lee, Staff Software Engineer at Toyota Research Institute

資料: tsung-hsien-lee-elements-of-programming-interviews-in-python.pdf - Google ドライブ

I will educate the audience on how to solve algorithmic problems commonly asked at interviews, emphasizing the aspects of Python that are the most useful. I will also describe how hiring decisions are made behind-the-scenes, based on my professional experiences at Facebook, Google, and Uber.

訳:

コーディング面接でよく出題されるアルゴリズム問題に役立つhow toをPythonを用いてお伝えします。また、FacebookGoogle, Uberで採用に関わった経験をベースに、採用するエンジニアの決定について話します。

Learn Guitar Via Python Programming

by Rishabh Shah, Associate Tech. Architect at Systango Technologies

資料: 無し

Ever wanted to play your favourite song on a guitar quickly even when you don't know how to play a guitar? Our Python based MIDI to guitar tabs Transcriber can help you do that. You just need to find your song in MIDI format (with .mid as file extension), and let our Python Transcriber do its magic!

訳:

好きな曲をギターで簡単に弾けるようになりたいけれど、その方法がわからないということがありませんか?MIDIからタブ譜へ変換する私達のPythonライブラリは、その悩みに役立ちます。必要なのは、曲のMIDIデータを変換ライブラリに通すことだけです。

ギター下手マンとしてはだいぶ気になっていた発表だったけど、実際に聴くと今ひとつ面白さが伝わってこなかったのが残念。

そう思っている時期が私にもありました(´・ω・`)

Closing Keynote

Run your ICO using Python

by Abhishek Pandey, Senior Developer at Tilde Trading

仮想通貨についての基調講演。

PyCon APAC 2018 Day 1

【2018.7.2 追記】トークの発表資料への追加

シンガポールで開催されているPyCon APAC 2018にやってきた。

海外のカンファレンスは初めて、シンガポールも初上陸。

PyCon APAC ツアー

初海外カンファレンスなうえに海外経験が少ないのでPyCon JPが企画するAPACツアーに参加しての旅だった。Pythonエンジニア仲間と行くと心強いし楽しい。

PyCon JP Blog: PyCon APAC 2018 in シンガポール のツアー参加者募集

シンガポール上陸当日

上陸した5月31日の天気は悪かった。昼を食べ終わる頃には雨になり、あまり観光できずに宿に戻ることとなった。

夜は現地で働いているonodaさん、APACのスポンサーのHDEのメンバーとHolland Villageにあるイタリア料理店で夕飯。その後は近くにあった屋台街めいたところで二次会となった。いっつもビール飲んでるな。

一日に2度もタワービールと対面するとは。

Day 1

PyCon APAC 2018の会場はNUS(National University of Singapore)。

f:id:Nao_Y:20180601165901j:plain

School of Computingの2階に上がると受付。

f:id:Nao_Y:20180601170019j:plain

ここでTシャツをゲット。乾きやすい生地になっているのが東南アジア感ある。

スポンサーブースではいつもお世話になっているPyCharmのJetBrainsのブースでPyCharmステッカーとハンドスピナーをもらった。

次の日に貼った。

カンファレンス後はAPACツアー勢、onodaさんと共に宿近くのショッピングモールに入っているフードコートで夕飯。鶏肉が入ったアジアンなスープを食べた。

その後はビールをキメた。飲んでばっかりでは。

Opening Keynote

Day1の基調講演はKatharine Jarmul。ドイツでデータサイエンスのコンサルをやっているkjamistanの創業者。

機械学習システムにおけるプライバシーというテーマの講演。

f:id:Nao_Y:20180601170931j:plain

Google Assistantが学習した音声情報はどうやって収集されたのかという疑問をきっかけに、データを収集、訓練データとして使うときにエンジニアが注意しなければならないことに繋がった。

  • 倫理的なデータセット

    • ユーザからデータを収集するという契約は明示的にする( Zen of PythonのExplicit is better than Implicit.になぞらえて)
  • 収集するデータについてユーザとの合意を得る

  • 匿名化(Anonymazation)や仮名化(Pseudonymization)を施す

なんとか聴き取れた範囲はこのくらい。英語力の無さ……。

最後にオーディエンス全員で「I am a Data Guardian」と声を合わせたりした。

f:id:Nao_Y:20180601172735j:plain

GDPRが話題になっているタイミングに合った話だったと思う(小並感

Talk

聞いたトークのサマリーを訳してみる。

全体のスケジュールはConference Schedule | PyCon APAC 2018

Introduce Syntax and History of Python from 2.4 to 3.6

by Manabu Terada, Founder and CEO at CMS Communications Inc.

資料: manabu-terada-introduce-syntax-and-history-of-python-from-2.4-to-3.6.pdf - Google ドライブ

CMSコミュケーションズの寺田さん。一般社団法人PyCon JPの理事でもある。

今回のPyCon APACツアーを企画していただいた。多謝。

The speaker will introduce the new syntax and functions between Python 2.4 and Python 3.6 in this talk. I will also compare the old style to the new style. You will learn the best practices for Python coding and how to perform refactoring your old Python code. You can look at the evolution of Python.

訳:

Python2.4から3.6の間に登場した新しい文法と関数の紹介と旧スタイルと新スタイルの比較。Pythonの進化の道筋をたどることで、古いPythonのコードをリファクタリングする際のベストプラクティスが学べるだろう。

Teaching Computers ABCs: A Quick Intro to Natural Language Processing

by Lory Nunez, Data Scientist/Data Engineer at J.P. Morgan

資料: loryfel-nunez-teaching-computers-abc.pdf - Google ドライブ

Natural Language Processing (NLP) is a component of Artificial Intelligence. Knowledge of NLP can make unstructured text data add tremendous value to any application. We will go over basic NLP tasks, techniques and tools. We will end with an NLP app built from open source libraries.

訳:

自然言語処理はAIを構成する要素である。自然言語処理によって、構造化されていないテキストデータがさまざまアプリケーションに大きな価値を与えられるようになる。ここでは、基本的な自然言語処理のテクニック、ツール、ユースケース、そしてオープンソースライブラリを使って自然言語処理アプリケーションを作る方法について発表する。

サンプルアプリ(Wikipediaの文章を用いて人名同士の類似度を測るアプリ・ツイートをクラス分けして災害時のトリアージを行うアプリ)が紹介されたが、アクセスできなくなっている(´・ω・`)

Dockerizing Django

by Ernst Haagsman, Product Marketing Manager for PyCharm at JetBrains

資料: Release pycon_apac_2018 · ErnstHaagsman/ecs-talk · GitHub

Docker helps make sure that the Django application you develop is exactly the same as the Django application you eventually deploy. In this talk, you will learn how to containerize a Django application, and use docker-compose to connect your Django application to your entire stack.

訳:

Dockerは、開発したDjangoアプリケーションと最終的にデプロイしたアプリケーションが同一であることを確認する際に役立つ。Djangoアプリケーションのコンテナ化と、アプリケーションをdocker-composeで管理しているサービスに接続する方法を紹介する。

このリポジトリやブログの記事(Using Docker Compose on Windows in PyCharm | PyCharm Blog )が元になっているようだ。

github.com

Build a Data-Driven Web App That Everyone Can Use

by Galuh Sahid, Data Engineer at Midtrans

資料: galuh-sahidbuilding-a-data-driven-web-app-that-everyone-can-use.pdf - Google ドライブ

You're a data scientist with a machine learning model that you want to show everyone. Do you give your users your Python scripts and tell them to run "python mycoolmodel.py"? Is there a better alternative? How about a web app? The speaker will show you how Flask can be the best fit pun intended for this case.

訳:

データサイエンティストのあなたは自分が作った機械学習モデルをみんなに使ってもらいたいと考えている。そんなときに「mycoolmodel.pyと名付けたファイルをpythonコマンドで実行してください」とみんなに伝えていないだろうか。他にもっと良い方法があるのではないか?Webアプリにするのはどうだろう。この発表ではFlaskを用いて機械学習モデルをWebアプリ化するベストな方法を紹介する。

レベル感として今回のトークの中で最も面白いと感じられた。Flaskは少しチュートリアルをやればWebアプリが書けるし、機械学習モデルもKaggleのタイタニックのやつを解説している記事に沿えば作れそう。復習したいので動画公開が待ち遠しい。

Closing Keynote

The Python QuantsのCEO、Dr. Yves Hilpisch。

いわゆるFinPyの分野の話なのだけど、そっち方面の知識がゼロなのでついていくことができなかった……。


Day 1の話はこれにて終わり。Day 2に続く。

BeautifulSoup4でコメントタグの中身を取得する方法に腹落ちするまでの話

同人音楽即売会M3の出展サークルリストから、サークル名やキーワードを抜こうとしている。何に使うかは未定だけど。

サークルリスト 2018年春 | M3 - 音系・メディアミックス同人即売会 を見てわかるように スペース, サークル名, 概要 となっている。サークルに関する情報はこれだけではなくて、ソースを見てみるとコメントとしてサークル名(カナ)やジャンルコード、キーワードが記述されている。キーワードも取りたくなってしまったのでひたすらググることになったという話。なお、BeautifulSoupに関しての説明はだいぶ省く。

<!--  アナベル    A01 女性ヴォーカル   ジョセイヴォーカル オリジナル オリジナル ポップス    ポップス    -->

コメントアウトされた情報はキーワードの数や並びが統一されていないのだけどそれは置いておく。これが実データのつらみか。

コメントタグの中身を取る方法

さて、beautifulsoup comment と検索するとトップにstackoverflowがヒットする。

stackoverflow.com

曰く、find_allメソッドのキーワード引数stringに以下のような無名関数を渡してやれば無名関数を渡してやればコメントが取れる。

lambda text: isinstance(text, Comment)

これで無事コメントタグの中身が取得できてめでたしめでたし、となるけどイマイチ腹落ちしなかったので find_allメソッドを調べた。

BeautifulSoupと無名関数については以下を参考にしたりした。

www.tomordonez.com

find_allメソッド

find_allメソッドは引数で指定した条件に一致するタグの要素を返す。

ここではpタグを取得してみよう。

from bs4 import BeautifulSoup as bs

markup = """
<body>
<h1>First Heading</h1>
<p>This is paragraph.</p>
<p>spam ham eggs</p>
<!-- This is comment -->
<!-- foo bar baz -->
</body>
"""

soup = bs(markup, 'html.parser')
paras = soup.find_all('p')
for p in paras:
    print(p)

実行結果は以下。

<p>This is paragraph.</p>
<p>spam ham eggs</p>

変数pTagオブジェクトで、get_text()メソッドでタグに囲まれた文字列を取得できる。

This is paragraph.
spam ham eggs

となる。

コメントタグの中身を取る方法: 再訪

先の例に当てはめて、コメントタグの中身を取得してみる。

from bs4 import BeautifulSoup as bs
from bs4 import Comment

markup = """
<body>
<h1>First Heading</h1>
<p>This is paragraph.</p>
<p>spam ham eggs</p>
<!-- This is comment -->
<!-- foo bar baz -->
</body>
"""

soup = bs(markup, 'html.parser')
comments = soup.find_all(string=lambda text: isinstance(text, Comment))
for c in comments:
    print(c)
 This is comment 
 foo bar baz 

CommentはBeatifulSoup4でコメントを表すクラス。

https://github.com/waylan/beautifulsoup/blob/master/bs4/element.py#L746L749

つまりCommentオブジェクトであるということが条件になっている。

次にstring引数について調べてみる。

https://www.crummy.com/software/BeautifulSoup/bs4/doc/#the-string-argument

With string you can search for strings instead of tags. As with name and the keyword arguments, you can pass in a string, a regular expression, a list, a function, or the value True.

正規表現やリスト、関数を渡すことができるとある。無名関数を渡しているのはそのためだった。

変数textがどのような値なのか気になって仕方ないので、普通の関数にして確認してみる。

from bs4 import BeautifulSoup as bs
from bs4 import Comment

def is_comment(text):
    print(text, type(text)
    return isinstance(text, Comment)

markup = """
<body>
<h1>First Heading</h1>
<p>This is paragraph.</p>
<p>spam ham eggs</p>
<!-- This is comment -->
<!-- foo bar baz -->
</body>
"""

soup = bs(markup, 'html.parser')
comments = soup.find_all(string=is_comment)
 <class 'bs4.element.NavigableString'>
 <class 'bs4.element.NavigableString'>
First Heading <class 'bs4.element.NavigableString'>
 <class 'bs4.element.NavigableString'>
This is paragraph. <class 'bs4.element.NavigableString'>
 <class 'bs4.element.NavigableString'>
spam ham eggs <class 'bs4.element.NavigableString'>
 <class 'bs4.element.NavigableString'>
This is comment <class 'bs4.element.Comment'>
 <class 'bs4.element.NavigableString'>
foo bar baz <class 'bs4.element.Comment'>
 <class 'bs4.element.NavigableString'>
 <class 'bs4.element.NavigableString'>

見づらいうえに改行も認識されてる(´・ω・`)

h1タグやpタグはNavigableString オブジェクト、コメントタグはCommentオブジェクトということがわかった。

ついでにパースしたHTMLの各行に対して処理が行われていることも実感できた。

まとめると、

  • find_allメソッドのstring引数には関数を渡すことができる

  • パースしたHTMLの各行が、タグの場合はNavigableString、コメントであればCommentオブジェクトになる

  • string関数に各行がCommentオブジェクトであることを判定する関数を渡すことで、コメントだけを取得できる

ひとまず腹落ちしたので心置きなくHTMLからコメントが取得できるようになった。

数や順番が統一されていないサークル情報をどう使うかを考えないとならないけど、それは別の話になる。

リズと青い鳥 - 感想

連休中にリズと青い鳥を3回ほど観た。

liz-bluebird.com

タイトルこそ違うが本作は「響け!ユーフォニアム」シリーズのスピンオフ。登場人物の学年が一つ上がった後の物語。主人公はみぞれと希美。

監督は山田尚子。キャラクターデザインは西屋太志、音楽は牛尾憲輔という「聲の形」を作り上げた3人。

あらすじ

Filmarks - リズと青い鳥より引用

あの子は青い鳥。広い空を自由に飛びまわることがあの子にとっての幸せ。だけど、私はひとり置いていかれるのが怖くて、あの子を鳥籠に閉じ込め、何も気づいていないふりをした。 北宇治高等学校吹奏楽部でオーボエを担当する鎧塚みぞれと、フルートを担当する傘木希美。高校三年生、二人の最後のコンクール。その自由曲に選ばれた「リズと青い鳥」にはオーボエとフルートが掛け合うソロがあった。「なんだかこの曲、わたしたちみたい」 屈託もなくそう言ってソロを嬉しそうに吹く希美と、希美と過ごす日々に幸せを感じつつも終わりが近づくことを恐れるみぞれ。「親友」のはずの二人。しかし、オーボエとフルートのソロは上手くかみ合わず、距離を感じさせるものだった。

感想

みぞれと希美の関係性

これまでの「ユーフォ」はコンクールでの演奏シーン、府大会での演奏をめぐるオーディションやあすか先輩が吹奏楽を続ける理由など画にも物語にも動きがあり、まさしく吹奏楽部を描いた物語だった。これに対して本作は、みぞれと希美の関係性を落ち着いたトーンで描く「静」の物語になっている。

みぞれにとっての希美について印象に残っているのが、パンフレットでの対談で山田尚子監督が語っている「みぞれにとって希美の一言はいつも最終回」ということ。階段に腰掛けて、校門を眺めながら希美を待つという冒頭のシーンでのみぞれから「いつも最終回」という気持ちが伝わってくる。

パンフレット p.6

山田: そうですね。冒頭で見せた二人の関係性も、天真爛漫な希美と、希美が大好きで希美しか見えていないみぞれにとって、希美の一言がどれだけいつも「最終回」なのかが伝わればいいと思います。みぞれは「次がない」と思って毎日生きているので……。

1年生の頃に突然、希美が吹奏楽部から去ったようにいつまた離れていくかわからないという不安をいつもみぞれは抱えている。みぞれの希美に対する想いは、眩しい朝の青空を背景に青い鳥の羽を空にかざす希美を見上げるという冒頭のシーンから伝わってくる。開始数分でこれだけの情報量をほとんど台詞も無く描く山田尚子監督の力量たるや……。

一方、希美はみぞれをいつも後ろにいて自分を見てくれている存在と捉えているように思う。それは二人が歩く画から伝わってくる。いつも、みぞれは自分だけを見ていてくれていると思っているからこそ、プールに一緒に連れていきたい子がいるとみぞれから告げられたとき、みぞれと梨々花のオーボエが聴こえてきたときに表情を陰らせる。プールの話をするときに、希美が表情を陰らせたと同時に誰かが希美とみぞれの前を横切って一瞬、希美の表情がわからなくなり次の瞬間には何もなかったような顔をする、という演出は本当にはっとした。エモい。

みぞれと希美は好き合っているけど、互いに方向性が異なっているから羨むところも違ってくる。みぞれは、希美が後輩たちを仲良く喋っているのを寂しそうに見ている。それに対して希美は「同じ音大を目指す」といえば同じくらい上手いように見られると思う。終盤のあるシーンで二人の好きの方向性がはっきりと描かれる。この後、みぞれは希美が好かれたいと思っていることに気付くことができるのか。ここのシーンはクライマックスだけあって3度観て、3度とも涙が出そうになった。

パンフレット p.13

山田: みぞれは多分、 全ては理解してないかもしれないけれど、希美が言って欲しかった言葉が何だったのかを少しずつ理解していくのではないかと思います。

本作は「青い鳥が自分が青い鳥であることに、リズは自分がリズであることに気付く」物語と考えている。けれどみぞれと希美は、リズと青い鳥のように離れ離れになるわけではない。気付けたことで、きっとこれからの二人は少しずつ互いの在り方を見つめていけるのだと思う。初めて、希美が歩きながらみぞれを振り返ったラストシーンのように。

キャラクターデザイン

「ユーフォ」の池田晶子から「聲の形」でキャラクターデザインを担当した西屋太志に変更になった。「ユーフォ」と比べると線が細くて頭身が少し高いデザインで、いわゆる「萌え」の感じが薄まって繊細になっている。これによって「静」の雰囲気がより高まっている。池田晶子デザインだったらこの落ち着いた空気感はまた違ったものになったと思う。 余談ではあるけども、久美子がだいぶ可愛いと思ってる。これまでの主人公とは思えないくらい出番ないけど。

まとめ

Twitterではみぞれと希美の恋のような関係性(パンフレット pp.6~7で監督が愛よりも恋と語っている)を描いた百合的な話として褒めるツイートをしていた記憶があるけど、演出、脚本、キャラクターデザイン、音楽など全てが繊細でアニメーション作品としての完成度も本当に高い。まだ劇場で観れると思うので、全力でオススメしたい。本気で劇場で何度も観たい。無限に観たい。

ゴールデンウィークふりかえり

アニメと映画

4/28, 5/1, 5/5と3度に渡って観た。これだけ観てるので後日、感想の記事を書いておきたい。とりあえずざっくりと言うと百合作品としてだけでなくアニメーションとしても完成された作品。これまでの「響け!ユーフォニアム」から一転して「静」の作品になっている。山田尚子監督は天才。まだまだ公開しているので、音を味わう意味でもぜひ劇場で。

あとは最近Netflixを契約したのでひたすら観ていた。

レストレポはアフガニスタンで激戦地となった渓谷で任務に就く米軍の部隊に密着したドキュメンタリーで、タリバンとの戦闘や現地の住民の交流、といった兵士の日常を追っている。レストレポとは戦死した兵士の名前かつ、その後に建設した前線基地の名前。随所で兵士レストレポについてのインタビューが入る。より兵士の内面を描いた2編目があるが、そちらは未視聴。

DOPEは麻薬捜査官と売人の両方に密着して取材したドキュメンタリーなのだけど、売人側は撮影のためにマスクをしているので「この状態で車乗ってたら怪しまれるのでは」と思わざるを得なかった。とはいえそういう些末なことを気にしなければ十分に面白い。

SACから数えて10年以上ファンを続けている攻殻。ARISEと新劇場版ももちろん面白いけど、やっぱりSACに戻ってくる。3話まで観たのでこれからまた最後まで観そうな気がする。

読書

ゼロから作るDeep LearningとEffective Pythonを持って帰省していたが、ずっとネトフリに齧りついていたのでEffective Pythonを数ページ読み進めるだけに留まってしまった。pyhack合宿みたいな環境じゃないと集中して読めないな…。あとは百合展で買ったアフターアワーズを読んだ。

百合展

3月開催の筈が色々あって延期になった百合展2018に行ってきた。青山は百合おじさんが歩くと浮く。

撮影可なので様々な百合漫画の原画と「やがて君になる」のアニメ化ポスターなんかを写真に収めた。

M3

4/29に行われた同人音楽即売会M3で10枚ほどCDを購入。茶太さんの曲が入った新譜が少ないこともあって量は控えめ。事前に決めたサークル以外では、ポスターにひかれて視聴してみた白衣とMonocleのPhantom Protocol 1が結構よかった。ボカロによるヒップホップといった雰囲気。

免許更新

都庁2階の更新センターで行った。前回の更新以来、運転していないのでゴールドに。金というか金メッキだ。運転するときっとメッキが剥がれる。

乗っ取られてたOriginアカウントを復帰させた話

OriginはEA社のゲーム管理・販売プラットフォーム。アカウント乗っ取りからの復帰方法のメモ。

TL;DR

  • 秘密の質問を変更するときはサポートセンター(0800-170-2170)に電話する
  • 二重認証を設定しておこうな

過去にBattleField3やらBattleField1をプレイしていたが1年半以上放置していた。

午後、何気なくメールチェックをしたらOriginに登録したメールアドレスが変更されたというメールが来ていた。身に覚えがなかったのでこちらをクリックしてメールアドレスを元に戻し、パスワードを変更してください。の文言に従ってパスワードを変更。パスワード変更後、アカウント詳細を見るとIDが変更されていた上に言語がロシア語になっていた。

Chromeの翻訳アドオンを使ってしめやかに日本語訳して、IDを直そうとするも「秘密の質問」まで変えられていた。もちろんロシア語。

origin 秘密の質問 変更 でググったところサポートセンターに電話することで変更できるらしい。ヒットしたブログにある通り0570-081800に電話するも繋がらず。あらためて検索すると、公式Twitterにサポートセンターの電話番号は0800-170-2170に変更されたとあった。EA社におかれましてはサポートセンターの電話番号のSEOを向上させていただきたいお気持ち。

サポートセンターに掛けると口頭でのメールアドレス確認の後、送信されてきたコードを伝えて秘密の質問変更手続きとなった。大体4~5分程度で全て完了。最後に二重認証を掛けておくことを勧められたので設定しておいた。

再設定された秘密の質問を使ってIDを元に戻して全て解決。

OverpyでOpenStreetMapのデータを取得して位置情報を可視化する話

4月末に近づいた頃にようやく今月初めての記事。あまりに書かなすぎた。

だいぶ前になるけど、OpenStreetMap(OSM)からガソリンスタンドの位置情報を取得してプロットしたデータアートめいた画像を見た。なにこれかっこいい。

地図ではなく全くの白紙にプロットしてるにも関わらず、欧州・北アフリカの海岸線や主要道路が見て取れる。

あまりにかっこいい画だったので日本でも似たようなことをやってみた。緯度経度をそのまま座標としてプロットしただけで日本列島とわかる姿になる。沖縄だけでなく東京都の島嶼部なんかも確認できる。

gas stations in Japan

今回のリポジトリはこちら。

github.com

OSMからデータを取得するライブラリ

openstreetmap pythonなどと検索するとosmapiがヒットする。しかしこちらはOSMにデータを書き込む用途に向いたライブラリ。

データの取得だけが目的なのであればoverpyを使うのがよい。

A Python Wrapper to access the Overpass API.

とあるようにOverpass APIPython用ラッパーだ。

Overpass API is 何

公式Wiki - Overpass APIには以下のようにある。

Overpass API(別名 OSM3S)とは読み出し専用のAPIであり、OSM地図データの中から個別に選択された部分を取り出します。Webを介したデータベースとして動作します。利用者はAPIに対してクエリを送り、クエリに対応したデータ セットを受け取ります。

クエリはOverpass QLと呼ばれ、OSMからデータを読み出すためのSQLのようなものといえる。

公式Wiki - Overpass API/言語ガイド

OSMのデータには、駅や店舗、施設などを表すノード、道路や河川、鉄道路線を表すウェイ、ノードとウェイを組み合わせたリレーションがあるようだ。

Overpass QLを書いてみる

東京都にあるガソリンスタンドを抽出するOverpass QLを書いてみる。

area["name"~"東京都"];
node(area)["amenity"="fuel"];
out;

WebベースのOSMデータマイニングツールOverpass turboでの(実行結果)http://overpass-turbo.eu/s/yb9にアクセスしてクエリを実行すると取得結果をOSM上で確認できる。

データ取得範囲は area["name"~"東京都|神奈川県"];のように|で区切ることで複数指定できる。新宿区といったより細かい範囲も指定可能。

node(area)["amenity"="fuel"]; でノードの種類を指定している。OSMではキー=値という形のタグでオブジェクトに情報を与えている。OSMのタグ情報はtaginfoが詳しい。

鉄道の駅であれば "railway"="station"、コンビニは"shop"="convenience"と指定する。ただ、コンビニの場合はコンビニエンスストア以外の小さな商店なども含まれているようなので、主要なコンビニリストを作ってノードの他のタグnameをフィルタリングしたりする必要がありそう。

overpyを使ってみる

overpyでデータを取得してシリアライズするスクリプトを書いた。

pickleではシリアライズできなかったのでpickleの拡張モジュールであるdillを使った。

日本全国を範囲指定するので、都道府県を並べたテキストファイルの中身を結合してクエリに突っ込んでいる。

overpass_plot/script at master · NaoY-2501/overpass_plot · GitHub

from datetime import datetime
import os

import dill
import overpy


def get_prefs():
    prefs = ''
    with open('pref.txt', mode='r') as f:
        for row in f.readlines():
            prefs += '{}|'.format(row.rstrip()) 
    return prefs[:-1]


def input_node_info():
    key = input('Input node key:')
    tag = input('Input tag of key:')
    return key, tag


def save_result(result, key, tag):
    now = datetime.now()
    date = '{}{}{}'.format(now.year, now.month, now.day)
    filename = 'data/{}-{}_{}.pkl'.format(date, key, tag)
    
    print('Save as {}'.format(filename))
    
    if not os.path.exists(filename):
        with open(filename, 'wb') as f:
            dill.dump(result, f)
        print('Save complete.')

        
def fetch_result(key, tag):
    api = overpy.Overpass()
    prefs = get_prefs()
    query = (
        'area["name"~"{prefs}"];\n'
        'node(area)["{key}"="{tag}"];\n'
        'out;'
    ).format(prefs=prefs, key=key, tag=tag)
    print('Fetch query...')
    result = api.query(query)
    print('Fetch complete')
    save_result(result, key, tag)


def main():
    key, tag = input_node_info()
    fetch_result(key, tag)


if __name__ == "__main__":
    main()

bokehでプロットする

可視化にはズームして、分布を細かく見たいという理由でbokehを使った。実際にやってみると重くてズームしづらいことに気づいた。bokehがGitHub上ではプレビューできないので保存した画像を貼る。

駅の分布

stations in Japan

駅をプロットするので自然と路線そのものが浮かび上がっている。

コンビニの分布

convenience stores in Japan

流石にコンビニ全国各地にありすぎだろ……。小さい商店なんかも含まれてることが想像できるので、これは見直す必要がある。

というわけでOSMラッパーライブラリOverpyの紹介と実験結果の話だった。