2009/12/16

QtとC++に対するいろいろな思い

最近はよく翻訳の傍らGUIプログラミングについて勉強していて、QtとC++の組み合わせで作業しています。これに関してもいろいろと書いていきたいのですが、とりあえずこの2つについて雑感をてきとーに。
  • Qtは便利。あんまりオブジェクトの所有権や参照カウントなどを考えなくてもきちんとメモリ管理してくれる。deleteする必要があるのは親を指定せずに明示的にnewした場合とかだけ。
  • 文字列のエンコードに関して悩まなくなったこともグッド。
  • シグナルとスロット機構は従来のイベントドリブン形式よりも使いやすい。静的な言語なのに動的な機構を混ぜるなんて不思議なかんじ。
  • 後発のライブラリだけあって、やっぱり考え方は洗練されている印象。最近LGPLも可能になってより使いやすくなった。
  • 日本語の文献が殆どない。オライリー本は必須。
  • 時々意味不明のビルドエラーが出るときはmake cleanすると直ったりする(唯一の不満)。
  • C++の行数が多い。Qtのおかげでだいぶ削減されているけど、これで削減されているってどんだけー
  • もしMFCなんかで作業することを考えたら…おそろしやおそろしや
  • コンパイル速度が遅い。すごい遅い。これは自分のパソコンがヘタレなだけじゃない。C++が遅すぎるんだ。
  • アクセッサ関数を定義するのが面倒。_valを定義したらval()とsetVal()を定義しなきゃなんない。でも面倒ってだけでそんな悩んでない。
  • MyClass obj; みたいな文法でコンストラクタが呼び出されるのは怖い。気づかないところでエラー出る可能性がある。
    いや、禁止することはできるんだけど、いちいちそのコードを書かないといけない。普通こんな形で呼び出したい人いないでしょー
  • 参照にあまりエレガントさを感じない。だってあれポインタを隠蔽しただけじゃん。引数を変更禁止にしたいんだったらconstつければいいだけのような気がする。
  • リスト内表記使いたい。無名関数使いたい…これ使えればだいぶ行数減るのに
ということで、やっぱ整理してみたらQtにはあんまり不満はなくて、C++にはけっこうあることが判明しました。でも慣れれば不満は減っていくかもしれませんので、しばらくは続けていきたいと思います。

追記
  • λ式あるね
  • テンプレート、ジェネリック、メタプログラミングはもうすこし勉強する必要がありそう。C++は奥が深い

2009/11/26

今までにやったプロジェクト一覧

*この記事は随時更新していきます。トップメニューの"PROJECTS"からも参照することができます。*

この記事では今まで立ち上げてきたプロジェクトやソフトウェアの一覧をまとめてみます。

(08/02/13) After Effectsのエクスプレッションでパーティクルを表現するシリーズ

particle03SS
  1. After Effectsのエクスプレッションでパーティクルを表現する-01
  2. After Effectsのエクスプレッションでパーティクルを表現する-02
  3. After Effectsのエクスプレッションでパーティクルを表現する-03
After Effectsを弄ってたころの話。AEのパーティクルは貧弱!貧弱ぅ!でもParticularは高価!買えるかアホ!みたいな反動から作った記事。実はAEは今でも普通に使うので、もしかしたら書くかもしれません。

(08/08/30) Processing(Proce55ing)と流体力学


流体力学とProce55ingを組み合わせてみた記事。地味にお気に入り。今度やるんだったら粒子法とか取り入れて煙の挙動などをシミュレートさせてみたいです。

(08/09/20) エッシャーっぽい絵を生成する「エッシャーくん」を作ってみた。



一番人気が出たときの記事。やっぱり理系はエッシャーとか好きなんでしょうか。

(08/12/08) Picasaのウェブアルバムに写真を自動的に載せるpythonスクリプトを組んでみた。


イライラしたので作った。後悔はしていないです。

(09/03/20) MeCabを用いてスパムフィルタを作ってみよう


文字通りスパムフィルタを作ってみた記事。確かここらへんはベイズ理論の勉強にハマってて、その反動で作ってみた記事だったような気がします。

(09/07/15) Pythonistaのための2chライブラリ"twopy"


Pythonから2chを操作したくて作った簡易ライブラリ。何を作りたかったかっていうと…それはごにょごにょ

(09/10/04) 住所一覧からマックと吉野家の光の地図を作ってみたシリーズ

  1. 住所一覧からマックと吉野家の光の地図を作ってみた
  2. (追記)郵便局で作る日本全国の光の地図
Wiredの記事から触発されて作ってみた記事。こーゆうグラフって結構実用的な気がします。視覚的にわかりやすい。

(09/11/14) OMakeのマニュアルを日本語訳してみた


OMakeはとても便利なのにちゃんと使おうとすると英文読まなくちゃいけなくて、フラストレーションがたまって勢いで翻訳したプロジェクト。分量の多さにやって後悔。現在も鋭意制作中。

OMakeマニュアル 第9章翻訳完了.

OMakeマニュアル日本語訳の翻訳が第9章まで完了しました。

しかし長い。27000文字書いてようやっと1章終わるとか。でも一応早めに終わらせたいのでもう少しがんばります。

2009/11/19

サイトデザインを更新しました。


前のサイトデザインだとありきたりなんで他のサイトと被ってたりとか、横幅がちっちゃかったから思いっきりスクロールしなきゃなんなかったりで結構気になってたんです。ソースコードもあんまり載せられないですし。

というわけでサイトのデザインを更新しました。たぶんこっちのほうがいろいろと見やすいと思います。なんせ横幅がでかいですし。前のなんか2-30文字かいて改行レベルでしたから…

どうでもいいですけど、さあテンプレートを変えようということでBlogger Templatesっていうところに行ってみたんですが、皆なかなかクオリティ高くてビックリです。流石米国で流行っているBlogger。日本のごにょごにょなサイトとエラい違いです。

2009/11/17

OMakeでSphinxを自動継続ビルドしてみよう

題名通りです。Sphinxっていうドキュメント作成ツールがあって、これがなかなか簡単に作れる、かつ様々なフォーマットの書き出しに対応してるのですごく使いやすい。

Sphinxについて詳しく知りたい方は以下のURLを参照すればいいような気がします。

Pythonって何?という人のためのSphinxインストール入門

しかしSphinxには自動でプロジェクトのMakefileが生成されるので簡単にビルドできるようになっているんですけど、それでもhtmlファイルをrstファイルが変更される度に自動ビルドしてくれたらもっと便利になるのにとか思うのが人の常。

というわけで、前回の記事と絡めて、OMakeでSphinxを自動継続ビルドしてみようというのが今回の記事の目的です。

まずはOMakeのインストールから

まず、OMakeっていうのはGNU/BSDのmakeもどきみたいなソフトです。でも「もどき」っていうのは失礼で、従来のmakeとは比べ物にならないほど多くの機能を備えているソフトです。今回使う自動継続ビルドもOMakeの機能の一つです。

OMakeは標準では入っていないため、面倒くさいかもしれませんがOMakeをインストールする必要があります。とはいっても大抵のリポジトリに入っているので、

sudo apt-get install omake

の一行で完了します。Macは持っていないので分からないですが、恐らくportで十分いけるような気がします。

SphinxをOMakeに対応させる

次にSphinxのプロジェクトをOMakeに対応させます。まずプロジェクトの構成は以下のようなものとします。
  • Sphinxのビルドコマンドは"sphinx-build"
  • ビルドディレクトリは"_build"
  • A4用紙を使用する
  • ソースファイルはプロジェクトのルートディレクトリ
別にこれと全く同じじゃなくても勝手に変えればいい話なんですが…

それではOMakeのファイルをインストールしてみます。プロジェクトのルートディレクトリに移動してから、

omake --install

でインストール完了です。OMakerootとOMakefileという2つのファイルができたはずです。

ここでのOMakerootは別にいじらなくていいので無視します。それではOMakefileを改造してみます。

まず開くと変なコードが羅列してありますが、すべて削除。Makefileを開くと
# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
PAPER         =
BUILDDIR      = _build

# Internal variables.
PAPEROPT_a4     = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
とかいうhtmlを生成するコマンドがずらっと並んでいるので、その流儀に従ってOMakefileに以下を記述。
# OMakefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
PAPER         =
BUILDDIR      = _build

# Internal variables.
PAPEROPT_a4     = -D latex_paper_size=a4
ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_a4) $(SPHINXOPTS) .

SRCS = $(glob *.rst)

.DEFAULT: $(SRCS)
    $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html

ここで.DEFAULTの依存先にglob関数を用いてすべてのカレントディレクトリ以下のrstファイルを指定してるのがミソ。これで.DEFAULTターゲットの依存先はすべてのrstファイルになったので、このうちのどれかが変更されたら自動的にビルドが開始されるみたいな。

途中の変数を変更したのは、OMakeではその書き方が禁止されているためです。まーそりゃあそうかもしれません(makeの流儀なのかもしれないけど、自分は最初見たときキモいなーって思った)。

これだけでもうすべての手順は終わり。あとはルートディレクトリから継続監視ビルドの-Pオプションをつけて、

omake -P --verbose

を実行すればomakeが立ち上がり

$ omake -P --verbose
*** omake: reading OMakefiles
*** omake: finished reading OMakefiles (0.01 sec)
- build . <.DEFAULT>
+ sphinx-build -b html -d _build/doctrees -D latex_paper_size=a4 . _build/html
Running Sphinx v0.6.3
loading translations [ja]... done
loading pickled environment... done
building [html]: targets for 0 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
no targets are out of date.
- exit . <.DEFAULT>, 0.56 sec, code 0
*** omake: done (0.57 sec, 0/0 scans, 1/1 rules, 0/74 digests)
*** omake: polling for filesystem changes

と監視してくれるのが分かります。あとはてきとーにrstファイルを変更すれば、自動的にOMakeが変更されたことを感知して勝手にビルドしてくれます。いちいち変更する度にmake htmlなどと打たなくてとっても便利。まさに悦楽の境地。

というように、OMakeはこっちが楽できるような仕掛けを大量に用意してくれています。なにかと便利なので覚えると楽かもしれないです。

ついでに

今思うと「継続監視」っていう機能は別にビルド用途だけじゃなく、他のことにも使えるかもしれないです。例えばhtmlファイルを変更したり追加したら差分だけ勝手にアップロードしてくれるとか、グループ作業で他の人の沢山の画像ファイルを別フォルダで縮小しなきゃなんない(しかもそれが頻繁に変更される)場合とか。

グループ作業にありがちな「どれが変更されてどれが変更されてないのかごっちゃになってわかんねーよ!誰かリスト作ってくれリスト」みたいなのにも威力を発揮しそうな気がします(ていうか今がまさにそんな感じ)。

2009/11/14

OMakeのマニュアルを日本語訳してみた


はじめに

OMakeは従来のGNU/BSDのmakeに取って代わる、新しいビルドシステムです。自動的に依存関係を解析してビルドしてくれたり、変更点を監視して自動的にビルドを実行できたりするなど、一回知ったら従来のmakeを使いたくなくなるくらい強力なシステムを持っています(すんごいコード量が少なくなる)。
OMakeについての大雑把な説明は以下の記事を読むとわかりやすいと思います。
少なくとも、卒論とか研究とかでOCaml/C/C++/LaTeXを積極的にビルドする人にとっては、大分恩恵を受けるんじゃないでしょうか。

ですが、さあOMakeを使用してプロジェクトを作ろうとすると、どうしても日本語の文献というものがほとんどない。GNU/BSDのmakeは結構あるんですけど。
いや、オフィシャルに詳しい英語の説明が載ってるじゃん」って人もいるとは思います。そりゃあそうなんですけど、英語できるだけ読みたくないって人も(自分含めて)少なからずいるわけで、日本語の文献を充実させることは、少なくともマイナスにはならないはずです。

といったポリシーの元に、OMakeのマニュアルを日本語訳してみました。現在15章あるうちの8章まで翻訳してありますが、残りは殆どリファレンス的な存在なのでとりあえず以下のURLに公開してみます。

『OMake マニュアル 日本語訳』
http://omake-japanese.sourceforge.jp/

もちろん、残りの章も翻訳する予定です。たぶん翻訳の不備とかいろいろあると思うので、なにかありましたらメールなどで連絡おねがいします。

とりあえず翻訳してみて、OMakeはユーザーが望んでいる機能は大抵実現されているというか、これは現場で大分助かるんじゃないかなとか、そういう痒いところに手が届く孫の手みたいな言語なので、みんなとりあえず使ってみるといいとおもいます。べんりべんり。

あ、最近Goっていう新しい言語が注目されていますが、これを使えばGoでも継続監視ビルドを行えますし、誰かGo用のOMakefileを書くかもしれませんね。

各章の印象

ざっと翻訳した感じですと、2章3章はOMakeについてのガイダンスになっています。4から8章はOMakeの言語や仕様についてより詳しく書いてあります。9章以降は各関数や変数についてのリファレンスです。
とりあえずどんな感じなのか使ってみたいという方は2章、やる気があれば3章を読めばいいような気がします。OMakeについてより詳しく調べたい方は4章以降、といった感じでしょうか。

ソースファイル

ソースというほどではないのですが、翻訳に用いたSphinx(参考: 1日〜1週間でOSSに貢献する方法)用のドキュメントソースをSourceForge.JPのgitリポジトリにアップロードしました。

git clone git://git.sourceforge.jp/gitroot/omake-japanese/omake_trans.git

で参照できます。LaTeX用のドキュメントが欲しい方などはここから各自ビルドしてください。

心がけたこと

  • 逐語訳を避けて、できるだけわかりやすい表現に置き換えました。
  • かといって文が持つ本来の意味をなるべく崩さないようにも注意しました。
  • 用語の表現を統一しました。
  • あっちのマニュアルでは索引がなかったので、ついでに索引をつけました。
そんくらいでしょうか。とにかく今日は疲れました。なんせ量が半端無く多いー!!

2009/10/12

忘備録:cvCalibrateCamera2()について

これは完全に個人用のメモです。

OpenCVを使っていたときに次の記事を発見。

因果応報 | cvCalibrateCamera2関数

で、そこに世界座標系におけるカメラの位置と姿勢が数式で書いてあったんだけど、まだ3Dを始めたばっかりの自分は((なんで?))ってなった。で、考えて見た結果以下のような理由だという結論に至った。

まず、世界座標系 X = (X, Y, Z)T からカメラ座標系 x = (x, y, z)T に変換するためには4x4のカメラ行列を利用して以下の式で表現することができる:

ここで、Rは3x3の回転行列、tは3次元のベクトルとする。OpenCVのcvCalibrateCamera2()が返すRとtはこれ。

それじゃあカメラ座標系から世界座標系に変換するにはどうすればいいのよっていうと、逆行列を用いて以下のように表現できる:

つまり世界座標系におけるカメラの位置と姿勢を求めるためには、この逆行列を利用しなければならない、と。たぶんこんな感じかな…

2009/10/07

(追記)郵便局で作る日本全国の光の地図

これは前回の記事
住所一覧からマックと吉野家の光の地図を作ってみた
の続きです。今回はデータとして、郵便局の住所一覧を用いました。
また、データは『全国郵便局名一覧』からダウンロードしました。ありがとうございます。


















当たり前ですけど、郵便局はやっぱり多いですね。解析にまる3,4日くらいかかったような気がします。
しかも日本全国に散らばっているあたり、郵政事業がいかに重要なのか思い知らされます。

2009/10/04

住所一覧からマックと吉野家の光の地図を作ってみた

おひさしぶりです。

お久しぶりです。どうやら巷ではアクセスアップのコツとして「内容よりも一日の更新頻度を上げたほうが人気が出る」らしいですが、ここはそんなこと全く気にせずにのんびりと更新していきます。(かと言って質が高いかと言えば疑問ですが…)

さて、更新してみようと思い立ったきっかけはこんな記事からでした。
「マックまでの近さ」が光で表された米国地図 | WIRED JAPAN
この地図を作成したのは、Steven Von Worley氏。ロサンゼルス盆地の、本当に何もないようなところで目にしたマクドナルドに刺激されてこの地図の作成を思い立ったという。
で、ブックマークのコメントを見たらこんなものが。
はてなブックマーク - 「マックまでの近さ」が光で表された米国地図 | WIRED VISION
Layzie food, ネタ 東と西でクッキリ分れてるねえ。誰か、日本で「吉野家」バージョンで作らないだろうか。
やってみようじゃないの。

というわけでちょっとした思いつきで吉野家地図の日本版を作ってみました。ちなみに本家ではきちんと距離を計算してそこからの最短距離で色を作っているらしいですが、そんなことしても面倒くさい割にそんな役に立たないので単純な加算処理にしてあります。

工程は後述するとして、画像は以下。

これが吉野家の光…

東京や大阪、京都の大都市は吉野家が密集していることが伺えます。また各種国道や高速自動車道をなぞるように点在しているようですね(*1)。しかし海岸沿いなどにはほとんどなく、東北地方、特に札幌を除く北海道は悲惨です。これが地方格差ってやつか。

ついでにマクドナルドの地図も作って見ました。結果の画像は以下。

やっぱり吉野家と比べると明るいですね。でも吉野家の光の密度が多くなったような感じで、全体的な傾向としてはあまり変わらないような気がします。
ちなみに2つとも画像映えを良くするために少しのグロー効果も入れてあります。

メイキング

作った流れとしては以下のような感じです。
  1. まずマックのすべての店舗の住所一覧を取得する。
  2. 住所から経度と緯度のペアに変換する。
  3. Proce55ingにデータを読み込ませ、パーティクルとして処理する。
店舗一覧はマックの場合は47都道府県すべてを検索し、電話番号などの不要なデータを消去し住所だけを抜き出すpythonスクリプトを組んで対応。吉野家は件数が少ないのでコピペと手動で対応しました。

住所から経度、緯度のペアに変換する手順では、今回はGoogleのウェブAPIサービスを利用しました。住所のデータを投げればXML形式で返ってくるので、ペアから経度と緯度部分だけを抜きだし、csv形式で保存するスクリプトを組みました(*2)。

最後にProce55ingを用いてデータを読み込ませ、経度、緯度を単なるXY座標のデータとして処理させました。ただし、座標軸の違いによりこのままでは日本が上下反対になってしまうので、単純に-1をかけて反転させてあります。
あとは見やすいように座標変換を行って、完成です。

ソースコード

今回のスクリプトをcodereposのリポジトリ上にアップしました。
svn checkout http://svn.coderepos.org/share/lang/java/misc/light
でチェックアウトしてください。

外部ライブラリに依存していないので単純にproce55ingを使えば動くと思います。ついでにpythonスクリプトも同様にアップしてみました(trans.py)。参考までに。
ちなみに使い方ですが、座標が書いてあるCSVファイルを指定した後はProce55ing側が勝手に読み取ってプロットしてくれます。

ドラッグで見たい場所を移動できます(Google Mapsと同じ)。
'f'キーでズームイン、'g'キーでズームアウトを行います。マウスポインタを中心としてズームを行います。
'j'キーでパーティクルサイズを大きく、'h'キーでパーティクルサイズを小さくします。
's'キーでフレームを保存します。

(ズームして分かる、東京都のマックの様子)

'b'キーで日本地図(Thanks http://www.freemap.jp/)をバックに表示します。

まぁ、おまけ機能です。なんで位置合わせしないかというと、そこまでするときちんと経度、緯度を座標変換しなきゃなんなくて面倒だからです。

終わりに

作業時間としては大体3日間くらいかかりました。そんなに難しくありませんが、いろんな知識が複合的に絡んでいたのでそれなりに面白かったです。
ちなみに、郵便局バージョンでも作れないかと今住所一覧を経度、緯度に変換しているんですがこれ3万件くらいあってすごい時間かかるんですよね…現在2日間くらい回してるんですがまだ1万件しか処理できていません。できたらちゃんと報告します。

*1 個人的に、国道にはよく吉野家が点在しているイメージがあります。
*2 もちろんこのままではサーバに過負荷(単なるDoS攻撃になってしまう)がかかってしまうので5秒のスリープを入れてあります。

追記
typo ×吉野屋 ○吉野家 

2009/08/11

自転車盗難 その後

自転車が2週間くらい経っても一向に見つかる気配がなかったので新しい自転車を購入。
その翌日に自転車屋に行って、ギアの調整なんかをしてもらっている最中に電話が。受けとると警察からで、自転車が見つかったから早く引き取ってほしいとのことでした。

iPhone 3GS 買った


ホーム画面。デフォルトが一番綺麗と思っているので、特にカスタマイズはしていません。

最近猫も杓子もiPhone持ってるので別に珍しくないんですが、とりあえずiPhone買ってみました。
旧ボーダフォンのプランだったので、逆に切り替えたほうが安いことになるんですよね。前は月に8-10kくらいかかってましたし。

とりあえず数週間使ってみての感想としては、『パソコンをあまり使わない人は、持っている意味が殆どない』という感じです。
Googleカレンダーで予定を管理していたので、iPhoneとの同期はすごく役立ちますし、当たり前のようにGmailアカウントを追加できるのも便利。「産経新聞」アプリのおかげで新聞が気軽に読めるようになりましたし(*1)、「weathernews」で各地の天気も気軽、かつ詳細に調べられるようになりました。なぜ今までの携帯ができなかったのか不思議に思うくらいです。
逆にそういうサービスをまったく使わない人たちは特に買う利点は見当たらないので、ちゃんとした日本の携帯を買ったほうが幸せなような気がします。

キーボードについては長短あり。フリック入力だと入力が通常の携帯よりも早いのでとても便利なのですが、デバイス上結構ミスが連発するのでなんともいえません。早いけれどタイプミスでちょっとストレスがたまるようなかんじです。

jailbreakについては別にあまり重要でないから、やんなくてもいいのではという意見が多数を占めていますが、自分はむしろ逆だと思います。jailbreakしないiPhoneなんて初めっから完成されているプラモを買うようなもんです。

例えば辞書の追加。現状のiPhoneは単語の追加登録ができないです。そうなると追加するためには辞書のファイル(sys.dic)を直接いじることになります(*2)。これにはjailbreakと、最小限のコマンドライン知識が必要となってくるわけです。
linuxなどを使っている方ですと、iPhoneの中身はまんまunixで知識が流用できるので結構楽しいです(*3)。Open SSH入れて遠隔操作したり、通信を偽装して3G通信でskypeができるようになったり、vlcやmplayerを入れてflvの動画を再生できたりとか。インストーラのCydiaも.debパッケージを使っているので、リポジトリを追加して自由に自作のアプリケーションを承認なしで入れることもできます。

そーゆー抜け道が色々あるところが一番面白いんじゃないかなーと。
でも気をつけないと個人情報が駄々漏れになるんで、そこらへんは気をつけないといけないですね(特にOpenSSH関連)。

*1 自分は一番この「産経新聞」がキラーアプリなんじゃないかと思うほど気に入ってます。なんせ無料で新聞が読めるというところがデカい。
*2 別にいじんなくても他の方法はいくらでもあるんですが、どれもスマートじゃありません。
*3 iPhoneのハッカー文化がここまで大きくなった理由の一つだと思います。

2009/07/22

自転車が盗まれました

1時間くらい目を離していたらいつのまにか消えてしまいました。
バイクはぶっ壊れるし自転車は盗まれるし踏んだり蹴ったりでさすがにキツいです。

2009/07/18

クレジットカードと脆弱性

「クレジットマスター」か? VIPルーム宿泊男を逮捕 警視庁

他人のクレジットカード番号を割り出してインターネット決済し宿泊代金の支払いを免れたとして、警視庁と北海道警が電子計算機使用詐欺などの疑いで、指定暴力団山口組系元組員、瓜生誠被告(35)=覚せい剤取締法違反罪(使用)で起訴=を逮捕していたことが15日、同庁への取材で分かった。同庁などは、不正に入手した他人のIDとパスワードを使ったとして、14日に不正アクセス禁止法違反の疑いで追送検した。

眠れないのでとりあえず記事を更新することにしよう。

さてと、最近なんかクレジットマスター関連の犯罪が増えているような気がします。「クレジットマスター」自体はもう10年くらい前から登場している、古典的な手法らしいんですが、なんで最近になってこんなに頻出しているんでしょうか?謎です。

まず、世界中でよく使われているVISAのクレジットカードだと、桁数は16桁となっています。このままですととりうるカード番号の数は10^16通りであり、とてもじゃないですが実際に使われているカード番号にはたどり着けなさそうです。

ですが、実は全てのクレジットカード番号の最初の6桁は銀行のID番号になっていますので、容易に推測可能です。さらに最後の1桁はチェックサムであり、これも残りの数値から算出することが可能である*1)ため、16-7=9で残りは10^9通りとなりました。
この値が一体どれくらいの多さなのかというと、会員数が多いであろう三井住友VISAカードを例にとりますと、会員数は1641万人(平成20年3月末日)であるので、割合は0.01641。なんとランダムに数値を取っただけで100回につき1、2回は本物のカード番号に突き当たってしまうという計算になってしまいます。これはひどい。


(クレジットマスターの例。アルゴリズムは非常に簡単なので、こんな感じで容易にキージェネが作れてしまいます。一応問題ないとは思いますがモザイク入れておきますね。)

後の残る問題は有効期限なんですが、せいぜい3〜5年以内ですし試行はスクリプトなりなんなりを使えば容易に自動化できますから、1晩か2晩くらい回せばある程度の量の有効なクレジットナンバーが手に入りそうです。

まぁ名義が違ったら目をつけられますし、本物の住所を書くとすぐにお縄になってしまうので、容易さの割に非常にリスクが高い手法なんですが、自分が言いたいのはそんなことじゃなく、ここまで容易に割り出せてしまうクレジットカードの制度自体に問題があると思うのです。今時ナンバーと有効期限だけで認証が通ってしまうシステムってどうなのさっていう話で。

*1) どうやって算出するのかというと、『MOD10』アルゴリズムを用いて算出します。これについては他のサイトをご覧になったほうが容易に理解できると思います。このアルゴリズムの致命的な問題としては、残りの数値からチェックサムの値が一意に推測できてしまうという点でしょうか。これによって桁が1つ少なくできてしまうので。

2009/07/15

Pythonistaのための2chライブラリ"twopy"


"Beautiful Kuwait 2" by creativesam

概要

さて、実は以前からちょっと2chの文章を利用して、いろいろ弄くることができないかなぁとは思っていたんですが、残念な事に2ch用のpythonライブラリなんてマニアックなものは作っている人は誰もいない。
それじゃあ自分でなんとかしようの精神で作ってみようと。正直使う人が居るのかどうかは甚だ疑問なライブラリですが、損するわけじゃないので一応公開してみます。

というわけで、Pythonistaのための2chライブラリ"twopy"をリリースしました。
現在のところ単純なスレッド一覧の取得、スレッド上のコメント取得、コメント書き込みや新規スレッド機能に対応しておりますが、まだ完全に動作確認しているわけではないので使用は自己責任で。ちなみにライセンスはMITライセンスなんで、比較的自由に扱えると思います。改良はこれから始まる期末テストに飽きたらやると思います。

インストール方法

インストールに必要な環境は以下の通りです。
Python 2.5 or higher
2.6.2での環境で動作を確認。外部ライブラリに依存していないので、もしかしたらそれより前のヴァージョンでも動作するかもしれません。

インストール方法はCodeReposに上げておきますので、

$ svn checkout http://svn.coderepos.org/share/lang/python/twopy/trunk

なりなんなりでチェックアウトしてください。

簡単な使い方

スレッド一覧の取得
import twopy
b = twopy.Board("http://takeshima.2ch.net/news4vip/")
b.retrieve()

スレッドごとのタイトル、レス数、速度(res/h)を取得することができます。
for t in b:
print u"%s (%i) %.4f" % (t.title, t.res, t.velocity)

配列のように呼び出すことも可能です。
print b[0].title
print b[0].since


スレッドの内容の取得
t = b[0]
t.retrieve()

で一番上にあるスレッドの内容を取得します。
t = twopy.Thread(b, "1247375844.dat")
t = twopy.Thread.initWithURL("http://takeshima.2ch.net/test/read.cgi/news4vip/1247375844/")

として、datファイルあるいはURLから直接初期化することも可能です。

コメントを出力するには以下のようにループさせます。また、特定のコメントのみを取り出すこともできます。
for c in t: print c.render()
print t[1].render()

ただし、その場合の引数は実際のレス番号を指定する必要があります(0から始まるわけではない)。

コメントの抽出
特定のコメントのURLやレスポンスを抜き出すことができます。
for c in t: print c.extractResponses(returnType="comment")
for c in t: print c.extractUrls()

追記: 10/07/22
returnType引数は廃止され、メソッドとして分割されることになりました。
for c in t:
    print c.extractResponses()
    print c.extractResponsesAsInteger()
    print c.extractResponsesAsComment()

コメントの書き込み
特定のスレッドに対して、コメントを書き込むことができます。

t.post(name=u"", mailaddr=u"", message=u"")

ただし、2ch側の仕様により必ずしも書き込まれるとは限らず、確認が求められる場合がありますので、実際には以下のようにします。
r = t.post(name=u"", mailaddr=u"", message=u"")
if r[0] == twopy.STATUS_COOKIE:
    t.post(name=u"", mailaddr=u"", message=u"", hidden=r[2])

すべての確認作業を自動的に行うメソッドも存在します。

t.autopost(name=u"", mailaddr=u"", message=u"")

ただし、上2つのコードは2ch側の確認をユーザに見せることなく書き込みを行っていますので、実際にはユーザーに文章を見せてから、同意を行なわせる必要があるでしょう。

他にもスレッド作成機能などのいろいろ細々したのもありますが、それはソースコード見ればだいたい理解できると思います。行数そんな多くないですし。
もし正常に動かないなどのバグがありましたらご連絡お願いします。暇があれば対処したいと思います。それでは。

2009/07/14

ヤスオクと人間心理、上手い商売

新感覚オークション「ヤスオク」の仕組み - いぬビーム
http://d.hatena.ne.jp/kusigahama/20090713/1247446523

とりあえず何も読まずに開いて、どういうサイトなのか考えてみてください。

ヤスオク

内容は上の記事を読んでみれば分かるとして、なかなか上手い商売を考えつくものだなぁと思います。きな臭いとか、実際にやってみたいかどうかは別として。

さて、記事では胴元にとても有利なギャンブルとあります。それじゃあどれくらい有利なギャンブルであるのか、ちょっと確かめてみることにします。

まず、初めのオークション開始価格をS0、市場価格(この場合ですとamazonの価格ですね)をSm、入札単位金額をα、入札回数をn、入札手数料をpと定義すると、主催側の儲けは以下のように定式化できます。

Slastはオークションでの最終価格です。

逆に主催側の損失はSmだけです。これより、主催側の儲けと損失の和がちょうど0になるような入札回数n~は以下のような方程式を解けば算出できます。

これよりn~が求まったので、主催者が損しない最低限のラインである入札金額S~は以下のように求まります。

今回の場合ですとα=15、p=75、S0=0であるので、S~は

以上より、大体市場価格の17%くらいの価格を越えれば主催側は特をするわけです。言い換えれば83%オフの値段より落札価格が越えれば元がとれると。

このシステムの秀逸なところは、人間の価値関数を上手く利用している点にあります。プロスペクト理論によると、人間は損をすることを極端に嫌がります。そして殆どの場合、そのまま損失を認める選択肢を選ぶよりは、多少のリスクを背負ってでも損失を回避しようとする選択肢を選ぶわけです。今回の場合ですと75円損失して入札するというリスクを背負うわけですね。

それじゃあどうやって主催者を打ち負かせればいいのかというと実は簡単で、裏で話し合って誰も争うことなく次々と落札すればいいんです。いわゆる談合です。
ざっと利用規約を見た感じですと談合しないでくださいとは書いてありませんし、誰かやってくれないでしょうか(笑)

追記
typo ×ヤスログ ○ヤスオク
他、表記をより適切なものに修正致しました。

2009/06/17

Ubuntu環境でのOpenCVとffmpeg


"Chris Powell Ubuntu Tattoo" by Myles Braithwaite
(全然関係ないですが、わざわざ刺青まで彫るなんてよっぽどUbuntuが好きなんですねー)

Ubuntu環境でOpenCVという、画像処理用ライブラリをインストールする際にすんごく苦労しましたので、一応書いておこうと思います。

実は、OpenCVは通常のレポジトリからapt-getでインストールすることができるのですが、それだとビデオ機能が追加されておらず、このままではビデオ機能を使うことが出来ないのです。そのためソースコードを引っ張ってきてconfigure->make->make installの流れでインストールしなければならないのかーめんどくさいなーと思って調べてみたら、どうやらそれ以前にffmpegを追加しなければならないことが判明しまして、しょうがなくffmpegを野良ビルドした後にさあインストールだという感じでmakeしたら、どうしてもcvcap_ffmpeg.cppでエラーが出て止まってしまう。悔しいのでソースコードを書き換えるなりパッチ当てるなりで努力するも、悉くエラーが出て止まってしまうので、さてどうしようか諦めようかとか思っていた最中に、この記事を発見。

Getting video i/o working with opencv and Ubuntu Jaunty (9.04)

要は

$ sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com cafc44ee7f39098ce6ec229cca70e6a9087475a0

で鍵を入手して、
/etc/apt/sources.listに

deb http://ppa.launchpad.net/gijzelaar/opencv/ubuntu jaunty main

を追記。リポジトリを追加してインストールするだけでビデオ機能が追加されたOpenCVがインストールできますよという話なのでした(*1)。同じ環境で困っている方は試しにやってみてはいかがでしょうか。

それにしても…
I was disappointed, crying, screaming, running around angry and banging my head against the wall when the video i/o functionality stopped working when I updated to the latest Ubuntu release (Jaunty).
本当に自分もそんな気分になりましたよ。本当にOpenCVのビルドには多くの人が苦労されているようで…

余談

一応そんなわけで解決はしたのですが、自分の環境では

#include "highgui.h"
CvCapture *src;
src = cvCreateFileCapture("file.avi");

のようなコードを記述しますと"test.avi"が読み込まれずsrcがNULLになってしまいます。でもなぜかPython上ですと

>>> from opencv import highgui
>>> src = highgui.cvCreateFileCapture("file.avi")
>>> src
<Swig Object of type 'CvCapture *' at 0x9904420>

となって、正常に読み込まれているんですよねー…どうせ遊びにしか使いませんし、python+ctypesの組み合わせでもいいかなとか考えるようになってきましたよ。

*1) 今までのことはすべて無視して大丈夫です。みたいな

2009/05/14

東北大院生の自殺は決して対岸の火事じゃない


"Resume the suicide" by gfbpublez

東北大大学院生が自殺…博士論文、2年連続受け取り拒否され

東北大の理学研究科って…まんまうちの学部生が行くとこじゃないですか…
まさかこのまま順調に進めば進学するであろう大学院で自殺が起こるなんて。流石にショックです。

事件の内容はニュースに書いてある以上のことは知らないので、自分がいるキャンパスでの様子を書いていきますね。

まず東北大学理学部のキャンパス(青葉山キャンパス)っていうのは人里離れた山の上にあって、基本的に学生や大学院生はバスやバイクなどで通学します。5分くらい歩けば工学部のキャンパスに着くんですが、工学部に行くのはせいぜい図書館で珍しい本を借りることくらいしかないので殆ど行くことはありません。

そんな環境ですので、必然的に理学部の人間は山の上という隔離された空間の中で勉強にいそしむことになるわけです。大学院生でしたら泊まりがけの研究とかやることもあると思いますので、より環境的には隔離された状況なのかもしれません。自分はそれが嫌なので授業が終わったらさっさと山を降りて部活だのサークルだのやるようにしています。

で、今日のお昼休みでのこと。理学部の生協はいつものように理学部の学生と大学院生でごった返していたわけですが、テレビの前で学生がみんな微妙な表情で立ち止まっているんです。こんな状況は今まで見たことがなかったので、どうしたんだろうと思い自分もテレビの画面を覗き込んでみると、NHKニュースのテロップには東北大学院生自殺の文字が。
自分がこのショッキングなニュースを知ったのはこのときでした。殆どの学生もそうだと思います。風の噂ほども聞いたことがなかったので、もしかしたらその研究所には箝口令がしかれていたかもしれません。

各自テレビを見ながらいろんなを言葉を口走っています。
「勉強一筋の真面目ちゃんだったからこんなことで死にたくなるんじゃない?」とか、
「いや、自分も2年連続で受け取り拒否されたら死にたくなるかもしれない」
とかです。そのニュースが終わった後、学生たちは散らばって各自のテーブルで議論を飛ばしていました。

これは自分の異見なのですが、やはり理学部の研究室という非常に閉鎖的な環境だったからこそ起こった事件なのかなと思います。せめて他に論文を審査してくれる教授がいたのなら。合わなければ研究室を変えるという選択肢があったのなら。アカハラを行うクソ准教授を訴える場所があったのなら。こういう事態は起こらなかったかもしれません。

あーーーそれにしてもこの先どうしようーー理学部は就職先もないしーーーお先真っ暗だーーーー

2009/05/06

はじめてのミシェル・ゴンドリー(Michel Gondry)


久しぶりに映像関係の話題をば。

映像、特にPV関係が好きな方ならば、ミシェル・ゴンドリー(Michel Gondry)という名前を知っていると思います。フランスの映像作家で、世界的に有名なプロモーション・ビデオを多数発表している方ですね。

プロモーション・ビデオっていうのは大体尺が3〜4分と短いため、必然的に独創的なアイデアとか技術力をふんだんに生かした映像を作らなければなりません。それでなんですけど、このプロモーション・ビデオというのは以下の4つのカテゴリに分けることができると個人的には思っています。
  1. 作り方も分かるし、アイデアも容易に思いつきそうなやつ
  2. アイデアはなんとかなりそうだが、作り方がどうしてもわからないやつ
  3. 作り方は容易だが、逆立ちして考えても思いつきもしないやつ
  4. 作り方も、発想も全く思いつきすらしないやつ
もちろん下に行けば行くほどすごいPVです。
大体のPV(特に日本のPV)はこの1のカテゴリに当てはまる場合が多いんですが、ミシェル・ゴンドリーの作品のほとんどすべては3か4に当てはまります。常軌を逸しすぎている。たぶん自分は薬でもキメないかぎり一生かかっても思いつきすらしない気がします。
今回はそんな不思議PVを製作しているミシェル・ゴンドリー作品の紹介です。


まずこれ。すごいPVを挙げろと言われれば秒速でこのPVが挙げられるほど有名。これに至ってはどうやって作っているのかまず分からないし、撮影も相当大変そうです。CGとアイデアの見事な融合ですね。


おなじみケミカル・ブラザーズ。ミシェル・ゴンドリーが何者か分からなくてもこのPVは知っているという人はかなり多いはず。新幹線の車窓を見ると毎回このPVを思い出します。


1999年だから10年前のはずなんですけど、現在でも十分通用するほどスタイリッシュなPV。こいつ本当に薬キメてるんじゃないかと疑いたくなるようなキ○ガイ作品です(褒め言葉)

上の3つは超がつくほど有名なので、まだ見ていない方は見ても損はしないと思います。以下は個人的に好きなミシェル・ゴンドリー作品です。といっても基本的にミシェル・ゴンドリーは外れがないので、何見ても面白いです。いやホントに。


技術的にはそこまで大変そうではないですが、まず思いつかないです。シンプソンズのアニメでパロディされたほど有名な作品。


CG技術がなくてもアイデアがあれば十分面白い作品は作れるという好例。1997年の作品です。


きがくるっとる。一体これを作成するのにどれくらいの時間がかかってるんでしょうか…
(実際はCGも利用しているらしいですけれど)

2009/04/25

大学3年の理系が行った、Ubuntu 9.04 Jaunty Jackalopeのアップグレードとメンテナンス



4月から大学3年生になりました。授業の内容が本格的になってきて、しかも事故によってまだ取得できていない前のセメスターの単位があったりとかで、結構大変です。

さて、4/23にUbuntuの新しいヴァージョン9.04 Jaunty Jackalope(軽快なツノウサギ)が発表され、その次の日には日本語版のRemix CDがダウンロードできるようになりましたので、いままで使っていた8.10から9.04にアップグレードすることにしました。その際に、8.10でいろいろアプリケーションやライブラリをインストールしたことによる不都合を起こしていたので、心機一転して一旦パーティションを初期化した後にクリーンインストールを行うという手法をとりました。
9.04が発表されたときは結構盛り上がるかなと思ったんですが、あんまりそのことをブログで書いている人が少なかったので、今回は自分が行ったアップデート作業を書いていきたいと思います。

Ubuntuの環境整理

1.VGAドライバのインストール
これは自動的にUbuntu側が認識してインストールを促してくれるので、特に悩む必要はないです。インストールしたら再起動して、ドライバが正常にインストールされているかを確認します。

2.アップデート・マネージャでアップデートのインストール
今回の場合、9.04の発表直後だったので何もありませんでしたが、通常はここでアップデートを行ってシステムの内容を最新に保ちます。

3.「日本語環境セットアップ・ヘルパ」を使用して日本語環境を整える
インストールしたいソフトを選択して、インストールを行います。Flashのプラグイン、Adobe Reader日本語版、IPAモナーフォントは結構お世話になるので、入れておいた方がいいかもしれません。

4.システムのフォントをIPAモナーフォントからVLゴシックに変更
3.でIPAモナーフォントをインストールするとシステムのフォントが自動的にIPAモナーフォントに変更されてしまいます。これを元のVLゴシックに戻すためにはターミナルを立ち上げて
$ sudo gedit /etc/fonts/conf.d/69-language-selector-ja-jp.conf
と入力。sans-serifとmonospaceの欄を

<edit name="family" mode="prepend" binding="strong">
<string>VL Gothic</string>
<string>IPAMonaGothic</string>
<string>IPAGothic</string>
<string>Sazanami Gothic</string>
<string>Kochi Gothic</string>
</edit>

のようにVL Gothicを先頭にもっていく。保存するとシステムのフォントとしてVLゴシックが使われるようになります。

5.システムの警告音をミュートにする
キーボードの打ち間違えでシステムのビープ音がいちいち鳴るのはとっても鬱々しいので、鳴らないように変更します。ターミナルを立ち上げて
$ sudo rmmod pcspkr
を入力。再起動後も鳴らないようにするには
$ sudo gedit /etc/modprobe.d/blacklist.conf
を入力。末尾に
blacklist pcspkr
を加えて保存します。

6.ホームフォルダの各フォルダを英語表記に直す
日本語でもいいんですが、ターミナルを使うといちいち日本語でフォルダを指定するのがめんどくさいので、英語表記に直します。ターミナル上から
$ LANG=C xdg-user-dirs-gtk-update
で英語表記に変更されます。再起動後はこの名前でいいのか聞かれるので、べつにいいよという感じのボタン(どんなんだったか忘れた)を押して英語表記のままにします。

以下の内容は各種ソフトやライブラリのインストールです。この操作はSynaptic上でも行えます。

7.各種コーデックのインストール、メディア環境を整える
各種コーデックをインストールして、メディア環境を整えます。ターミナル上から
$ sudo apt-get install ubuntu-restricted-extras
でインストールを行います。
ついでに動画鑑賞の定番であるvlcもインストール。
$ sudo apt-get install vlc
で簡単にインストールが行えます。

8.Nautilusの拡張
sudo apt-get install nautilus-gksu nautilus-open-terminal

9.日本語のLaTeX環境を整える
理系必須のLaTeX環境を整えます。「Ubuntu 8.10 Intrepid Ibex で 日本語 LaTeX 環境を整えてみよう」を参考にインストールを行います。
ついでにLaTeXのコンパイルが劇的に楽になるOMake(参考:OMake つかって LaTeX コンパイルしたら簡単すぎて身長が5cm伸びた)も同時にインストール。
$ sudo apt-get install omake
とっても簡単ですね。

10.各種計算ソフトのインストール
個人的によく使うライブラリやソフトをインストールします。
$ sudo apt-get install python-scipy python-matplotlib wxmaxima gnuplot r-base

所要時間にして約2時間。結構早く終わりました。Windowsだとあと2,3時間はかかるかもしれません。

まとめ

Ubuntuは初心者に優しいとかコマンド入力しなくてもいいとか言われていますがそれは全くの嘘で、ちょっとこみいったことをしようとすると依然としてターミナル上からの操作が必要とされます。
でも慣れればwindowsよりも保守管理がしやすいのは確か(apt-getで一括してすべてのソフトのアップグレード、インストール、アンインストールが行える)ですし、なにより理系がよく使うgnuplotやRが楽にインストールできるところがうれしいです。操作性もwindows上でインストールするよりたぶん数倍使いやすいと思うので、理系の方はUbuntuを試してみるという選択肢もありだと思います(べつにFedoraでもいいと思うけど)。

2009/04/12

辞書と組み合わせと再帰関数


Photo by joka2000, Double-flowered Cherry Blossoms

辞書が与えられて、そのキーと値の群の中でタプルやリストを持っている値を、任意の値で組み合わせたリストを返すという処理はどう実装すべきか悩んでいました。
言葉にすると難しく聞こえますが、要は
{"a":(1,2), "b":4, "c":(3,4)}という辞書が与えられた場合、返すリストは
[{"a":1, "b":4, "c":3},
{"a":1, "b":4, "c":4},
{"a":2, "b":4, "c":3},
{"a":2, "b":4, "c":4}]
となるわけです。

通常の行列のような処理は単純にループを2回回せばいいわけですが、今回の問題の場合ループ回数は変動するわけで、単純にループを回すわけにはいかない。どうすればいいのかちょっと考えて見たら、再帰関数を使えば案外スマートに実装できそうな気がしたので、実際にやってみました。


from copy import copy

def makeKwargsList(kwargs, exceptions=[]):
"""
タプルやリストを含んだ辞書から、それらの値を含む任意の組み合わせを
すべてリストとして返します.
例:
kwargs = {"a":(1,2), "b":3, "c":(True,False), "d":(1,2)}
exceptions = "d"の場合、返される辞書のリストは、
[{"a":1, "b":3, "c":True, "d":(1,2)},
{"a":1, "b":3, "c":False, "d":(1,2)},
{"a":2, "b":3, "c":True, "d":(1,2)},
{"a":2, "b":3, "c":False, "d":(1,2)}] となります.

kwargs : タプルやリストを含んだ辞書
exceptions : 組み合わせとして出力してほしくないキーのリスト
"""
if type(kwargs) != dict: raise TypeError
# キーワードの抽出
kwdict = {}
base = {}
for (key, value) in kwargs.items():
if (type(value) == list or type(value) == tuple) and \
(key not in exceptions):
kwdict[key] = value
else: base[key] = value
# key, kw の分離
keys = kwdict.keys()
values = kwdict.values()
kwargs_list = []
__makeKw(values, [], kwargs_list)
# 結合
r = [dict(zip(base.keys() + keys, base.values() + ag)) for ag in kwargs_list]
return r

def __makeKw(kwlist=[], base=[], kwargs_list=[]):
argslist = kwlist[0]
if len(kwlist) > 1:
newKwlist = kwlist[1:]
for kw in argslist:
new_base = copy(base)
new_base.append(kw)
__makeKw(newKwlist, new_base, kwargs_list)
else:
for kw in argslist:
new_base = copy(base)
new_base.append(kw)
kwargs_list.append(new_base)

__makeKw()が再帰関数で、この場合[(1,2),(3,4)]のリストから、[[1,3], [1,4], [2,3], [2,4]]をkwargs_listに代入させていく関数となっています。

本来のプログラマがどうやってこのようなアルゴリズムを組んでいるのかは残念ながら勉強不足で分かりませんが、とりあえずきちんと動作しますし、そこまで速度が重要となるような処理ではないですので(せいぜい100〜10000程度)、べつにこれでいいかなと。

それにしても、1年前は思いつかずに挫折していたであろうアルゴリズムが実際に組めるようになってくると、ちょっと成長している感がありますね。

2009/03/20

MeCabを用いてスパムフィルタを作ってみよう


Photo by vsz, night glow

以前このブログでMeCabによる形態素解析を紹介しました。正直その後すっかり取り上げたことを忘れてのほほんと過ごしていたわけです(*1)が、ふとしたことでベイジアンフィルタに関するアルゴリズムの記事を見つけ、日本語でこのような記事があるなんて珍しいなということで、ちょっくら実装してみようと思い立ったわけです。

形態素解析部分はMeCabくんがやってくれるので、こっちがするのは名詞を抜き出してデータベース辞書を作り、Graham方式を用いて実装したくらいです。正直ただ単純に実装しただけなのでそこまで参考にならないと思いますが、一応coderepos上に公開してみます。

svn checkout http://svn.coderepos.org/share/lang/python/spam Somewhere

でチェックアウトしてください。

テストにつきましては正直自分のメールアドレスにスパムが届かなかったので(*2)、『Google ニュース』を使って『政治』分野をスパム、『スポーツ』分野を非スパム文章として40件サンプルを手作業で作り(*3)、2つのセンテンス

大阪府の橋下徹知事が進める、府庁を大阪市の第三セクター「大阪ワールドトレードセンタービルディング」(WTC)に移転する構想について、公明党府議団は19日、「原案には賛成できない」として府議会で審議中の移転関連予算案と条例案に反対する方針を決めた。 公明党は自民党とともに知事与党の立場だが「議会として十分な議論ができていない。あまりに拙速だ」としている。条例案の可決には出席議員の3分の2以上の賛成が必要で、原案通りの可決は極めて厳しい状況となった。橋下知事は同日、高齢の障害者らの医療費自己負担を引き上げる案などを、議会側の求めに応じて修正する意向を議会側に伝達。府庁移転問題の好転を図る狙いがあるとみられるが、先行きは不透明だ。橋下知事は、府議会総務常任委員会であらためて移転への意欲を示し、記者団に「(反対は)公明の政治的決断。自民、民主、諸派に納得していただくよう精いっぱい頑張る。可能性はゼロではない」と述べた。

フィギュアスケートの金妍児(キムヨナ)(韓国)が過去の国際大会の練習中、日本選手に進路を妨害されたなどとする韓国メディアの報道について、日本スケート連盟は19日、韓国スケート連盟に対し、報道内容についての調査を求める要望書を提出した。また、国際スケート連合(ISU)に対しても同日、報道への見解を問う文書を提出した。日本スケート連盟によると、韓国側からの直接の抗議や、ISUからの警告はこれまでないという。同連盟の常山正雄専務理事は「日本選手が意図的に妨害した事実はなく、今回の報道には大変困惑しているし、遺憾」としている。


がきちんと判定されているか確かめました。これらの記事を選んだ深い理由は得にないです。
結果は、

$ python test.py
センテンス1がスパムである確率 : 1.0
センテンス2がスパムである確率 : 6.07068879794e-100
スパム文章のサンプル数 : 20
非スパム文章のサンプル数 : 20
スパム辞書が学習した単語数 : 1040
非スパム辞書が学習した単語数 : 854

大体大丈夫そうです。よかったよかった。

学んだこと

  • ベイズ理論を用いたフィルタリングは結構面倒かと思ってましたが、意外と楽でした。まぁ面倒な部分はMeCabがやってくれたっていうのもあるんでしょうけど。
  • pythonのreduce()はとてもエレガントに扱えて便利。たった一行ですむっていうのは気分いいですね。
  • どうでもいいですけどフレッシュネスバーガーのスパムバーガーはおいしいのでお勧めです。

うーんおいしそう!明日食べに行ってきます。

*1 どれくらい忘れていたかというと、"MeCab python"で検索したら自分の記事がトップに出て、「そんなん書いたっけ?」と驚いたくらい。自分の欠点は熱しやすく冷めやすいところだと思う
*2 出会い系とかに登録していればたくさん来ていたかもしれない
*3 本来は4000件くらい作るらしいんですが、さすがに勘弁してください

追記

Robinson方式も扱えるようにレポジトリを更新しました。Robinson方式は未知の単語が出てきた際に、Graham方式よりも適切に判定が行えるアルゴリズムです。

$ python test.py
=====Graham方式による判定=====
センテンス1がスパムである確率 : 1.0
センテンス2がスパムである確率 : 6.07068879794e-100
=====Robinson方式による判定=====
センテンス1がスパムである確率 : 0.999957539928
センテンス2がスパムである確率 : 0.0234555720353
=====辞書に関する情報=====
スパム文章のサンプル数 : 20
非スパム文章のサンプル数 : 20
スパム辞書が学習した単語数 : 1040
非スパム辞書が学習した単語数 : 854

Robinson方式に対応させるために逆カイ二乗関数が必要になったので、今回はchi2pモジュール(http://garyrob.blogs.com/chi2p.py)を利用することにしました。chi2pモジュールはMIT Licenseの元で配布されています。

2009/03/05

PyBrain - a modular Machine Learning Library for Python


今、python界でPyBrainが熱い!…わけじゃないですけど、個人的にけっこう注目しているライブラリ。機械学習ライブラリにおける、期待の新人が出てきなような気持ちです。

0.PyBrainとは?

PyBrainっていうのはPythonによって動く、モジュール式の機械学習ライブラリです。python界ではいままでにもニューラルネットワークとかSVMなどを扱うライブラリが存在していましたが、PyBrainではそれらをより包括的に扱う、一種の環境としての機械学習ライブラリを目指しているようです。
PyBrainが優れているのはその思想もさることながら、扱っているアルゴリズムの多さにもあります。例えばFeaturesの欄を見てみると、
  • Backprop
  • Rprop
  • Policy Gradients
  • Support Vector Machines
  • Evolution Strategies
  • CMA-ES
  • Competitive Coevolution
  • Natural ES
  • Natural Actor-Critic
  • Reward-weighted regression
  • Evolino
  • Fitness Expectation Maximization
  • SPLA
  • PCA/pPCA
  • LSH for Hamming and Euclidean Spaces
と、比較的新しいアルゴリズムについても対応する予定のよう。(リファレンスをざっと見ると、まだ対応していないアルゴリズムはけっこう多いようです)とりあえずアルゴリズムについて確認したり、テストとして組んでみる分には申し分ない仕様です。

1.ダウンロード〜インストールまで

まず、PyBrainでは以下のツールが必要となるので、足りない場合は適宜apt-getやらeasy_installやらでインストールを行います。
  • g++
  • scipy
  • matplotlib
ちなみにホームページには書かれていませんが、自分はビルドした際にcblasが足りないと怒られてしまったので、ついでにそれもインストールします。
次に、PyBrainのサイトにアクセスして、Stable versionのソースコードを入手。圧縮ファイルを展開します。

~$ cd PyBrain-0.2
~/PyBrain-0.2$ ls
LICENSE arac docs examples pybrain setup.py

setuptoolsの慣例通りにビルド。

~/PyBrain-0.2$ sudo python setup.py build
arac/src/c/layers/common.c: In function ‘void make_layer(Layer*, int, int)’:
arac/src/c/layers/common.c:12: error: ‘malloc’ was not declared in this scope
arac/src/c/layers/common.c: In function ‘Layer* make_layer(int, int)’:
arac/src/c/layers/common.c:40: error: ‘malloc’ was not declared in this scope
Traceback (most recent call last):
File "setup.py", line 87, in <module>
compileArac()
File "setup.py", line 74, in compileArac
extra_postargs=['-O3', '-g0', '-DNDEBUG'])
File "/usr/lib/python2.6/distutils/ccompiler.py", line 697, in compile
self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
File "/usr/lib/python2.6/distutils/unixccompiler.py", line 180, in _compile
raise CompileError, msg
distutils.errors.CompileError: command 'g++' failed with exit status 1

怒られてしまいました。どうやらmallocが定義されていないみたいなので、暫定的な処置として"arac/src/c/common.h"に以下の文を付け加えます。

#include <stdlib.h>

再度ビルドを行うと、ビルドがうまくいったみたいです。

~/PyBrain-0.2$ sudo python setup.py install

でインストール。無事インストールが完了しました。
正常に動くかどうか確かめてみます。

~/PyBrain-0.2$ python
Python 2.6.1+ (r261:67515, Feb 24 2009, 20:00:00)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pybrain
>>>

何事もなくインポートすることができました。

2.試しに使ってみる〜ニューラルネットワークの構築から学習

Pybrainのチュートリアル通りに、単純なFeed Forward型のニューラルネットワークを組んでみます。Pybrainではレイヤを個別に定義し、それらを繋げてネットワークを構成することもできるみたいですが、もっと簡単にネットワークを構成できるショートカットがあるみたいですので、それを利用します。

from pybrain.tools.shortcuts import buildNetwork
net = buildNetwork(2, 3, 1)


これで2つのインプット、3つの隠れユニット、1つのアウトプットから成るニューラルネットワークが出来上がりました。とても簡単ですね。
入力したインプットからアウトプットを出すには、activate()メソッドを用います。

net.activate([2,1])

buildNetworkの時点で各ニューロンはランダムな数値で初期化されていますので、既にactivate()ができる環境になっています。

ちなみに通常、各ニューロンに用いられる活性化関数はシグモイド関数が用いられますが、違う関数を用いたい場合は適宜指定することができるみたいです。まぁ好みの問題ですね。

from pybrain.structure import SoftmaxLayer
from pybrain.structure import TanhLayer
net = buildNetwork(2, 3, 1, hiddenclass=TanhLayer, outclass=SoftmaxLayer)


次に、教師あり学習を行うためにデータセットを用意しておきます。

from pybrain.datasets import SupervisedDataSet
ds = SupervisedDataSet(2, 1)
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))


こんな感じでインプットとアウトプットのサンプルを増やしていきます。
そして、構成されたネットワークに誤差逆伝播法で学習を行わせるため、trainerを作成します。

from pybrain.supervised.trainers import BackpropTrainer
trainer = BackpropTrainer(net, ds)
trainer.train()


train()メソッドは返り値として誤り率を返しますが、もしある一定の割合に収束するまで学習を行わせたい場合、trainUntilConvergence()メソッドが有効です。そのまんまですね。

trainer.trainUntilConvergence(validationProportion=0.25)

だいたいニューラルネットワークの構築方法としてはそんな感じですが、他にもSVMを選択することもできるようです。詳しいことはPyBrainのドキュメントを参照してください。

3.使ってみて

とりあえずざっと使ってみた感想ですが、非常に組みやすく、かゆいところに手が届くような設計がなされているライブラリだと思います。まだバージョンは0.2ですし未完成な感じは否めないですけれど、将来が非常に楽しみなライブラリです。(しかも名前がカッコいい!!)

2009/02/12

Ambient Occlusion with Python


前々からやってみたかった、syoyoさんのAO benchでのコードをPython用に移植させてみました。上の画像はその出力結果です。ちなみに、出力を楽にするためにPython Imaging Library(PIL)を利用しています。

なんで前々からやってみたかったかというと、3Dでのレンダリングアルゴリズムの学習がしたかったから。ray tracing法やらAmbient Occlusionなどの手法は頭の中では分かってましたが、実際にどうやって動かしているのかは全然分かんなかったですから…今回の移植を通して、レンダラの実際の動きが少しだけですが掴めたような気がします。

それで気になる速度はというと、

  • サブサンプリング数:2
  • AOのサンプル数:8
  • 画像の長さと高さ:256px

という標準的な設定でレンダリングしたところ、
$ python sample.py
time:463.692063 sec
という結果が出ました(AMD Athlon 64 x2 3800+)。

まぁPythonですから大体予想してた通りの結果となりましたが、それにしてもものっそい遅いです。C言語での2.6secという結果を比べてみると、環境が違いますからそのまま評価することはできないんですがだいたい180倍くらい時間かかってます。もう少しなんとかできなかったかなー…

2009/02/11

退院しました

12月18日にバイクを運転していたら車にはねられましてそのまま救急車で病院に直行、1月31日まで約1ヵ月半ちょいの入院生活を送っていました。病名(というのかどうか分かりませんが)は両足の骨折(そのうち左足は開放骨折)で、あと骨盤にヒビと脳にも多少の出血があるそうです。

それにしても1ヶ月半でこれだけの怪我をして退院できたのはある意味幸運でした。その理由っていうのは今考えてみると
  • 衝突時自分が上に飛んでいったこと(下にいくとタイヤに巻き込まれてもっと大変だった)
  • ヘルメットがフルフェイスだったこと(顔が削れるとか洒落にならない)
  • 加害者がひき逃げしないですぐに通報してくれたこと
こんな感じかなぁと思うのです。脳みそがやられなかったのが一番デカいですね。脳に障害が出てしまったらもう大学にいられなくなりますから…

これからしばらくは松葉杖生活で外に出られない状態が続くので、ブログの更新も積極的に行っていきます。(あと追試の勉強も平行してやんないと…)

2009/01/06

事故にあったのでしばらく休みます

題名通りです。交通事故で車と衝突して現在入院中ですので、しばらく完治するまで休みます。

生きててよかった。