tkm2261's blog

研究員(OR屋) → データ分析官 → MLエンジニア → ニート → 米国CS PhDが諸々書いてます

Python高速化 Numba入門 その2

今回は、QuickStartを読んでいきます。

Quick Start — numba 0.15.1 documentation

とりあえず、前回の@jitデコレータだけで動くのは理解した。

from numba import jit

@jit
def sum(x, y):
    return x + y

引数と戻り値の型が陽にわかっている場合には、@jitの引数に『戻り値の型』(引数1の型, 引数2の型, ...)で指定できる。恐らく早くなるのだろう

@jit('f8(f8,f8)')
def sum(x, y):
    return x + y

numpyの配列もサポート。多次元配列はこんな感じf8[:, :, :]

@jit('f8(f8[:])')
def sum1d(array):
    sum = 0.0
    for i in range(array.shape[0]):
        sum += array[i]
    return sum

サポートされている型は以下。主要なものは大体ある。

Type Name Alias Result Type
boolean b1 uint8 (char)
bool_ b1 uint8 (char)
byte u1 unsigned char
uint8 u1 uint8 (char)
uint16 u2 uint16
uint32 u4 uint32
uint64 u8 uint64
char i1 signed char
int8 i1 int8 (char)
int16 i2 int16
int32 i4 int32
int64 i8 int64
float_ f4 float32
float32 f4 float32
double f8 float64
float64 f8 float64
complex64 c8 float complex
complex128 c16 double complex

型は文字列で指定しなくても、importして指定もできる。ハードコーディングにならないのでこっちのが嬉しい。

from numba import jit, f8

@jit(f8(f8[:]))
def sum1d(array):
    ...

型がわからない場合は、通常のPythonで処理するので異常に遅くなってしまう。それを避けるためにPythonでの処理を禁止することもできる。
どうしても型がわからない場合はエラー吐くのかな?

@jit(nopython=True)
def sum1d(array):
    ...

Numbaの型推論の結果を取得するには、inspect_typesメソッドが用意されている。これを参考にデコレータの引数を決めるのも良さそう

sum1d.inspect_types()

実際にやってみる

とりあえず、型がわからない時に、nopython=Trueするとどうなるか

from numba.decorators import jit
import numpy

class DummyClass(object):
    def __init__(self):
        hoge = 0
        huga = 2
        hogo = "hogehoge"

@jit('f8[:, :](f8[:, :], f8[:, :])', nopython=True)
def pairwise_numba3(X, D):
    M = X.shape[0]
    N = X.shape[1]
    for i in range(M):
        for j in range(M):
            d = 0.0
            for k in range(N):
                tmp = X[i, k] - X[j, k]
                d += tmp * tmp
            D[i, j] = numpy.sqrt(d)

    return DummyClass()

結果は、やはり推論出来ない型でnopython=Trueはエラーらしい

TypingError: Failed at nopython frontend
Untyped global name 'DummyClass'

型指定したほうが速いのか?

検証のために以下を実行

# coding: utf-8
import numpy
from numba import double
from numba.decorators import jit
import time
import traceback

@jit
def pairwise_numba(X, D):
    M = X.shape[0]
    N = X.shape[1]
    for i in range(M):
        for j in range(M):
            d = 0.0
            for k in range(N):
                tmp = X[i, k] - X[j, k]
                d += tmp * tmp
            D[i, j] = numpy.sqrt(d)

    return D

@jit('f8[:, :](f8[:, :], f8[:, :])', nopython=True)
def pairwise_numba2(X, D):
    M = X.shape[0]
    N = X.shape[1]
    for i in range(M):
        for j in range(M):
            d = 0.0
            for k in range(N):
                tmp = X[i, k] - X[j, k]
                d += tmp * tmp
            D[i, j] = numpy.sqrt(d)

    return D

if __name__ == '__main__':

    t = time.time()
    X = numpy.random.random((1000, 3))
    D = numpy.empty((1000, 1000))
    pairwise_numba(X, D)
    print "numba:", time.time() - t

    t = time.time()
    X = numpy.random.random((1000, 3))
    D = numpy.empty((1000, 1000))
    pairwise_numba2(X, D)
    print "numba2:", time.time() - t

結果は・・・

numba: 0.134999990463
numba2: 0.0120000839233

10倍高速化!

前回、普通のPythonから33倍高速になったので、型指定まですると330倍高速化したことに。

Numba結構イケるやん!

次回は、ユーザーガイドの続きか、First Steps with numbaを読む予定

Python高速化 Numba入門 その1

みなさん、こんにちは
今日からPython高速化 Numbaに入門したいと思います。

入門資料を探しに来た皆様すみませんが、 本記事は私がこれから入門する内容になります。

結果として入門資料に慣れば幸いですが、過度な期待は御無用でお願いします。

基本的には以下を読み進めて行きます。

http://numba.pydata.org/

Numbaとは

JIT(just-in-time)コンパイラを使ってPythonを高速化しよう!』というPythonモジュールです。

LLVMコンパイラを使っており、これはJuliaが高速な理由でもあるので期待大です。

学生時代はCythonを使って高速化をよくしていましたが、以下の理由により今回はNumbaを学びます

候補 今回諦めた理由
Cython cdefとか結構手を入れるのでPythonに戻すのが面倒。pyximportも面倒
C拡張 C言語は極力触りたくない
PyPy numpyサポートが怪しい。いつか触るかも
Julia なるべくPythonでやりたい。これでダメなら入門するかも。

Numbaはどうやらデコレータ一発で一応動くらしい。Cythonよりは使いやすいことを期待したい。

とりあえず通常Pythonと比較

以下のサイトのコードを参考に速度を計測

Numba vs Cython

ちょっと手を加えて、実行したのが以下のコードで比較

# coding: utf-8
import numpy
from numba import double
from numba.decorators import jit
import time

@jit
def pairwise_numba(X, D):
    M = X.shape[0]
    N = X.shape[1]
    for i in range(M):
        for j in range(M):
            d = 0.0
            for k in range(N):
                tmp = X[i, k] - X[j, k]
                d += tmp * tmp
            D[i, j] = numpy.sqrt(d)


def pairwise_python(X, D):
    M = X.shape[0]
    N = X.shape[1]
    for i in range(M):
        for j in range(M):
            d = 0.0
            for k in range(N):
                tmp = X[i, k] - X[j, k]
                d += tmp * tmp
            D[i, j] = numpy.sqrt(d)


if __name__ == '__main__':
    t = time.time()
    X = numpy.random.random((1000, 3))
    D = numpy.empty((1000, 1000))
    pairwise_python(X, D)
    print "python:", time.time() - t

    t = time.time()
    X = numpy.random.random((1000, 3))
    D = numpy.empty((1000, 1000))
    pairwise_numba(X, D)
    print "numba:", time.time() - t

結果は

python: 4.64800000191
numba: 0.137000083923

34倍の高速化!イケるやん!

次回はQuick Startを読む予定

最適化超入門

SlideShareだけでなく、ブログの記事にもすることに

先日、TokyoWebMning #40にて最適化について熱く語ってきました。

個人的にも結構やりきった感があり、網羅的に最適化手法を紹介出来たと思います。

その後飲んだ研究室の同期には『難しすぎる』と言われましたが、どうなんでしょう・・・

一応はてブが400を超えており、大丈夫だったと信じたい。

というか、最適化の話題ではてブこんなに頂けるのは予想外でした。ありがとうございます!

はてなブックマーク - 最適化超入門

PyData Tokyoの方にもお声掛け頂いたのでまたどこかでお話出来ればと思ってます。
次はセクシー女優みたいにしょーもない話にする予定ですw  
 
 

今回は修士卒の人間が最適化の入門資料を作る事のは、おこがましいと戦々恐々していたのですが、 Twitter上では概ね好評であり、安心しております。

NIIの前原先生からもお褒め頂いたので、最適化チートシート流行らそうと思いますw

f:id:tkm2261:20141206141012p:plain

あと、阪大の梅谷先生からご指摘があり、CPLEXは出来る子とのことです。

CPLEXはコア単位課金でお高いため、企業ではほぼGurobi一択な現状なので誇大に書きすぎたようです。
あとSOS制約の入った問題が高速だったため、うちの会社ではCPLEXからGurobiに移行しました。

研究で使われるかたはどちらもフリーなので、mpsファイルでも吐いて検証してみることをオススメします。

ちなみに、Gurobiは先日バージョン6.0がリリースされ、イベントに参加してきました。

Company - News - Highlights of Gurobi Optimizer 6.0

目玉としては、分散MIPと区分線形関数でした。
MIPも分散する時代になったか・・・といった感じです

区分線形関数もSOS制約でいちいち書かなくて済むので、応用事例が増えることが期待出来そうです。

合わせてBixby氏からNFLの試合日程最適化の話があり、非常に興味深い話でした。 2014年から木曜日に試合を行うことなり、モデルが異常に難しくなったようです。

新日鉄住金ソリューションズの山本さんからもJリーグの日程最適化の話があり、
うちの会社でもスポーツ系やりたい( ´Д`) 

長くなりましたが、益々最適化が流行ればいいな!と思う次第です。

Word2vecで大谷翔平の二刀流論争に終止符を打つ!

皆様、お久しぶりです。

VOYAGE GROUPさん主催の14' Data Scientist MeetUpでLTした時の資料 3時間で作った資料なので超絶適当です。

リファクタしてから上げようかと思いましたが、忙しくて断念

ネタ的にお蔵入りは勿体無かったので、そのまま上げています。

気が向いたらなんかやるかも

Scikit-learnで学ぶ機械学習入門

 今回はこの前勉強会で話してきたこの話

 

『Scikit-learnで学ぶ機械学習入門 』

ついに、このブログでもデータ解析っぽいことを話せて感無量です。

 

詳細な勉強会の模様は天丼丸さんのページをご参照ください。

機械学習勉強会 #2 | /home/by-natures/*

 

 

この勉強会では、機械学習が初めての方も多かったので、

機械学習の全体的な流れを重視して話して来ました。

 

特にp.11の、機械学習の流れは汎用的に使えるかと思います

精度が上がらない時は、このフローに抜け漏れが無いかを確認することが重要です。

f:id:tkm2261:20141002010817p:plain

 

scikit-leanの使い方については、ほとんど解説してませんが、

APIが全て統一されているので、以下だけでほぼ全て使えます。

  • 使用したい手法のインスタンスの生成
  • パラメータのセット
  • fit()関数による学習
  • predict()関数による予測

githubにサンプルコードも載せておいたので、必要でしたら見て下さい。

anaguma2261/scikit-learn-sample · GitHub

 

あとは、各種の手法の利点欠点などをまとめておいたので、

これから機械学習やろうとしている方の一助になればと思います

 

dplyrとR界隈について

Pythonianの私としてはブログの記事として、

Pythonよりも先にRについて書くのは若干気になるものの、

同僚のR使いに面白い共有を頂いたので備忘のため記事にします。

※同僚の受け売りなので、私はあんまりRに詳しくないです

 

近年、R界隈に彗星のごとく現れた、Hadley神ことHadley Wickham氏

had.co.nz

hadley (Hadley Wickham) · GitHub

 

同僚によると、彼の登場により、R界隈に大きい変化の波が来るとのこと

日本語の資料もないので、日本ではほとんど話題になってないが、時間の問題らしい

 

彼の書いた、Advanced R (http://adv-r.had.co.nz/)は

Rのパッケージの作成方法から、

テストといったコードの品質保証まで網羅的に書かれており、

Rをあまり使わない私としても非常に参考になる

 

これにより近年のR(笑)の流れに歯止めがかかり、

Tokyo.RでもRがメイントピックになる日が来る! かな?

 

ウチの会社でも、分析のみの案件では良いものの、システム化が絡むとRは

カワサキバイクのコピペ並に、エンジニアの顔が歪みます

       (それよりも分析官が、テストを書いていないことに起因することが多いですが・・・)

 

ともあれ、分析官にR使いは多いので、

Rがシステム化に耐えられる様になるのは、なにより喜ばしいこと

この流れはこの辺ウォッチしとけば追えるのかな


R-bloggers | R news & tutorials from the web

 

 

前置きが長くなりましたが、dplyrについて語ります。

といっても先人たちがすでに良記事をたくさん書いているので

使い方はそっちを見てください。この記事では思想のみ語ります。

 

日本語資料

英語資料

 

まだまだR-pubs漁れば、たくさん出てきます。

 

dplyrの特徴としては、

  • (Rなのに)速い!
  • filter()、 arrange()、 select()、 mutate()、summarise()の5つの動詞に集約された洗練された設計
  • DB上のテーブルも同じ操作で扱える
  • 近年流行りのパイプ(『%>%』←こいつ)でコードの見渡しが非常に良い。
    SQLライク(筆者感)にもコードが書ける。

 

特にDB上のテーブルを簡単に扱えるのは強力かと

 

Pythonでも Pandas + SQLAlchemy で似たことはできるが、

SQLAlchemyがフルスタックのORマッパなので、

高機能過ぎて学習に時間がかかったり、手順がどうしても多くなる

 

その点、Rはデータ分析に特化しているので、シンプルに機能を絞り込めているので、

使い勝手が良さそう。

 

久しぶりにRで心を動かされたので記事にしてみました。

私もRしっかり勉強するかな・・・

セクシー女優で学ぶ画像分類入門

記事第一弾はこちら

『セクシー女優で学ぶ画像分類入門』

おそらくTokyoWebMining史上もっともはてブ数をもらっています

タイトルが反則くさいですが。。。

この記事を書いている段階で698はてブなので700は目指したいところ

 

2chにスレ立てたときのまとめはコチラ


【画像あり】割と本気だしてAV女優分類したんだが・・・ : 暇人\(^o^)/速報 - ライブドアブログ

 

 

一年以上前なんであんまり語っても仕様がないので、内容を簡単にまとめ

 

全然大したことはやっていません。

実際作業は3日、資料作成を入れても1週間で出来ました。

 

LT受けするネタも結構簡単に作れてしまうもんです。

 

ただし、

思いついたネタやアイデアは得てして簡単に埋もれてしまいます。

例えば今回は主に

この3つの技術を使ってますが、どこかで躓くとお蔵入りします。

他の2つがどんなに出来ても、一つの為にお蔵入りするのは非常にもったいない事です

 

勉強会の怖い人を意識したり、ベストプラクティスを追い過ぎず

動くことを最優先にする思想が、新しい事をやるときに非常に重要だと感じてます。

 

あと勉強会は話してナンボなんで、なんかやったほうがいいです

自分より出来る人がたくさんいますが、動くものを持っていった人は誰よりも強いです。

優位にコミュニケーションとれますし、人脈も広がるかと

 

AV女優ネタの癖に偉そうに語ってしまいましたが、

今後もこんな形でつらつらと書いて行ければと思います

 

最後に、この分析で一番面白かったのは

  • スリーサイズと趣味の基礎分析

です。詐称が当たり前の世界なんで男性の願望が出ている歪な分布を考察するのは一興です。

AV女優モナリザも誰か使ってください

 

f:id:tkm2261:20140923235842j:plain