コンピュータの性能向上にともない、最終的な実行速度よりも開発効率を重視するというトレンドが生まれた。研究者は短時間でアルゴリズムを実装して実験する必要があり、自然とAI分野ではRやMATLAB、Pythonなどの動的で高水準な言語に人気が集まった。これらは基本的には逐次実行のスクリプト言語であり、実行速度は遅い。これに対する戦略として、これらの言語では外部の数値計算ライブラリを呼び出す何らかの方法を持っている。具体的には、計算処理をある程度まとまった単位にまとめて、Cなどの低水準言語で書かれた数値計算ライブラリにまるごと送り出す。ループでやるような処理をベクトルに対するマップ操作として記述するとか、ベクトルの計算ならば、小単位のバッチ処理にまとめて行列の演算に置き換えてから外部ライブラリに渡すなどのテクニックを用いることになる。いつでもこれができるとは限らない。リアルタイムのオンライン処理には向かないし、そもそも逐次処理を必要とする学習アルゴリズムでは使えない。いう場合は結局Cなどで書いてコンパイルしたものを呼び出す必要がある。なってくると、実行速度を出すためにアルゴリズムの選択やプログラミングスタイルに制約がかかることになり、本末転倒ということになりかねない。Lispは数値計算に向いているもともとLispの特徴として、柔軟で強力な抽象化機構を持ち、時としてプログラマ自身が構文すら自由に拡張できる高水準言語だということがあった。LispにはSBCLなどのオープンソースの高品質なネイティブコンパイラがあり、Cで書かれたライブラリに簡単にアクセスできる仕組みCFFIがある。最近ではインターネットからライブラリをダウンロード、インストール、ロードまでを一貫してこなすライブラリ管理システムQuicklispや、処理系のバージョンを管理したりデプロイを行なえるツールRoswellなども出てきて、いよいよ便利になりつつある。一部ではLispはスクリプト言語で遅くて数値計算には向かないというイメージがあるようだが、SBCLなどはJIT(AOTでした)コンパイラであるし、現在ではコンパイル型言語の中でもむしろ速い部類に入る。この話題の概要としては、Gauche作者のshiroさんのエントリがとても分かりやすかった。Lispが速いのは、動的言語にも関わらず、最適化宣言と型宣言をオプションとして付けることができるためだ。LispコンパイラはCとほぼ同等のネイティブコードを吐き出す。これらの宣言はあらゆるレベルで付けることができるので、関数単位、ブロック単位で、本当に必要な部分にのみ集中して最適化することができる。してそのようなボトルネックはプログラム全体のごく一部にすぎない。Lisp処理系には、プロファイラという、プログラムのどこの部分に計算時間が割かれているかを調べるツールが付いており、ボトルネックを探すのに役に立つ。コンパイルした関数を個別にディスアセンブルすることもできる。アセンブリコードを見ることによって、実行時の型変換がどこで起こっているかや、メモリアロケーションがどこで発生しているかなどが分かるので、これもチューニングの手掛かりになる。Lispの開発サイクルは以下のようになる。付けてコンパイルディスアセンブルしてネイティブコードを見ながら最適化これら全てが開発環境の中から出ることなく、対話的に行うことができる。これにより開発サイクルが短く、試行錯誤できる回数が多くなり、結果として最適なアルゴリズムを見つけ出すチャンスが増える。LispでCよりも速いコードが書ける」というのは、最高速度のことというよりは、この開発サイクル自体の効率性が高いことを示している。Lispで書くより速いって人がいたら、それは彼のCの技量が高すぎるってことだね。Lispはそれ自体で速いとはいえ、巨大な行列同士の掛け算のように、マルチコアCPUやGPUの性能を極限まで引き出したいときには外部ライブラリに頼ることになる。CFFI経由で比較的簡単にCの共有ライブラリから関数を呼ぶことができるが、主な数値計算ライブラリにはラッパーライブラリが存在する。MKLやOpenBLASのラッパーライブラリとしてはLLAがあり、CUDAによる行列計算のラッパーライブラリとしてはMGL-MATがある。Lispの方が若干速くなる。Lispのみを使うという選択肢も取れるようになる。することでアプリケーションとして配布するときの外部の依存ライブラリを減らし移植性を増すことができる。Lispの機械学習ライブラリは数はあまり無いものの、重要なところは抑えているような気がする。https://github.com/mmaul/clmlもともと数理システムで開発されていた機械学習アルゴリズムのコレクションだが、今は別の方によってメンテナンスされている。システム定義がASDFに直され、インストールが簡単になった。https://github.com/masatoi/clml-svmCLMLからSVMだけ抜いたもの。https://github.com/melisgl/mgl2014年のKaggleの機械学習コンペ優勝者によるディープラーニングの実装でCUDAに対応している。https://github.com/masatoi/cl-online-learning自作の線形分類器のコレクション。AROW++やLIBLINEARより速いし精度も出るのでオススメ。実装アルゴリズムパーセプトロン、ロジスティック回帰+ADAM、AROW、SCWなど。二値分類、マルチクラス分類(1vs1、1vsRest)データは密ベクトル、疎ベクトル両対応。https://github.com/masatoi/cl-random-forest自作のランダムフォレストの実装。ランダムフォレスト学習後に線形分類器により再学習させることでより性能を伸ばす手法を実装している。Processing)から来ているという話がある*2:一応、PythonであればCythonなどのネイティブコードにコンパイルする仕組みもある。*3:例えば、新たにオブジェクトを生成して返すようなコードは、結果受取り用の変数を引数として与えてそれに代入させればメモリアロケーションは発生せず、ガベージコレクションの時間を削減できる。Lispから使える形態素解析器で、辞書にはmecab互換の辞書が使える。masatoi/cl-igoでインストールできる。SBCL推奨とのこと。EUC-JPでipadicというディレクトリができている。~/igo/ipadicにでも置いておくとする。"庭には二羽にわとりがいる。"記号,句点,*,*,*,*,。