2011年4月26日火曜日

漠然とした不安とmilkモジュール

皆様おはようございます.
今朝の滝沢村は,雨だれの音が音がこだましていて
どんよりとした雲が低く垂れこんでおります.

地震から日が経つに連れ余震の頻度は落ちてきた
はずなのに,正直なところ気持ちは落ち込む一方です.
なにか悪いことが起こるのではないかという,
なんともいえない気持ち悪さが心から離れません.
そんなことは無いさと思ってみても,気を緩める頃には
決まって地震に大地が震え,私は再び悪い予感に
とらわれるという循環になっています.

自分の心に素直に向き合い,本能の声に耳を傾けるならば
「これだけでは済まされない,もう一つ何かが起こるよ」
というささやきが聞こえてくるようです.
その声を無視して日常をやり過ごせばよいのか,それとも
理屈では説明のつかない悪い予感に従えばいいのか,
まだ割り切れずにいながら,時間が過ぎていきます.

ところで,ここまでの話と全く脈略がありませんが,
ここからガラリと話題を変えまして...

先日,少し知的な処理をコンピュータにやらせたいと思いまして,
pythonの機械学習モジュールについて調べてみる機会がありました.
そのとき見つけた「milk」というモジュールについてメモを披露したいと思います.

「milk」は名前の印象とは関係なくって複数の機械学習
アルゴリズムを集めたpythonパッケージのようです.
SVMやboostingなどをお手軽に使えるところが気に入りました.
複数のアルゴリズムを組み合わせて使うことも考慮されています.
残念なことに,milkのドキュメントは2つくらいしか見つかりません.
pypiとluispedroです.
インストールは「easy_install milk」でいけました.

使い方ですが,サンプルを引用します.
import numpy as np
import milk
features = np.random.rand(100,10)
labels = np.zeros(100)
features[50:] += .5
labels[50:] = 1
learner = milk.defaultclassifier()
model = learner.train(features, labels)
example = np.random.rand(10)
print model.apply(example)
example2 = np.random.rand(10)
example2 += .5
print model.apply(example2)

milk.defaultclassifier()は,お手軽に使えるように
あらかじめデフォルト設定された学習機となっていて
SVM=Support Vector Machineを使った学習となっています.
教師信号として入力する特徴量(features)と対応するクラスタラベル(label)を
入力してやります.
特徴量の正規化や線形従属な要素の除去なども全自動でやってくれます.
defaultclassifier()では複数のクラスタに分類するためにone-versus-rest手法が
用いられるようになっています.
もちろんこれらの組み合わせを自分で自由に設定することも可能です.
defaultclassifier()の中身は,次のようになっているようです.
defaultclassifier = ctransforms(
   chkfinite(),
   interval_normalise(),
   featureselector(linear_independent_features),
   sda_filter(),
   gridsearch(one_against_one(svm.svm_to_binary(svm.svm_raw())),
   params={
     'C': 2.**np.arange(-9,5),
     'kernel': [svm.rbf_kernel(2.**i) for i in np.arange(-7,4)],
   }
))
ctransforms()というのが複数のフィルタ(学習器)を束ねてくれるmilkのAPIです.
そのなかで1つづつ与えられている引数の要素がそれぞれ別個の学習機や
フィルタとなっています.
・chkfiite()は,特徴量やラベルに無限やNaNなどが含まれていないかチェックするフィルタ.
・interval_normalise()は,特徴量を正規化するフィルタ.
・sda_filter()は,判別分析を行うフィルタ.
・gridsearch()は,多値問題をグリッド検索に基づいて与えられた学習器で学習するフィルタ.
・svm.rbf_kernel()は,Support Vector Machineのradial basis function kernel.

milkのフィルタ(学習器)は,皆 learn_func(features, label)のような引数を持つように
設計されていて,ctransforms()で束ねて与えると,パイプライン処理により1つの
学習機として動作するようになっているようです.

冒頭のサンプルコードに戻りますが,学習器のインスタンスを生成した後,
「train」で特徴量とラベルを与えて学習させます.
learner = milk.defaultclassifier()
model = learner.train(features, labels)
処理には数秒を要します.学習が終わると学習モデルが得られますので,
未知の特徴量を与えれば,学習結果に基づいて分類してくれます.
print model.apply(example)
学習モデルは,pickle化できるのでディスクから読み込むことも可能です.

OpenCVと組み合わせたり,あるいはネットから集めたデータを
自動分類したい時など,お手軽に使えるのではないでしょうか.

2011年4月21日木曜日

近況報告と64bit windows環境でのCython

皆様こんにちは.
どうやら2ヶ月ぶりの更新だったようです.
2月から3月までは,ただブログ更新をサボっていただけなのですが,
3月から4月にかけての1ヶ月間は リアルな生活で精一杯でした.
ようやく余震は,頻度も規模も小さくなってきて3.11以前の日常に戻りつつあります.
大震災で亡くなられた皆様のご無念を思うと切なくてなりません.
亡くなった皆様のご冥福をお祈り致しております.
また被災者の皆様には一日も早く落ち着いた生活を取り戻せますように祈っております.

日本政府の遅々とした対応には憤りを感じるばかりです.
奮闘している現場と対照的に政府にはリーダーシップのかけらも感じられません.
今回の大震災は被災地が広範囲に渡っているとはいえ散々な対応ぶりに見えます.
震災以前は,日本政府の能力は高く国民主体であると漠然と思って疑いませんでしたが,
これが大きな勘違いであったと今回の出来事で思いました.
普段あまり意見の合わないカミさんとさえも,この点においては意気投合しておりましたので,
世の中の皆さんにもこのように感じた方が少なくないのではないかと
勝手ながら想像しているところです.
どうか日本に一刻も早く良きリーダーが与えられて人々が希望を胸に
前に進むことができるようにと強く願い,毎日祈る日々です.

 私の近況ですが..地震の後 3日ほど停電,
その後の余震でも1日程度停電があった事などで
仕事にも多少の影響はでておりましたが,
事前の計画を遅れなく実現すべく開発業務に勤しんでいます.
 この頃は,もっぱら物理現象を観察しその現象をある程度再現する
なるべく簡略なモデル式とパラメータを探すといった地味な仕事をしております.
地味な仕事とはいえ このような最適化の作業は,物理の教科書をほっくりかえしつつ,
過去にサボったツケを実感しながら,
試行錯誤の繰り返しと計算の待ち時間のやり過ごし方など
ストレスの多い作業となっています.
 数時間かかった最適化計算が収束せず,良く調べてみたら計算プログラムのバグに
行き着いたときに感じる無気力感を 気持ちの隅に追いやりながら
作業を継続せねばなりません.
 以前は最適化計算をさせるためにC++やCを使っていましたが,
この頃は Python+SciPy+Numpyの組み合わせが気にいております.
特に「scipy.optimizeパッケージ」に感謝です.
 私は普段,Intel T7600(Core2duo 2.3GHz)+32bitVistaのノートPCを
持ち歩いて仕事しているのですが,最適化の計算だけは時間がかかってしまうので,
その時だけちょっと速そうなデスクトップパソコンを起動して計算させています.
例えばAMD PhenomII3GHz+Vista64bitなどにPythonスクリプトを走らせると,
T7600ノートPCでは及びもつかないスピードで計算してくれます.
当初は,私もこれだけで満足していたのですが,どんどんフィッティング対象の式が
複雑怪奇なものに成長するにしたがってPhenomマシンでも待ち時間が長くなり
どうしたものかと悩むようになりました.
 JITで早いとウワサのPyPyを試してみようと思いましたが,残念なことに
NumpyもScipyもPyPyでは動きませんので箸にも棒にもかかりません.
 そこで,Cythonを試してみることにしました.
Cythonは,Pythonもどきのスクリプトを書いてあげるとCに変換してくれて
pythonからimport可能なDLLを生成してくれるものですが,
現時点におけるpython高速化の確実なソリューションといえると思います.
 しかし普段やらないことにとりかかるのは億劫なものです.
ドキュメントも読まねばなりません.
こういうパッケージを追加していざ取り組んでみると落とし穴にハマって
抜け出せないことが多々あります.Cythonも例外ではありませんでした.

 結論からいうと,Vista32bit環境でCythonを使うことは全く問題ありませんでした.
Vista32bitではVisual Studio2005をインストールしているけれども,
mingwでコンパイルする設定を追加しておりますが問題もなく動きました.
きっとVCでもサクっとコンパイル出来るに違いありません.
私のVista32bit環境python27にあるLIB/distutils/distutils.cfgの中身を書いておきます.
[build]
compiler = mingw32
Cythonスクリプトをコンパイルしたときのsetup.pyは次のとおりです.
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("hoge_func", ["hoge_func.pyx"], include_dirs=["C:/cygwin/usr/local/Python27/Lib/site-packages/numpy/core/include"])]
setup(
  name = 'hoge function',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)
これでhoge_func.pyxにCythonスクリプトを書いておいて
"python setup.py build_ext --inplace"を実行すればサクっとコンパイルされて
pythonから"import hoge_func"できて恩恵に預かることができました.
ただしVista32bit環境だけです.
 Vista64bit環境のCython設定でハマりました.
正しく言えばdistutilの設定ということでしょうか.
Vista32環境+Cythonで十分早くって64bitで動かすことをしなくてもいいぐらい
高速化されたんですが,欲が出まして Vista64でも scipy+numpy+cythonの
最適化計算環境がどうしても欲しくなりました.
そこで 64bitネイティブなmingw64でもないかと探して"x86_64-w64-mingw32-gcc"なるものを
見つけインストールしsetup.pyを走らせましたがエラーを吐きます.
エラーの内容はもはや思い出せませんが,多数のエラーにブチ当たりました.
行き着いた先が,「Compiling 64-bit extension modules on Windows」というドキュメント.
64bitでcythonを楽しむためには次の条件を揃えねばならないようです.
1.Python2.6か2.7もしくは3.1
2.Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1が必須
 つまり,mingw64は使えないということです.
先程のドキュメントにはSDKバージョンは"Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1"以降となっていますが,最新版をインストールしてもコンパイルできませんでした.
SDKのダウンロードも結構かかった上に2種類もインストールしたり,
インストール中にフリーズしたりとハマリにハマってやっとコンパイルできました.
コンパイル時の呪文も書いておきます.
これをバッチファイルやMakefileなどに書いておくといいかもしれません
C:\Program Files\Microsoft SDKs\Windows\v7.0>set DISTUTILS_USE_SDK=1
C:\Program Files\Microsoft SDKs\Windows\v7.0>setenv /x64 /release
python setup.py build_ext --inplace
 苦労した割に,振り返ってみると大した事ではなかったのに
いったい何でハマってしまうのかと毎回思うのですが,
知らないもんは知らないのですからしょうがないと諦めます.
 ちなみにCythonの高速化は,ハンパではありませんでした.
正確にベンチマークとったら報告したいと思いますが,
体感スピードでは100倍以上早くなったといっても大げさではないと思っています.

2011年2月22日火曜日

VHDLが好きな岩手県?

ちょっとだけ面白いことを見つけたので紹介します.
下のランキングはGoogleで「Verilog」を検索している地域の順位.

続いて「VHDL」のランキング.
何故か岩手県がトップに君臨.
しかも2位を30ポイント近くも引き離しております.
岩手県にはVHDLが気になっている人が多いのでしょうか

もう一つ「Python」でのランキング.
これにも岩手県が2位にランキングしています.
世の中ではあんまりメジャーじゃないものが岩手県民のお好みなのでしょうか
とても不思議なランキングです

2011年2月8日火曜日

FT2232HをPythonで使う

ストロベリーリナックスからFT2232Hを載せたUSB高速シリアル変換基板が発売されております.
FT2232H(2ch)高速USBシリアル変換モジュールキット
これは単純に言えば,パソコンから自作マイコンやFPGAボードなどに480Mbpsでデーターを簡単に送れてしまえるスグレモノなのです.
パソコン側のソフトを開発するためのライブラリなどはFTDI様が配っておられます.
FTDI CHip D2XX Driver Download site
筆者はこの頃,年をとったせいか開発中にコンパイラを起動するのがストレスになり,
単にアウトプットだけが問題なときやテストメインの時は,Pythonでお手軽に処理するのが最近の趣向なのです.
そこで上記のボードもPythonから使えるようにFTDI様のDLL用にctypesラッパーモジュールを書きました.
これを書いているほうが断然キーボードを叩く量が多い気が途中でしましたが,一度作れば480Mbpsの通信を
Pythonで制御できるので嬉しい気分となります.
ftd2xx-py.zip
スクリプトの中身は整理もなんにもしてなくて,コメントもありませんがご容赦下さい.

使い方は,例えばこんな感じです.32メガバイトを送信する例となっています.
from ftd2xx import *
handle = c_ulong()
ret=FT_Open(0, byref(handle))
ret=FT_SetBitMode(handle, c_ubyte(0xff), c_ubyte(0x0))
print "FT_SetBitmode=", ret
ret=FT_SetBaudRate(handle, 6000000)
print "FT_SetBaudRate=", ret
data = range(1024)*1024*32
ret=easy_write(handle, data)

2011年2月3日木曜日

健康食品

今週の週明けは,新幹線移動による日帰りでの出張からはじまった。
その日の盛岡の朝は,寒かったが晴れ渡った空に上る朝日がまぶしい。
きっとこの寒さは放射冷却現象という現象に違いないと思った.
以前はこの言葉を天気予報でよく聞いた気がするのだが、
このごろあまり聞かなくなったのではないか。
私は出張の時に、決まって乗る盛岡駅行きのバスには乗らずに、
青山駅まで徒歩で向かった。
途中の歩道は凍っていて転倒するかしないかは運みたいなものだ。

歩くと汗が心地よい。

体によいことをすると気持ちがくなるように
人間の体はできているのだと誰かに聞かされことがある。
しかし「体によい気持ちよさ」が得られる機会とは、
実に限られているものではないか。

たとえば,昨今、健康ブームもあってか
様々な健康食品が世にあふれている。
だが健康食品が体によいものであっても
直接的な心地良さを効能として体感できるものではない。
病気の際に飲む薬とは違って効果が見えないのだ。
健康が持続していることこそが健康食品の効果であると
いえるかもしれないがそれが、
直接的に影響したのかどうかはわからないのだ。

ここで前述の通り体によい事をしたときには
心地よさが得られるような体の仕組みが
実際に存在したと仮定しても、
健康食品にはそれが当てはまらないことは明白だ。
強いて健康食品を摂取したときに得られる
心地よさをあげるとするならば、
「おいしさ」や「はごたえ」といった味覚と食感のみである。

乏しい直接的効能にも関わらず高価な健康食品に人気があるのは、
カタログや説明書に書いてある効果が得られたという体験談や
毎日継続して飲んでいるのだからきっと効き目があるに違いないという
目には見えない働きを信じているのだ。
つまり期待感や自己満足と行った
心理的快感を得ているにすぎない。

現代人は理性や科学を信じたことによって、
理屈で説明が付かない事柄には関心がなくなったかといえば
このことからも違うことがわかる。
健康食品一つとってみても、
自分の体への有効性を確かめることもなく
高価な健康食品を信じて今日も食べるのだ。
健康食品のラベルやパンフレットには
体によい根拠が記載されているではないかという
主張が聞こえてきそうだが、実際にそれを検証した
客観的事実を確認しつつ飲んでいる人たちがどれだけいるだろうか。
コレステロールにいいとか、おなかにいいと言われていることがらを
有効成分の働きなどを交えて科学的に説明する広告を見て、
それが自分の体にも聞くに違いないと信じるから買うのだけど、
自分の体への有効性が保証されているわけではないのに
それを追求せず今日も健康食品を食べ続けるのだ。
医者からもらう薬でさえ、風邪をなかなかなおしてくれず、
時と場合によって効果があったりなかったりするというのに
自分用に特別に作られたものでもない「食べ物」や「飲み物」がなぜ、
個人間で異なる様々な体質の人間たちに
一様に有効であるといえるのだろうか。

それでも健康食品を買って飲むのだから、
それを動機づけしているものとは、
自分の健康が損なわれそうな可能性を恐れ、
健康食品のもつ目には見えない働きに、
自分を健康にしてくれるのではないかという
期待感であると思うのだ。

「実際に少しでもプラスならよいではないか」
そのような許容によって、私たちは
目に見える世界と見えない世界の狭間で
揺れ動く心のバランスを
保っているのではかなろうか。

2011年1月28日金曜日

pythonでctypesを使ったときにちょっと困った不可解なエラー

経験のないUSB機器をお手軽に試用するため、
久しぶりにpython+ctypesを試してみることにした。
長いこと使っていないと一度調べたことを再び
一から確認していかねばならなくなるので、
煩わしくて、せっかく適応可能な機会に恵まれても
使う気力は失せてしまう。
それでも、全く使わないですむかというと、
使ったときの快適感だけは鮮明に記憶されているので、
引っ張りだして使ってみたくなるのがpytho+ctypesだと
僕は思うのだ。
以前に書いたスクリプトとドキュメントを参考にしながら、
今回お世話になるDLLのヘッダファイルを見て、
ctypesラッパーを書いたのだけど、すぐにつまずいた。
正しく関数の引き数の指定しているにも関わらず、
引き数の数が合いませんとかいうエラーが出るのである。
エラーメッセージを頼りにしてGoogle先生に聞いてみたら、
DLLに組み込まれている関数のプロトタイプ宣言に
関係があるらしい。いわゆるstdlibとCDECLの違いだ。
簡潔に言えばstdlibは、Win32APIみたいなOSの
サービスコール的な関数をDLLに埋め込むときの規約で
CDECLは、C/C++でつくった関数を単純にDLL化したときに
適応される約束みたいなものだ。
話を元に戻すと自分が今回でくわしたエラーは、
stdcallで宣言された関数を呼び出すときに、
ctypesに対してそれはCDECL宣言の関数ですよと
謝った情報でDLLをオープンしていたかららしい。
DWORD testFunc(DWORD a, DWORD *b);
みたいなDLL関数をインポートするとき、次でエラーが出るような場合だ。
from ctypes import *
_lib_hoge=clib.LoadLibrary("hoge.dll")
testFunc=_lib_hoge.testFunc
testFunc=testFunc.args=[c_ulong, c_void_p]
bb=c_ulong()
ret=testFunc(10, byref(bb))
testFuncがstdcallな関数だった場合に、このスクリプトを
実行したときのエラーメッセージはこんな感じ。
"ValueError:Procedure called with not enough
argments (8 bytes missing) or wrong calling
convention"
一見,引数の数か型指定が間違っているだけとしか思えない.
でも正しい指定をしているから期待通りに動かない怒りは,
結果としてctypesに向けられることになるのだ.
エラー対策方法は,スクリプトの冒頭にあるDLL読み込みのところを
次のように改めればよい。
from ctypes import *
_lib_hoge=clib.LoadLibrary("hoge.dll")
testFunc=_lib_hoge.testFunc
testFunc=testFunc.args=[c_ulong, c_void_p]
bb=c_ulong()
ret=testFunc(10, byref(bb))
知っていれば些細な問題なんだけど、知らないとこれだけで
python+ctypesをあきらめてしまう要因になると思うのだ。

湯船につかりながらポメラでこの記事を書いているのだけど、
昨日やったばかりの作業やエラーメッセージを思い出せない。
日頃どれだけコピペに頼る生活をしているのか、
実感させられるのである。
2011/01/27 07:23

2011年1月23日日曜日

ソリの思い出

「東北小さな旅」は毎週土曜日の朝にNHKが
放送している東北地方限定ニュースのなかのコーナー。
その名の通り東北地方の各地を回り田舎の風景を
そこに住む人々の生活も交えて紹介していく番組だ。

毎週絶対見るのだと決めているわけではないのだけど、
土曜日の遅い朝に目が覚めてテレビをつけチャンネルを
ポチポチと切り替えると決まってこの番組に落ち着く。

今日の町は「秋田県にかほ市」
ちょうどテレビをつけたところで、
雪深い神社の境内に長く張り巡らされた階段を
女性レポーターが歩いているところだった。
階段には10cmほどの新雪があり
レポーターは長いブーツで雪を漕いで歩いていた。

雪と階段をテレビに見ながら僕は、
冬になると決まって思い出すソリの思い出を
反芻していた。

小学3年生まで僕は盛岡市青山4丁目にある
自衛隊官舎に住んでいた。
そこは運動公園の前にあり、雪が積もると
誰も来なくなる冬の運動公園に行っては
雪を漕いで歩いた。

あの頃は今に比べると盛岡も寒かった。
運動公園の中にある日本庭園の池も
カチガチに凍っていた。
学校から池の氷の上に乗らないように
注意されたが、1度くらいは
氷の上にのっかったような気がする。
高松の池でスケートをしていた頃だから
真冬ならなにが問題だと思うほど
ガッチリと堅く凍っていた。
今は絶対に無理だろう。

冬の運動公園へ遊びに出かけるときは
いつも後ろにプラスチック製の
青いソリをひいていた。
ソリの先端につけた白いビニールのヒモ、
確かピーピーテープと家では呼んでいたのだけど、
そのヒモを長めにソリに結んでおいて、
外に遊びに出かけるときは欠かさず引いていた。
夏は自転車、冬はソリが子供の乗り物だと
子供の僕は堅く信じていた。

一度だけ運動公園の中にあるスタジアムの西側の階段で
ソリ滑りをして遊んだ思い出がある。
スタジアムというのは運動公園の最北端にある
今改修している野球場のことだ。
このスタジアムの階段は、西側にあって観客用の
入り口に設置されているもので今も昔も変わっていない

ソリを引いた小学3年生の僕は、
このスタジアムにさしかかり、
この階段に心を奪われた。
階段の中程にある踊り場が
ジャンプ台となって
ソリのスリルを味わうには
よい場所に見えた。

そう思って僕は迷わず雪の積もって
上りにくい階段をソリを手にかけあがり、
そして滑った。

階段の踊り場は予想通りジャンプ台となって
ソリと僕を勢いよくはじきとばし、
回転しながら氷の地面にたたきつけた。
怪我をした記憶はないが、
僕の大事な青いソリの中程に
パックリと亀裂が入ってしまった。

親は壊れたからと言って易々と
買い換えてはくれないとあきらめていたので、
僕はこの階段の踊り場でソリ滑りをしたことを
とても後悔した。
それから何度もソリの亀裂をガムテープなどで
修理して滑ったが、雪の上を滑らせるとすぐに
テープは端からはがれ亀裂から雪が吹き込み
ソリは鉋のようになって止まるようになった。
だからソリ遊びはあきらめざるを得なくなった。

ソリが壊れた冬の雪が溶ける頃、
僕は父の転勤で幼少期を過ごした
思い出の多い盛岡を後にし、
北海道旭川市へと引っ越した。

それから28年たった今、自分は再び岩手に住んでいる。
毎朝の通勤時に運動公園横を車で通過する度に、
あの階段は、ソリの思い出と共に
僕は少年時代へとフラッシュバックさせられるのだ。

3年前、旭川に帰省した際、割れたソリが
家にまだあって冬に濡れた靴をストーブの前に
乾かすときに活躍していることを知った。
子供の頃の買い換えは無理だろうと
あきらめた事は正解だったと
これで証明されたような気がした。