たけのこブログ

凡人が頑張って背伸びするブログ

色んな正規表現が知りたい方々へ(備忘録)

概要

いろんなテキスト前処理をやってると正規表現が必須になる場面に遭遇しますが、複雑なのになってくると面倒臭いし、かといって定番な正規表現を一々書けるかと言われると複雑になってくると怪しい...。

そんな自分と似た境遇のための備忘録として、今回は正規表現の例が沢山見れるサイトや入門書に最適なサイトを紹介してみました。

いきなり結論

このサイト一択

regexlib.com

英語のサイトだけど、youtubeだろうかtwitterだろうが日付だろうが、大体のものは検索すれば出てくる。正規表現の勉強にもなるし、ちょっと複雑な正規表現を作るのが苦手な人でも簡単にテキストの前処理が使えるようになります。

しかもこのサイト、正規表現の内容によって評価もされていて、評価値が高い正規表現を探して自学自習にも使える優れものです。

色んな正規表現を試したい人、仕事で正規表現に悩んだ人は参考にしてみてください。

正規表現を何から学んだら良いか分からない人に

僕も自然言語など

qiita.com

jupyterからSSH接続してAWSのRDBにアクセスする方法

概要

僕が業務でデータ分析をするときは主にbigqueryをjupyterからアクセスしてクエリを叩いて分析することが多いですが、企業によっては、

  • Sequel ProでDBにSSH接続してからSQL投げてcsvでエクスポート

  • エクスポートしたcsvを読み込んでPoC検証

という手順を踏むところもあります。別にこれで良いのですが、例えば

「新しい日にちのデータで分析してくれない?」

と言われると、毎回Sequel proで接続して数回クエリを叩いて複数のcsvを取得するような解析をしないといけないので、個人的に少しイライラします。僕は元々面倒臭がりなので、毎回Sequel proにアクセスしてデータを取ってくるのが怠い。どうせ検証なんだから全てjupyter上でささっと素早く分析してタスクを片付けたい!けど向こうの細かい要望は手間を掛けずに出せるようにしておきたい!

そこで、もうjupyter側からAWSのRDSにアクセスすることにしました。

接続方針と実際のソースコード

sshtunnelで踏み台サーバをSSHで経由してRDSにアクセスします。RDSへ接続するための仕組みはこちらの記事の解説図を見ると分かりやすいと思います。

pythonのmysqlclientでSSH越しにAWSのRDSにアクセス – 或る阿呆の記

そして、上記の方法でアクセスしようとしたのですが...ちょっとうまくいかなかった汗 PC側でそのポートが開いてないからなのかなんなのか...当初は検討が付かず処理が凍結して先に進めませんでした(原因については察しがついたので最後に書いてます)。

そこで色んな方法を調べていたところ、以下のサイトを参考にして解決できました。

PythonでSSH経由し外部のMySQLデータベースを操作してみる - Qiita

以下が実際に動かして上手くいった関数になります。重要なのはserver.local_bind_portの部分でlocal_bind_addressをsshtunnelで設定せずにsshtunnelで通過した際のlocal_bind_portを代入すると上手くRDSにアクセスすることができました。

from sshtunnel import SSHTunnelForwarder
import pymysql as db
import pandas as pd
import datetime

# ssh
sshOptions = {
    "bastion": {
        "host": '踏み台のIPアドレス',
        "ssh_username": 'ユーザー名',
        "ssh_private_key": '鍵のファイルパス',
        "ssh_password": '鍵のキーワード'
    }
}
ssh = sshOptions["bastion"]
# database
dbOptions = {
    "mysql": {
        "localhost": 'hogehoge.rds.amazonaws.com(rdsのエンドポイント)',
        "user": 'ユーザー名',
        "password": 'パスワード',
        "database": 'DBの名前',
        "port": 3306
    }
}
dbConfig = dbOptions["mysql"]

# なんかのクエリ
sql_query='''
SELECT * FROM tables
'''

def query(q):
    with SSHTunnelForwarder(
    (ssh["host"], 22),
    ssh_username = ssh["ssh_username"],
    ssh_password = ssh["ssh_password"],
    ssh_private_key = ssh["ssh_private_key"],
    remote_bind_address=(dbConfig["localhost"], dbConfig["port"])
    ) as server:
        conn = db.connect(host = '127.0.0.1',
                          port = server.local_bind_port,
                          user = dbConfig["user"],
                          passwd = dbConfig["password"],
                          db = dbConfig["database"],
                          charset = 'utf8',
                          cursorclass = db.cursors.DictCursor)
        df = pd.read_sql_query(q, conn)
        conn.close()
        return df

query(sql_query)

そもそもserver.local_bind_portで上手くいったのはなぜか

そして原因ですが、おそらくjupyterが関係してると思います。jupyter自体がlocalhostにポートを開いて接続してるので、sshtunnelでlocal_bind_addressを設定しても一致せずに動かないのが原因じゃないかなと推測しています。なので、sshtunnelを経由する前にlocal_bind_addressを設定せず、with ~ as serverとSSHで経由した際にserver.local_bind_portを設定すると上手くいくんだと思います(実際、sshtunnelでlocal_bind_addressを設定して上手くいっていた記事は複数確認できたので...)。

まとめ

今回はjupyterでローカルからAWSのRDSに接続する方法を備忘録として紹介しました。これでSequel Proの呪縛から解放されました。請け負ってる委託や研究も、PoCはほとんどjupyterで片付けられる状態にできたのでちょっと嬉しい。

とある博士後期課程の大学院生が開業して半年経ったそうです

一年修行して開業してから半年が経ちました

修行期間で取り組んだことについては以下の記事に書かれているので参考にしてください。

yukr.hatenablog.com

四月の頭に開業届を出して半年以上が経過しました。 長期のインターンから始まり、スキルを身につけて業務委託案件を得るために求人に応募してた今年の2月と比べると、開業してからは金銭面の問題はほぼ解消しました(精神的な余裕ができたお陰で、余計な不安事を考えず集中できたので有り難かった)。

開業し始めた頃と比べると、研究してるにも関わらず担当案件数が三倍以上になりました。簡単に言えば、常時三倍界王拳です

f:id:YuKR:20201018212847p:plain
こんな感じ

スカウトだったり、インターン先から改めて雇用形態を見直して頂いたり、本当に感謝しております。これに加えて今まで取り組んできた研究に関するジャーナルの修正をしつつ新規研究もやっているので忙殺されてますが、周りの支えもあってなんとか踏ん張れています(それでも休みが欲しい...)。仕事は週5~6、残りの隙間時間で研究というハードワークですが自分の能力を最大限活かせているので不満はありません。今は主に機械学習エンジニアみたいな位置付けで、主に衛星画像からメディア関連のデータ、衣食住に関連したデータなどを扱って解析(PoC検証やA/Bテスト)やサービスへの実装をしています。どれも研究テーマとは全く別物で、オンライン講習やteratail、オープンソース等を含め独学で身につけた部分がほとんどですが、元々いろんなデータを弄るのが純粋に好きだったのであまり抵抗はないです。

今回は開業してから半年経ったという事で、一人の博士後期課程の大学院生が開業して良かったことや苦労した経験をお話したいと思います(後で気が付いたら追加するかもです)。

博士課程の間に開業して良かったこと

圧倒的にスキルを貯めやすい

これはインターンをやっていても感じることですが、何よりスキルの貯まる速度が早い。 開業してからやった大まかな実績や内容ですが、明らかにスキルの取得速度と実績速度が倍くらいになっています。単純に給料が上がった分振られるタスクも増えるので、これはある意味収穫でした。お金も稼げてスキルもそれに応じて貯まるwinwinの状態にできました。

始めてから成熟するまでの期間もあると思うので、やれることが増えるのは当然じゃないかと思われるかもしれません。しかし、インターンだと「別に失敗しても構わないから、これやってみる?」みたいなケースが多いのに対して、仕事だと「これを実現してくれないと困る=クビ」みたいな感じで案件が振ってくるので、「なんとなくやっていた」から「絶対にリリースしても大丈夫なレベルに昇華させる必要がある」に意識が変わります。仕事をしてる方からすると当たり前のことかもしれませんが、これは自分にとって結構大きな意識の変化でした。

経費でアレコレ落とせる

学振も民間の給付も通らずお金に苦労するとパソコンすら変えられないというケースになります(なりました)が、開業すればこれらが経費で落とせます。自分も仕事と研究の書類を整理するために経費でipad proを購入しましたが、これも確定申告の際に経費で落とせるのでお得です。この経験も個人的に重要だと思っていて、20代の間に自分で経費などのやりくりをするのは、きっと起業した際や複数の会社を経営するようになった際にも活かせると思います

色んな人と仕事ができる

これも開業主ならではですが、研究室という狭い環境を飛び越えて色んな方々と仕事ができるのは非常に面白いですし、研究とはまた別のベクトルで凄い人たちと仕事ができるのは色んな意味で刺激になります。特に業務委託で雇われる方は30歳以上の方が多いので、自分にはないスキルや知見を持ってる人が沢山います。実際その人たちの意見を元にして新しいアイデアや物の見方ができるようになるので、素晴らしい経験になると思います。

博士課程の間に開業して大変なこと

なるべく研究と仕事の締め切りが被ることがないようにリスク管理を徹底する必要がある

開業主は自分のネームがそのままブランドに直結するので、納期は絶対に厳守してます。しかし、研究も学会発表や原稿、ラボのミーティングの資料作成などの締め切りはあります。一番きついのがこれらがoverlapした時で、土日徹夜になって廃人になります笑(笑い事じゃない)

したがって、事前にスケジュールを組んでリスクヘッジをしっかりすることが、両立させる上で非常に重要になります。幸い開業主だと正社員で社会人博士をしてる方と比べると会社との締め切りの交渉はしやすいはずなので、そこの障壁は少しマシな気がしています(余程大事なタスクでなければ、数日休みなら事前に交渉すれば対応してくれることが多いです。あくまで自分のケースですが...)。

やっぱり両立がきつい

個人的に開業主で週3くらいの案件を選べばあまり苦労せずに研究もできると思ってるのですが、それでも学振の方や民間から給付金を貰ってる方と比べると両立が大変です。私みたいに実験がある程度終わって数理モデル寄りの研究に移行したり解析寄りの人は両立しやすいかもしれないですが、生物実験をやってる方などはメンテで毎日実験室に通わないといけないので厳しいかもしれません。過去記事にも書いてあるようにそのためのリモート案件なのですが、週2程度の案件やインターンを求人サイトから探すのは大変なので、自分のやり方が全ての分野の院生に対する特効薬になるとは限りません。というか思ってません。自分のようなやり方を選択肢の一つとして参考にしれもらえればと思い、このような記事を投稿しています(といってもその選択肢を全く考えないよりは良いと思いますが...汗)。しかし、両立の厳しさが自分で調節しやすいのが開業主の利点としてあるので、そこは救いかなと思います。

出会いは諦めた方が良い

これは自分がエンジニアやってるのでしょうがないですが、出会いはあまり期待できません(インターンなら女性も結構いるけどね)。 自分の働いてるところは最低でも年齢30歳以上の男性エンジニアの人たちで構成されてるので、女性と仕事を一緒にすることは経験上ほとんどないです(メディア関連は編集者の方もいるので除きます)。これはまぁ確率というか何というか運です、はい。

素直に合コンや婚活サイトの利用をオススメします(一応研究しながら開業するほどのポテンシャルがあるという見方をされるようなので、有利といえば有利らしいです)。

まとめ

開業して半年経ったので、どんなメリットやデメリットがあったのか書いてみました。確定申告の時期に入るともう少し内容が増えるかもしれないので、また追記していきたいと思います(大変にならないことを祈ってます)。 また、今年中にジャーナルの投稿もできそうなので、その時のTipsなども今年中に掲載できたらと思ってます。解析記事などはそれらが落ち着き始めたら追々書きたいと思いますので、よろしくお願い致します。

失敗しないために、AutoMLを使うときに試している三つのこと

簡単な深層学習タスクはAutoMLで実装できるけど...

(まだ研究してる博士後期課程の院生だけど、)業務委託で複数の企業の案件に携わっていると、いろんな要望があります。例えば、 ・HTTPレスポンスで良いからSageMakerやcloud functionsとかでUI意識せずに気軽に機械学習ウィジェット作ってよ ・モバイルに組み込みたいから、それに対応した形で出力してよ(TFLite形式とかで作ってよ) ・いろんな前処理も導入させたいから、関数じゃなくてEc2やGCE、GAEとかで定期実行するように実装してよ

特に上記二つに関しては、簡単な深層学習タスクであればAutoMLで簡単に作成可能ですし、自分も面倒臭くてAutoMLで解決できそうなものはAutoMLで素早くデプロイまでやってしまうことが多いです(機械学習の「UberEats」みたいな感覚で使ってます)。AutoMLは機械学習の知識がない方でも簡単に学習器を作れると唄ってる通り、実際に知識がなくてもデータさえあれば簡単に機械学習モデルが作れます(機械学習エンジニアの仕事を奪うとか言ってる人もたくさん居るみたいだし)。しかし、例えば誤ったデータを入力として入れると「過学習」と呼ばれる、端的に言えば「入力データに過剰に適合しすぎて、実際のサービスに移植した時に汎用性に欠ける挙動をしてしまう」ことが(知識があっても)度々あります。

そこで、今回は自分自身の経験を踏まえた上でAutoMLを実際に使用する時にチェックしてることを大きく分けて三つ紹介したいと思います。

知識があろうがなかろうが、PoC検証は必要

これを言ったら元も子もないじゃないかと言われても仕方がないのですが、必要だと思います。

AutoMLは確かに便利です。HTTP形式でもモバイル形式でもデプロイできますし、並列にいろんなモデルを学習させる環境を作ってジョブ投げる必要もないし、コスパよくやって評価指標まで出してくれる。特徴量が見えないのが難点ですが、それでも実用に早く移したいプロジェクトにおいてはそこまで重要視しないので、かなり有用なツールだと思います。

しかし、AutoMLを実行すると当然ながら(無料期間の範囲でなければ)お金が発生します。データが少ない場合は並列処理させる(あくまで推奨なので変更できますが)ノードの数は1~2個くらいで済みますし処理時間も1時間くらいで終わったりしますが、全体のデータ量が多かったりするとノードが1,2個じゃ済まないし処理時間も3時間以上が当たり前のようになるので、2000円のはずが数倍以上になっちゃったというケースがあります。この場合、事前にPoC検証して使用するデータや性能評価の当たりをつけておかないと、その訓練データで本当に大丈夫か分からない状態で実機で試してはダメでまたAutoMLでモデルを作って...という負の連鎖でコストが発生していきます。特に性能評価は重要で、過学習してしまうようなデータセットなのか見極めるために必要です。潤沢に予算があればAutoMLで逐一結果を確認していくのでも良いかもしれませんが、ハッキリ言ってもったいないです。

例えば画像処理なら簡単に事前学習されたモデルを使ったCNNなどの検証で構わないと思うので、知識がなくてもちゃんと判定できてるのか事前に最低限の検証をした方が良いと思います(ウェブサイトのコピペで挙動を試すのでも良いと思うので...汗)

そのデータ、本当にロバスト

これは適当にPoC検証やってたりデータの仕様を眺めてると直ぐに気付き出すのですが、「データのサイズが統一されてるけど実サービスではリサイズされてないデータが対象」とかの自体が発生した時に、スケール不変性が保証されてないデータで学習して詰んだりとかが例としてあります。

AutoMLを使用する際にもこれは共通で、統一されたデータを使うのは良いことですが、ちゃんと実サービスに沿った入力・出力を意識して対応づけることをオススメします。自分は一回ミスった経験から、画像処理の場合は「スケール不変性は必要?回転不変性は必要?」と実サービスの設計と睨めっこしながら逐一確認する癖がつきました。

独立したテストデータで確認

これもPoC検証の一環といえばその通りなのですが、実際にサービスで動いて欲しい挙動が評価できるようなテストデータを用意しておいた方が良いです。これも実際に機械学習の解析してる方からすると当たり前なのですが、事前にテストデータを用意しておくことをオススメします。

自分もいきなり「こういうAPIのための学習器モデル作ってよ」とかテストデータがない状況でお願いされた時は、自分で勝手に独立性を検証できるようなデータを半自動でスクレイピングできるソースコードを作って収集して、一部ラベル付けしてみたいなことをやってたりします(収集を定期実行させてもラベル付けは手動になりがちなので、地味で怠いんですけどね笑)。

これをしないと汎化性能を確認できないし、精度改善のために何が足りないのかAutoMLのテストなどから推定するのも難しいと思うので、テストデータは訓練データと別途違う形で用意して評価することをオススメしたいと思います。

まとめ

今回は、業務でAutoMLを使うときに気をつけている三つのことについてまとめてみました。正直にいうと、「機械学習で解析する時に気をつけてること」とほぼ同じ注意点だったりするのですが、コスト面などの問題もあるので最低限のPoC検証はできた方が良いかなと思います。

よくよく考えたら、こういうネタを喋るのって初めてかもしれない笑

Dockerで作ったDS環境にmecab+fasttextを安全に入れるための備忘録

前回、以下の記事でDockerを使って簡単にBiqqueryのデータをjupyterで可視化する方法を備忘録として掲載しました。datascience-notebookのDocker-imageを使用しております。

yukr.hatenablog.com

今回は、前回の記事で構築した環境にmecabとfasttextをインストールして、自然言語解析向けの環境に昇華させていきます(word2vecの入ってるgensimはpip installで終わるので割愛します)。特に、mecabに関しては通常通りのインストールを行うとドツボにハマるので、その部分を重点的にご紹介できたらと思います。Dockerを用いた環境構築は先述したURLの記事を参考にしてください(そちらの環境をベースとして構築しております)。

まずは、Dockerの環境

まず、Dockerにログインします。前回の記事に沿って環境構築するとsudoコマンドを使ってmecabなどをインストールする際にパスワードを要求されてしまうので、-u rootを加えてログインします。これによって、パスワードを要求されることなくインストールができるようになります。

docker exec -u root -it 6330a9d586d7 /bin/bash

mecabのインストール

次に以下のコマンドを順番に実行してmecabをインストールして行きます。

# アップデート(これをやっておかないと、apt-get installできないエラーが発生するので、必ずやってください。)
sudo apt-get update 
sudo apt-get -y upgrade 
sudo apt-get -y dist-upgrade

# mecabを以下のコマンドに沿ってインストール(utf-8対応しないと、日本語を分かち書きするときに文字化けします)
sudo apt-get install mecab libmecab-dev mecab-ipadic mecab-ipadic-utf8 file
git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
cd mecab-ipadic-neologd
./bin/install-mecab-ipadic-neologd -n -a

# editで以下の行を修正(注意点については後述)
vi /etc/mecabrc
dicdir = /usr/lib/mecab/dic/mecab-ipadic-neologd

# pip install mecab-python3と実行してしまうとver1.0以降から辞書ライブラリをベットインストールすることが要求されたため、エラー処理とか面倒臭い。なので、何も考えずにインストールしたいのなら以下のように0.996.5で指定するのが一番無難だと思います。
pip install mecab-python3==0.996.5

ここで一番注意しなくてはならないのは、dicdir = /usr/lib/mecab/dic/mecab-ipadic-neologdのところで、参考資料では上記のように書かれていたのですが、自分の場合は普通に実行すると以下のようなエラーを吐いてしまいました。

------------------- ERROR DETAILS ------------------------
arguments: -Owakati
error message: [ifs] no such file or directory: /usr/local/etc/mecabrc
----------------------------------------------------------

これについての対策方法ですが、以下のように環境変数を設定してあげて、

sudo vi ~/.bashrc
# 以下を追記
export MECABRC='/etc/mecabrc'
source ~/.bashrc #更新

とすれば問題ないです。

参考資料: bokunoitnisshi.hatenablog.com

また、次に辞書のパスでエラーが生じてしまうので、次はneologdの辞書の正確なパスを通す必要があります。これについては、./bin/install-mecab-ipadic-neologd -n -aを実行したときに以下のような画面が最終的に出てきます。

f:id:YuKR:20200906195558p:plain

ここに書かれている

/usr/bin/install -c -m 644 ./dicrc /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd/dicrc

というのが、neologd辞書のファイル正確なpathです。なので、`vi /etc/mecabrc'で辞書のパスを指定する場合は、上記のケースならば

 dicdir = /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd/dicrc

と記述する必要があります。仮にこのケースに当てはまらないとしても、./bin/install-mecab-ipadic-neologd -n -aに必ず有効なneologd辞書のpathが出てくるので、それを間違えずにコピペすれば問題なくpython上でmecabが機能すると思います。

参考資料: ・mecab-python3のバージョンに関する記事

medium.com

mecabのインストール手順について qiita.com

fasttext

fasttextのインストールはとても簡単で、ホームディレクトリで以下をそのまま実行すれば問題なくインストールできます。

git clone https://github.com/facebookresearch/fastText.git
cd fastText
pip install .

簡単にpip install fasttextでも良いのですが、バージョンや互換性などでエラーが発生するみたいなので、上記の手順を踏むのが確実だと思います。

ついでにmatplotlibの日本語対応も行う。

以下のURLのように事前に日本語対応させた状態でdockerを構築して起動する手もあったのですが、面倒臭かったので環境ないで独自に日本語対応させることにしました。

qiita.com

直接matplotlibの豆腐(日本語文字化け)の対策を行うには以下の手順を踏んで行きます

# 日本語対応フォントを拾ってくる
curl -L  "https://oscdl.ipa.go.jp/IPAexfont/ipaexg00301.zip" > font.zip
# 展開する
unzip font.zip

cp font/ipaexg.ttf /opt/conda/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/ipaexg.ttf

cp font/ipaexg.ttf /opt/conda/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/ipaexg.ttf
cd /opt/conda/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/
echo "font.family : IPAexGothic" >>  /opt/conda/lib/python3.8/site-packages/matplotlib/mpl-data/matplotlibrc
# キャッシュを捨てないと豆腐のままになってしまうので注意
rm -r ./.cache

これで、プロットしたときにも日本語対応して描画できるようになりました。

まとめ

如何だったでしょうか。ローカルでない限り、mecabのインストールは初心者がつまづきやすい所だと思うので気をつけて頂ければと思います。ついでにmatplotlibの日本語対応を行なったので、これで本格的に自然言語関連の解析をすることが可能になると思います。今後委託先の企業などでみんながDS環境を使う機会が来たら、全部Dockerfileにまとめていかないとなぁ...汗

Dockerで簡単にBigqueryのデータをjupyterから可視化する方法

「誰でも簡単にDS環境作って、データベースからデータを持ってきて、結果を可視化できるようにしたい」

企業によって様々ですが、分析する方が業務で行う良くあるパターンとして、

・RDSやBigqueryなどからクエリを叩いて必要なデータを収集 ・収集したデータでいろんな分析をして報告→実装へ

みたいな流れがあると思います(特に、仕様設計やPoCを行う前後ではこんな感じになりやすいと思います)。

上記の手順で行うと、解析する方と結果検証する方々(営業や上司)との間に隔たりがあると感じています。理由としては、以下が考えられます。 ・解析した人がミーティングの際に一方的に報告するケースが割と多め →結果検証する側も手軽に同じ環境で結果を可視化できると、考慮できる幅が広がる可能性がある ・皆が動かせる環境を構築して逐一API叩いて結果を確認するよりは、ローカルで手軽に動かせるくらいの方が柔軟性があって良い などなど ・とにかく保守性を!!!

しかしながら、解析作業などを行なった経験がない方からすると、どのように環境を構築したら良いか分からなかったりすることも多いため、なるべく簡単に環境構築+結果検証を行えるようにする必要があります。今回は、Bigqueryのデータを以下に簡単にjupyterなどで可視化するかについて焦点を当てたいと思います。

Dockerで簡単にDS環境を構築して、Bigqueryの結果を可視化する

そこで今回ご紹介するのは、以下の環境の構築方法です。 ・Dockerで簡単にDS環境を構築 ・BigQueryのデータを可視化する 以下、具体的な手順を説明します。

1.Dockerをインストール

Macでのインストールは、以下のURLを参考にしてDockerをインストールしてください。 qiita.com

2. docker-compose.ymlを作成

自分のPCの好きなディレクトリの中に、docker-compose.ymlを作成します。vimvscodeでも良いので以下を貼り付けコピペします。

version: "3"
services:
  jupyter:
    image: jupyter/datascience-notebook
    ports:
      - "8888:8888"
    volumes:
      - jupyter_data:/opt/conda
      - jovyan_data:/home/jovyan
    container_name: jupyter
volumes:
  jupyter_data:
  jovyan_data:

この手順は、以下のURLなどを参考にしました。

qiita.com

qiita.com

3. コンテナを起動

ターミナルで以下を実行してコンテナを起動します(全体で4GBくらい容量を食います)。

docker-compose up

4. コンテナの中に入る

次のコマンドを実行して、コンテナの中に入ります。

docker exec -it CONTAINER-ID /bin/bash

CONTAINER-IDについては、docker ps -aを実行して対象環境のコンテナID(jupyter/datascience-notebookの左隣の文字列)を確認してください。

dockerの基本的なコマンド(停止や再起動)に関しては、以下のURLに纏まっているので、あまりコマンドに慣れていない方はこちらを参考にしてください。

tkmr.hatenablog.com

個人的には、vscodeにdockerの拡張機能を入れて管理するのが楽ちんです。

qiita.com

こちらを使うと、写真みたいに管理しつつ右クリックで簡単にコンテナを起動したりできます。

f:id:YuKR:20200820172856p:plain

5. jupyter notebookをブラウザで立ち上げる

docker logs jupyterと打って、docker起動後にjupyterをブラウザで立ち上げるために必要なトークンを取得します。実行すると以下のような形で表示されるので、出力の一番下のURL(下の例ならhttp://127.0.0.1:8888/?token=から続いてる文字列)を保存して、docker内でjupyterを立ち上げた後にそのURLを開くと環境に入れます。

To access the notebook, open this file in a browser:
        file:///home/jovyan/.local/share/jupyter/runtime/nbserver-8-open.html
    Or copy and paste one of these URLs:
        http://6330a9d586d7:8888/?token=d93c8b5d127479b788b49e083cc75d431b0188e8d33c0335
     or http://127.0.0.1:8888/?token=d93c8b5d127479b788b49e083cc75d431b0188e8d33c0335

こちらについては、以下のURLを参考にしました(2回目以降のjupyter環境への入り方も載ってます)。

qiita.com

6. 必要なモジュールをターミナルかjupyter上のターミナルからインストールする

Jupyter環境からBigQueryのクエリを叩いて結果をデータフレームとして表示させたいので、以下のモジュールをインストールします。

pip install pandas-gbq -U
pip install --upgrade google-api-python-client
pip install --upgrade oauth2client

7. BigQueryの結果を可視化する

一例ですが、以下のコードでBigQueryのクエリを叩いて結果を可視化することができます。実行するとURLからgoogle accountの認証を行う必要があり、それが終わると結果を可視化できます。

%load_ext google.cloud.bigquery # クエリを実行するためのおまじない
import pandas as pd
sql = '''
SELECT
sys_created as sys_created,
comments,
FROM tables
'''
data_frame = pd.read_gbq(sql, プロジェクトID, dialect='standard')

これで環境構築&可視化が実行できました!

参考URL:

cloud.google.com

オプション: credentials情報を読み込んでBigQueryの結果を可視化する方法(自動化したい場合)

上記の手順まで行えばdocker、環境からBigQueryのクエリを叩いて結果をpandasなどで簡単に可視化を行うことができます。しかし、もう一つの方法としてcredentials情報を読み込んでクエリを叩いて可視化する方法があります。こちらをマスターすればURLからgoogle accountの認証がいらないので、可視化コードを自動化することができます。

まず、すでにGCPのサービスアカウントキーをjsonで生成してる方は必要ないですが、そうでない方は以下のURLなどを参考にしてサービスアカウントキーを取得してください。

www.magellanic-clouds.com

そして、生成したキーをjupyterのworkディレクトリにアップロードして、以下のように実行して結果を可視化します。キーの名前は、コード内ではsecrets.json命名してます(サービスアカウントキーは大切なものなので、失くさずに大事に保管してください!)。

from google.cloud import bigquery
from google.oauth2 import service_account
import pandas as pd
import os

key_path = os.path.join('/home/jovyan/work', 'secrets.json')

credentials = service_account.Credentials.from_service_account_file(
    key_path, scopes=["https://www.googleapis.com/auth/cloud-platform"],
)

client = bigquery.Client(credentials=credentials, project=credentials.project_id,)

query = '''
SELECT
sys_created as sys_created,
comments,
FROM tables
'''

df = pd.read_gbq(sql, project_id=credentials.project_id, dialect='standard')

まとめ

今回は、dockerでデータサイエンス環境を整えて、dockerのjupyterからBigqueryを実行して結果を可視化する方法をまとめてみました。Bigqueryにデータがあるなら誰でも気軽に環境を作って可視化&解析できるので、興味のある方はぜひ試してみてください。

SAR画像の見た目を基本的な画像処理で一瞬に改善する方法

背景

はい、久しぶりの投稿です。 最近、様々なところからお声が掛かっており、ブログを書く暇がありませんでした(汗)

自分は、趣味の延長で衛星画像の一つであるSAR画像と呼ばれるレーダ画像について解析を行なっていて、解析記事の執筆なども行なっております。このSAR画像ですが、Google Earthなどで見られる光学画像と異なる部分としては、スペックルノイズと呼ばれる白黒のゴマ状のノイズが大きな問題になっております。そしてこのSAR画像、頑張ってデータのバイナリ情報を取り出して可視化しても、最低限の処理をしないと見栄えがあまり良くないです(何もせずにマニュアル通りのキャリブレーションをかけても白っぽく映ってしまう)。今回は、この対策をご説明したいと思います(単純な画像処理です)。ちなみに、最終的に以下の見栄えになります。

f:id:YuKR:20200803004849p:plain

さて、上記の問題ですが、「コントラスト強調」を行うことで簡単に解決できます。

今回はopencvのように自動でコントラスト変調を行わずに手動での調整を行いたいので、以下のサイトを参考にしてコントラスト強調の処理を加えました(余談:話が逸れますが、opencvの平坦化ヒストグラムは便利ですが使い所を間違えると潜在的な情報を見失う場合があるので注意が必要です)。

www.blog.umentu.work

今回は、衛星画像を無料で公開しているプラットフォームであるTellusから取得した霞ヶ浦周辺の画像を使って解析してみます。TellusでのSAR画像の取得方法については、以下のサイトなどにTellusでSAR画像を取得するソースコードがまとまっているので参考にしてください。

sorabatake.jp

HH = np.load('/SHH.npy')
HV = np.load('/SHV.npy')
VV = np.load('/SVV.npy')

import cv2
import matplotlib.pyplot as plt
from numpy import inf

sigma = HH
sigma = 10*np.log10(sigma) -83.0 -32.0
sigma = np.array(255*(sigma-np.amin(sigma))/(np.amax(sigma)-np.amin(sigma)),dtype="uint8")
HH = sigma


sigma = HV
sigma = 10*np.log10(sigma) -83.0 -32.0
sigma = np.array(255*(sigma-np.amin(sigma))/(np.amax(sigma)-np.amin(sigma)),dtype="uint8") # opencvなどの処理に対応できるように8ビットに正規化してあります。
HV = sigma

sigma = VV
sigma = 10*np.log10(sigma) -83.0 -32.0
sigma = np.array(255*(sigma-np.amin(sigma))/(np.amax(sigma)-np.amin(sigma)),dtype="uint8")
VV = sigma


img=np.zeros((2000, 2000, 3), np.uint8) # 画像サイズは切り出したサイズを指定してください
img[:,:,0]=HH
img[:,:,1]=HV
img[:,:,2]=VV

# コントラスト強調
min_table = 90
max_table = 252
diff_table = max_table - min_table
look_up_table = np.arange(256, dtype = 'uint8')
for i in range(0, min_table):
    look_up_table[i] = 0
for i in range(min_table, max_table):
    look_up_table[i] = 255 * (i - min_table) / diff_table
for i in range(max_table, 255):
    look_up_table[i] = 255

img = cv2.LUT(img, look_up_table)

plt.figure()
plt.imshow(img)
plt.imsave('sample.png', img)

結果がこちらになります。実際にコントラスト強調を行わずに疑似カラーにしたSAR画像と比較して見ましょう。

Before

f:id:YuKR:20200803003717p:plain

After

f:id:YuKR:20200803003723p:plain

...全然見た目が違いますね。コントラスト強調を行うだけで、見違うくらい見た目が良くなります。

ちなみに、これをパワー(値の複素共役を掛け合わせる)で表示してコントラスト強調を行うと以下の見た目にできます。専門ソフト並みの綺麗なSAR画像の見栄えを、コード一つで簡単に表現できるのは嬉しいですね。

Before

f:id:YuKR:20200803004827p:plain

After

f:id:YuKR:20200803004849p:plain

まとめ

今回は、SAR画像を使ってコントラスト強調を行い、コントラストを強調して見た目をよくする事を行なって見ました。 普段なこのような画像のコントラストや画質の調整はENVIなどの専門ソフトを使って行うことが専門家だと多いと思いますが、専門ソフトがなくてもちょっとした工夫次第で様々な解析ができます。 光学画像に飽きてSAR画像を綺麗に表示してみたい方がいましたら、ぜひ参考にしてください。

参考文献

www.blog.umentu.work