luggage baggage

Machine learning, data analysis, web technologies and things around me.

Python 機械学習コードを Cython でラップして C/C++ から使う

お久しぶりです。吉田弁二郎です。

Cython という便利なトランスパイラ(言語と言語の中間にある言語のようなもの)があります。Python ライクな文法で書ける Cython スクリプトは C/C++ コードに変換・コンパイルされた後に Python から呼び出し可能で、C/C++ ライブラリを Cython スクリプトから呼び出すことも難しくないので、Python ライブラリの高速化作業を効率良くおこなうためによく使われています。

著名なプロジェクトで言うと scikit-learn や pandas だったり、最近利用が広がり始めた cupy などで Cython が使われています。scikit-learn の例で言うと、例えばツリー系のアルゴリズムを実装したこのスクリプトは Cython によるものですね。

また逆の方向として、Python で書いたライブラリを C/C++ コードから手軽に呼び出したい、という時にも Cython を使うことができます。双方向のラッパーとして機能するのですね。今回の記事では、この方向で Cython を使うための簡単な例を紹介していきます。Cython の文法については詳しくは書かないので、ドキュメントもしくはデモコードなどを見ていただけるとよいと思います。

続きを読む

Python の defaultdict には注意しよう

こんにちは。

Python には標準的なデータ型に加えていくつかの便利な型が用意されています。特に collections モジュールには、以前記事に書いた deque や、今回取り上げる defaultdict が格納されています。

通常、辞書型のデータ d にデフォルト値を設定しながら値を詰めていく場合、d.setdefault(key, default_value) といったやり方をするのではないかと思います。このようにしない場合は、例えば d に保存されていないキー k で辞書にアクセスしてしまうと、KeyError が出てしまうのですね。

同様の用途で、より柔軟かつ(おそらく)高速な処理が実現できるのが defaultdict です。

続きを読む

SQLAlchemy + PostgreSQL で Upsert を行う(ユニークキーに重複があるデータのバルクインサート)

こんにちは。吉田弁二郎です。

タイトルにある Upsert とは、Update or Insert のことです。あるテーブルにデータを insert しようとするとき、ユニーク制約が効いているキーが過去データのものと重複して insert できない場合、update に切り替える処理のことですね。データ量が多くキー重複の懸念がある状況で multiple insert したい場合などに有効な手段の一つです。

私はよく PostgreSQL を使うのですが、Python 経由で操作したい時には psycopg2 とか SQLAlchemy を選ぶことが多いです。特に SQLAlchemy はオブジェクト的にデータベースを操作できるため、web アプリを開発する時に使っています。

今回は、PostgreSQL 9.5 以上で利用可能な upsert 構文 ON CONFLICT ... DO UPDATE を SQLAlchemy (>= 1.1) から使う方法について書いていきます。

続きを読む

Python のリスト操作は collections.deque が速い

こんにちは。吉田弁二郎です。

先日タスクスケジューラを Python で実装することがあり、深さ優先探索の方針で作業を進める必要がありました。その際、リストの先頭からデータを取り出し先頭にデータを入れる、ということをやったのですが、デフォルトの list ではなく collections.deque を使うと遥かに効率的に動作することを知ったので共有したいと思います(かなり旧聞にあたる内容ですが、ご容赦ください)。

続きを読む

Pandas メジャーアップデート(0.20.1)の要点〜高速 I/O、集約関数強化など

こんにちは。吉田弁二郎です。

先日(5月5日)、pandas の最新版 0.20.1 がリリースされました。agg/transformメソッドがgroupbyしなくても使えるようになり、10倍以上高速な I/O を実現する feather-format が(試験的に)導入され、スライスの際に頻繁に利用されていた.ixインデクサが deprecated となるなど、全般的に着実な改善もしくは変更がされている印象です。以下、リリースノートのハイライト部分より、目についたものをピックアップしていきます。

続きを読む

GPU 版 TensorFlow 環境を AWS 上にコマンド一発で立ち上げるスクリプトを書きました

こんにちは。吉田弁二郎です。

前置き

最近、TensorFlow のインストールは pip により簡単にできるようになりました。一方で GPU 環境の整備(CuDNN の準備等)が相変わらず面倒だと思うことも多く、GPU 自体の進歩も早いのでオンプレ環境に手を出すのも少しためらわれる感じもします。そこで Amazon Web Services (AWS) の GPU インスタンスを使ってみるものの、毎回ゼロから手作業で TensorFlow 環境を構築するのもそろそろ効率的にしたい、という状況になっています。

そんな訳で、コマンド一発で環境構築するための自動化スクリプトを書きました。もしかしたら誰かがやっているかもしれませんが気にしない。

やり方としては、Ansible を使います。Ansible はエージェントレスな構成管理ツールなどと言われ Web 系の人たちが使っていますが、要するにサーバ上でのディレクトリ作成やソフトウェアのインストール等を自動化するものです。リモートマシン、ローカルマシンのそれぞれに Python2 が入っていれば pip install ansible で使い始めることができます*1

ここでは、Ubuntu Server 16.04 LTS (HVM) を選択し(=あらかじめ GPU 開発環境が設定されていない)、最小限の工数で済ませるために nvidia-docker を使い、TensorFlow の docker image を取得することを大きな方針とします。

(2017.06.19 追記)
こんな AMI が登場したので、もはやこれでよさそうです。笑
AMI 自体が有料ではありますが(本記事の方法では、AMI は無料となります)。
AWS Marketplace: Deep Learning AMI Amazon Linux Version

*1:Python3 対応もされ始めているものの、現状は2系で安定稼働します。今回書いたコードも Python2 で動かすことを前提としています。ただ、Ansible を動かすために2系が必要というだけなので、数値計算用に3系が独立して存在していても問題ないはずです。

続きを読む

conda の環境名に応じて ipython / jupyter notebook の起動時読み込みライブラリを変更させる

こんにちは。吉田弁二郎です。

ipython コンソールや jupyter notebook をお使いの方は、起動時の自動処理設定ができることをご存知かもしれません。具体的には、

~/.ipython/profile_default/startup

に置かれたスクリプトが起動時に自動的に読み込まれます。適当に numpy などを import するスクリプトを用意しておけば、 毎回手作業する苦痛から解放されるわけですね。

ところで、anaconda / conda でパッケージ管理する場合、

conda create -n another_env python=3.6 numpy pandas

などとして独立した開発環境 (another_env) を用意して作業を進めることも多いと思います。今回は、独立した conda 環境ごとに ipython 起動時に読み込まれるライブラリを自動的に変えるための startup スクリプトを書いたので、ここに紹介しておきます。

続きを読む