2015年3月29日日曜日

Pythonで2次元配列を初期化するときのアレ

備忘録として。

Web上でよく見かける、Pythonで2次元配列を初期化する際のtipsは以下のようなものかと思います。

# N x M.
# ダメな例
ng_list = [[0]*M]*N

# 良い例
ok_list = [[0 for j in range(M)] for i in range(N)]

2次元以上にも応用が効くので全く問題ないのですが、推奨されている方も内包表記がネストしていてなんとなくモヤっとします。
てことで思いついた記法を試したら問題なさそうだったので、一応晒しておきます。
ツッコミ歓迎なので、気になる点がありましたらご指摘ください。

# N x M.
my_list = [[0] * M for i in range(N)]

2015年3月22日日曜日

別サーバにあるJenkinsジョブと連携するスクリプト書いた

タイトルの通り、別サーバにあるJenkins間でジョブを連携させるスクリプトを勉強がてら書いたので、ことのついでに晒してみます。

ソースはgist(syncbuild_remote_jenkins.py)にあります。
動作環境などは↓のような感じ。
  • python2.7で動作確認済み
    • 3.x系では動きません
  • 基本的に標準のライブラリだけで動く(はず)
    • 自由にpip install出来ない環境では重宝するかも
使い方としては、任意のホスト、ポート、ジョブ名を指定する感じです。
$ ./syncbuild_remote_jenkins.py --host remote-jenkins-server --job RemoteJobName --interval 300

ちなみに、intervalオプションでジョブの状態をポーリングする間隔を変えられるようにしています。(上記の例だと300秒)
時間のかかるジョブであれば長めに設定すると無駄な処理が走らなくて良いかと。

できること/できないこと

今のところ以下のことが可能です。
  • 指定したサーバのJenkinsジョブが完了するまで待機して、成否などの情報を返す

一方、できないことは以下の通りです。
  • 認証付きのJenkinsサーバには対応していません
  • このスクリプトでビルドしたジョブの成果物を取得するとかも特にやってません
  • その他いろいろ未対応

いやそもそもさぁ……

Q:普通に Remote access API とか Parameterized Remote Trigger Plugin とかあるよね?
A:うん。

確かに便利なプラグインやライブラリは存在していて、最初はRemote Trigger Pluginを使おうと考えていました。
が、こいつの出力があまり充実しておらず、特にビルドした別サーバのJenkinsジョブのURLが出てこないのがちょっとマズかったので自作することにしました。
(設定いじると出てくるのであれば乗り換えたいですが。)

自作するにしても、なるべく簡単に作りたかったので単にRemote access APIをシェルから叩くつもりでしたが、レスポンスのパースとかが面倒くさそうだった大変そうだったのでPythonで実装しています。

実装方針とか

そもそも複数サーバのJenkinsを連携させようと考えたきっかけが、会社で動かしてるCI環境のせいだったりします。
現状が、
  • プロダクトビルド用のJenkinsがある
  • デグレードの検出に直前のバージョンとの返却値比較をしたい
  • ただし、デグレードのチェックは最近構築したJenkinsサーバでやりたい
    • ビルド用サーバは共有していてあまりいじりたくないので
  • ビルドジョブはそのままビルド用サーバ上で動かしたい
  • チェックが失敗したら、プロダクトのビルドも失敗させたい
  • 成否によらず、プロダクトのビルド結果からチェックのビルドを参照したい
という感じなので、複数サーバの連携が必要だと考えました。

今回の要件としては、
  • python2.7で動く
  • pip installはNG
  • ビルドしたジョブが終わるのを待機できる
  • ビルドしたジョブのURLを出力する
  • できれば1ファイル
というところでしょうか。

JenkinsのREST APIを色々試していると、
  1. 対象ジョブのビルド開始
    1. ${JOBNAME}/buildWithParameters を叩く
  2. ビルドキューの状態確認
    1. ${JOBNAME}/buildWithParameters のレスポンスについてくるLocationヘッダに対象ビルドに関するキューのステータス取得用パスが入ってる(実際には、api/jsonなどを末尾に付与する必要はありますが)
    2. JSONの場合、ステータスとして取得したオブジェクトにexecutableフィールドが存在しない間はキューで待ち状態になっているようなので、返ってくるまで定期的にポーリング
    3. executableフィールドが返ってきたら、中のurlを使ってビルド自体の進捗をチェック
  3. ビルド自体の状態確認
    1. キューの状態確認で取れたexecutableフィールドのurlにアクセスすると、ビルドの状態が取れる
    2. ビルドが完了していない間は、取得したオブジェクトのresultフィールドがnullになっているので、これまた定期的にポーリング
    3. null以外になったら、入っている文字列が最終的なビルド結果
という感じで必要な情報は全部取れそうなので、この流れで実装すれば大丈夫そうです。

そして実装したソースコード全体は以下の通りです。
会社で動かすものはいろいろな事情で制約がつきやすいと思いますので、そういう時に活用していただけると良いかと思います。

2014年10月5日日曜日

HMMLearn導入メモ

どうもご無沙汰しております。気づけば一年以上ぶりですね。
忙しさを言い訳に全く何もしてない状況が続いていましたが、さすがにこれはマズいとそろそろ重い腰を上げたいところです。

最近はデータ解析のまねごとに勤しんだり、新しい機能の開発をやってみたり、新卒の子のフォローをしてみたりと色々やっているわけですが、ここに来てまた他のことにも手を出そうとしています。下手の横好きとも

ということで、タイトルのネタです。

諸々の事情により時系列データの予測をする必要に迫られそうなので、とりあえずHMM使ってみるかー、という安易な発想に基づき手頃なライブラリとして sklearn を導入することに。

が、

HMMのリファレンスいわく、
Warning

The sklearn.hmm module has now been deprecated due to it no longer matching the scope and the API of the project. It is scheduled for removal in the 0.17 release of the project.

This module has been moved to a seperate repository: https://github.com/hmmlearn/hmmlearn
とのこと。
仕方ないので、hmmlearnのリポジトリに飛んで記載されている手順通りにインストール。

  1. git clone git://github.com/hmmlearn/hmmlearn.git
  2. cd hmmlearn
  3. python setup.py install
  4. nosetests
すると、4. で以下のエラーに遭遇。

E.E
======================================================================
ERROR: Failure: ImportError (cannot import name _hmmc)

まぁ、なんやかんやあって切り離されたライブラリみたいだし、しょうがないかと思ってissuesを漁るとありました、ドンピシャのやつ。
https://github.com/hmmlearn/hmmlearn/issues/3
見るとまだ解決していないようですが、とりあえず全部コピればOKのようです。

……汚くなるからやだなぁ。

ということで色々試してみた結果、以下のようにすれば良さそうです。
$ cp -r hmmlearn/utils/ ${PYTHON_ROOT}/site-packages/hmmlearn/utils/
(${PYTHON_ROOT}はpythonのインストール先。virtualenv使ってたら、${VIRTUAL_ENV}/lib/pythonx.x/とかでしょうか)

どうもこのutils直下にいるfixes.pyを読んでいる感じですが、詳細不明なのでとりあえずの対処ということで。
ひょっとしなくてもvirtualenv使ってるとおかしくなるとかそういうアレかもしれません。

割とニッチなライブラリみたいなので困っている方はいない気もしますが、万一お困りの方がいれば参考までに。

2013年5月10日金曜日

PRML読書録(その0)

コンスタントに書く習慣をつけたい今日このごろ。

前回の記事(→WebGLでk-meansをビジュアライズ)ですが、当初の予定ではこれにDirichlet Process Mixtureによるクラスタリングを追加する予定でした。
学生の頃から気になる手法ではあったのですが、ちゃんと追えていなかったので、ここでやろうと。
が、どうにも基礎知識が足りなさすぎて実装の手がかりすらつかめない状況に陥ったので、方針を変えることに。

何をするかといえば、これまた学生の頃から(ry な、Pattern Recognition and Machine Learning(PRML)*1をちゃんと読んで、しばらくの間基礎知識の補強期間にしようと思います。
で、その過程で色々実装したものを使って遊んだり、アウトプットしていって、最終的に最近の新しい話題に関するネタをやれる状況を作ろうかなー、と。

ただ、このあたりは既に偉大な先駆者(PRML 読んでやってみた(上巻編)PRML 読んでやってみた(下巻編))がいらっしゃるので、ちょっと違う観点で実装したり出来ればなぁと考えていたり。*2

ということで、本来は順番通りに読んでいくべきでしょうけど、DPMに関係の深そうな、HMMとかその辺を中心にやっていこうと思います。
果たして最初のアウトプットはいつになるのか

  • *1:amazonだと和書が中古でしか流通していないので、手元にあるのはなぜか洋書。無駄にハードルが…
  • *2:実装に使われている言語はRがメインのようなので、numpyで書いてみるとか、実装したお試しコード全部ビジュアライズするとか。

2013年5月3日金曜日

WebGLでk-meansをビジュアライズ

久しぶりの連休!
ということで月イチどころか、週イチでの更新です。珍しい。
多分続かないですが

さて今日は少し前からちまちま作っていたものが形になったので公開してみます。

WebGLでk-meansをビジュアライズ
http://www.lazykyama.jp/ClusteringVisualizer/contents/
はい。タイトルのまんまです。

どういうものかというと、てっく煮ブログさんの以下の記事をパクったにインスパイアされたコンテンツです。
3D版!「K-Means法」ビジュアライズしてみた
http://tech.nitoyon.com/ja/blog/2009/04/13/kmeans-visualize-3d/ 

内容は機械学習やクラスタリングなどでお馴染み、k-meansの結果をWebGLで可視化する、ということで、インスパイア元とほぼ同じ*1です。
ちなみに動作確認はChromeでしかやっていないので、他のブラウザの方はご覧頂けないかもしれません。

このコンテンツですが、実際にアクセスすると、
こんな感じで表示されます。

で、nextボタンをポチポチ押していくとクラスタの割り当てが変わっていき、最終的に、
こうなります。
当然回転するので、くるくる回しているだけでも結構楽しいかもしれませんw


最後に実装について少し。
今回はWebGLを使ったと書きましたが、実際の描画などはthree.jsを使っています。
色々調べているとWebGLを直で触るのがしんどそうだったので、ライブラリの力を借りました。
OpenGLを少し触っていた事もありますが、サンプルが充実しているので、このくらいの規模なら割と簡単に作れるなー、というのが率直な感想です。
今後はWebGLを使ったサイトも増えてくるんでしょうかね。

  • *1:うちの方がアニメーションなどもろもろしょぼいので、正しくは劣化コピー


2013/05/14 追記:
「関連キーワードでググったらどのくらい上に来るかな〜」と、嬉々としてググったところ、全く同じ事をやっている方のブログ(K-means法をHTML5 canvasで可視化する)を発見して(´・ω・`)ションボリ
なんか作るときはちゃんと調べてからやりましょうねということで…

2013年4月29日月曜日

プレゼン・各種発表用タイムキーパーツール

月イチとか言いつつ週イチくらいでアウトプットできていて非常によい傾向です。

さて今日は深夜テンションでぱぱっと作ったツールを公開しようかと思います。
https://gist.github.com/lazykyama/5477836
プレゼンや発表会などで使う、タイムキーパー用のツールです。
特徴としては、

  1. HTMLファイル一つ(とjQuery)で動くので、特別なインストール作業が不要
  2. 背景色で残り時間をお知らせ

といったところでしょうか。
まぁ正直、何番煎じだかすらわかりませんが。

使い方

肝心の使い方ですが、とっても簡単!
  1. 上記gistにアクセス
  2. HTMLファイルをダウンロード
    1. 画面左側の「Download Gist」ボタンをクリックし、ダウンロードした.tar.gzファイルを解凍する
    2. または、画面右側の小さい「<>」ボタンからファイルの内容を表示し、右クリックで「ファイルに保存」など
  3. ダウンロードしたファイルをGoogle Chromeなどのブラウザにドラッグ&ドロップ
と、たったこれだけ。

ブラウザで開いた直後の画面はこんな感じで↓

右上の小さい「start/stop」ボタンを押すと、
こんな感じに。

残り1分を切ると、
背景が黄色になって、
制限時間をオーバーすると赤くなります。

最近はブラウザにフルスクリーンモードがあったりするので、発表者の前にPCなどを置いてデカデカと表示してあげるといいんではないでしょうか。


今後ですが、せっかくHTML5で書いているので、この手のツールに必須の音を出す機能を追加したいなと思っていたりします。
が、このへんの予定は未定です。
あと、一晩でぱっと書いたのでコードが汚いのも早いうちにどうにか

2013年4月22日月曜日

複数の色を均等に生成する

コンスタントに色々やる体制が整いつつあるkyamaです。こんばんは。
目指せ月イチアウトプット。

さて今日のお題は、「複数の要素に区別しやすい色を割り当てる方法」です。

いくつかの要素をカテゴリ分けして表示する際などに、カテゴリごとの色を作らないといけない、と言うことはそれなりにあると思います。
プラットフォームやフレームワークなどで提供されていれば悩む必要はないのですが、そういうものがない場合は当然自前で書くことになります。

このとき手っ取り早い方法は、以下の様なコードでランダムに色を選ぶことでしょうか。
var color = {r: 255, g: 255, b: 255};
color.r = Math.round(Math.random() * 255);
color.g = Math.round(Math.random() * 255);
color.b = Math.round(Math.random() * 255);

ただしこれは、重複した色や類似した色が生成されてしまい、実際には使いにくい場面もあります。
そのため、以下の様なコードで、色相を均等に分割して色を割り当てるのが妥当な落とし所ではないかと思っています。
// splitSize: 分割数
// index: 分割されたうちの何番目か
// return: RGBのオブジェクト。0から1までの値をとる。
function pickRGBColorOnCircle(splitSize, index) {
    var interval = 360.0 / splitSize;
    var hue = (index * interval);
    var sat = 1.0;
    var val = 1.0;
 
    // this code written in reference to the following site and Wikipedia.
    // http://www.technotype.net/tutorial/tutorial.php?fileId=%7BImage%20processing%7D&sectionId=%7B-converting-between-rgb-and-hsv-color-space%7D
    var hi = Math.floor(hue / 60.0) % 6;
    var f  = (hue / 60.0) - hi;
    var p  = val * (1.0 - sat);
    var q  = val * (1.0 - sat * f);
    var t  = val * (1.0 - sat * (1.0 - f));
 
    switch(hi) {
    case 0:
        return {
            r: val,
            g: t,
            b: p
        };
    case 1:
        return {
            r: q,
            g: val,
            b: p
        };
    case 2:
        return {
            r: p,
            g: val,
            b: t
        };
    case 3:
        return {
            r: p,
            g: q,
            b: val
        };
    case 4:
        return {
            r: t,
            g: p,
            b: val
        };
    case 5:
        return {
            r: val,
            g: p,
            b: q
        };
    default:
        throw new Error('unexpected error: args = ' + splitSize + ', ' + index);
    }
}

色相を分割する関係上、HSV表色系で色を特定した後にRGBに変換するようにしています。
現状は色相の開始位置を固定していますが、引数にoffsetなどを追加して変更できるようにすれば任意の位置から色の選択を開始できるはずです。

また上記のコードはGistにも置いているので、使いたい方はご自由にお使いください。
 https://gist.github.com/lazykyama/5429907
ライセンスは要らない気もしましたが、一応MITにしています。
ファイル名の変更などもご自由に。

しかしもう完全に備忘録ではなくなってきてますね…