研究進捗どうですか
- 国際学会に行くことになったよっ
久々に日記を書くわけですが、自分は修士生というのもあって日々自分の研究を進めております。進捗はボチボチ順調な感じです。国際学会に出席することになったので、ポスター発表の準備やら、英語の勉強やらを始めないとなぁとか思いつつ、「Linuxの認定試験を受けろ(LPIC Lv.1)」との内定先からの御達しがあったので、それもそろそろやる日を決めようかなっとか考えてたりします。
- 何から手を付けようか
このブログをご覧になられた方々は、僕の専攻を全く知らない思うんですが、僕は現在、統計学とシミュレーションを道具に、単純なルールに基づいて動くAIの作成を行っております。最先端の画像処理やテキストマイニングで使われている、いわゆる”機械学習”ほど複雑なものではありません。
ところが、自分は鯖エンジニアになる予定なので、今の研究は直接関係なかったりします。そこで、「今行っている研究」と「企業に入るにあたっての勉強」をする必要があります。この二つの学習をどのような順番で学んでいくかを上手く考えて、自分の中でいい影響を及ぼし合ってほしいなと思っているわけです。
- とりあえず、python
色々とやりたいことは増えましたが、手つかずな状態になってます。気が付けば、手を実際に動かすような勉強をせずに仏教哲学とか、ウィトゲンシュタインの言語ゲームってなんだろとか、飯の種にならない夢想は尽きないわけです。こういう自己の内面を見つめるような哲学は、認知科学っぽい分野とも取れる内容なので読んでいて面白いです。皆さんも、是非、哲学探究を読んでみてはどうでしょうか。
- 犬が喋ったような、赤ん坊が立ったような感覚
僕には歳の離れた弟がいるんですが、その弟も現在大学生になりました。宇宙工学を専攻しているらしく、また、プログラミングのサークルに入っているようです。いずれ抜かされてしまう気がしてならない(笑)僕の心配をよそに、弟はどんどん成長を続けています。兄はまったりしているというのに!
最近、お盆に弟と会う機会があり、弟がraspberry piで遊んでいるというではありませんか!これはまずい。弟に先を越されてしまう。兄の威厳が~~てなわけで、折角pythonをかじってる兄としては、pythonを使ってraspberry pi b+でサーバーを作るとの無謀な計画も遂行中だったりします。LPICの勉強になるしな、やったぜ。
#まずはmicroSD買おう
Amazon.co.jp: Think Bayes ―プログラマのためのベイズ統計入門: Allen B. Downey, 黒川 利明: 本
Amazon.co.jp: Python文法詳解: 石本 敦夫: 本
新しいpython本も続々出てるようだ。みんな見てくれよな!
リスト内包表記と条件式
- 内包表記条件式は色々できる
リスト内包表記というのは便利で、for文と組み合わせて次のようなリストが作れます。
>>> a = [2*x for x in range(5)] >>> a [0, 2, 4, 6, 8]
条件式を加えても同様の機能が得られます。
>>> a = [x for x in range(5) if x%2 == 0] >>> a [0, 2, 4]
次のように書くとエラーになりますが、
>>> a = [x if x%2 == 0 for x in range(5)] SyntaxError: invalid syntax
でも、elseで落としどころを用意してあげると、
>>> a = [x if x%2 == 0 else 'N' for x in range(5)] >>> a [0, 'N', 2, 'N', 4]
通る。ふーん。けどこうなると、'N'抜くのがめんどいなぁ
[[0]*m]*nの注意点、その2
- ドキュメントを読む
前回の括弧の件ですが、pythonのドキュメントを読んだところ、次のような記述がありました。
4. 組み込み型 — Python 3.3.3 ドキュメント
ノート:
0 より小さい n の値は 0 として扱われます (s と同じ型の空シーケンスを与えます)。また、コピーは浅いコピーです; ネストされた構造はコピーされません。これは新人 Python プログラマーによく出没します; 次のコードを考えてください:
>>> >>> lists = [[]] * 3 >>> lists [[], [], []] >>> lists[0].append(3) >>> lists [[3], [3], [3]]ここで、[] が空リストを含む 1 要素のリストなので、[] * 3 の 3 要素はこの一つの空リスト (へのポインタ) です。lists のいずれかの要素を変更すると、その一つのリストが変更されます。別々のリストのリストを作るにはこうします:
>>> >>> lists = [[] for i in range(3)] >>> lists[0].append(3) >>> lists[1].append(5) >>> lists[2].append(7) >>> lists [[3], [5], [7]]
なんか、新人()がやってしまう「あるある」な例として挙げられてました。うへぇ
それはともかく、このリストのリスト構造は、よく使う方法なのか、単に説明のために用意されたものなのか。。
[[0]*m]*nの注意点
最近、C言語で書いていたMASのコードをpythonに書き直してみようかといろいろ画策しております。ですが、C言語でできたことがpythonでもできるわけではなかったりするので注意が必要です。私の場合、得てして、ベクトルや行列を扱いたいわけで、その代替品がリストや配列です。
- リストと配列は違う
pythonには配列が存在しないので、リストを配列のように使うことが多いと思います。numpyのarrayを使う人はそちらのほうがよいと思いますが、僕はあいにく使っていないので、現時点では生のpythonでやることにします。
さて、次のような0を含む配列の配列に、一定数の個数1を代入したいとすれば、僕はC言語で次のように記述します。
#include<stdio.h> #define N 10 #define Ns 3 int main(){ int i,j,k=0; int a[N][N]; for(i=0;i<N;i++) for(j=0;j<N;j++) a[i][j]=0; while(k<Ns){ i=rand()%N; j=rand()%N; if(a[i][j] == 0) { k++; a[i][j] = 1; } } for(i=0;i<N;i++) {for(j=0;j<N;j++) printf("%d ",a[i][j]);printf("\n");} }
そうすると、次のように行列を表示してくれます。
$ gcc -o array array.c $ ./array.exe 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
pythonで同じことをしようとしたところ、初期値0の入力で、気を抜くと変なことが起こる場合があるので注意が必要です。
>>> a = [[0]*3]*3#ここがだめ >>> a [[0, 0, 0], [0, 0, 0], [0, 0, 0]] >>> a[0][0] 0 >>> a[0][0]=1 >>> a [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
[[0]*m]*nって別段普通に使えると思ってたのですが。いざ代入しようと思った時に僕としては、一か所だけ変更したくても、つられて一列変わっちゃうわけで。これは、使いにくい。折角短くかけるのに、どうしてこうなるの~。
ちゃんとやろうと思ったら、
>>> a = [[0 for i in range(3)] for j in range(3)] >>> a [[0, 0, 0], [0, 0, 0], [0, 0, 0]] >>> a[0][0] = 1 >>> a [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
これならちゃんと、一か所だけ変わってくれます。なんで揃ってないのだろうか。うーん、"zen of python"なんでしょうきっと。
まぁ、ともあれ、ちゃんと意図した動きをしてくれるコードは以下のようになりました。
import random Lx, Ly = 3, 3 a = [[0 for i in range(Lx)] for j in range(Ly)] k = 0 Ns = 2 while k < Ns: i, j = random.randrange(Lx), random.randrange(Ly) if a[i][j] == 0: k += 1 a[i][j] = 1 [print(i) for i in a]
インデックスkを必要としない書き方ができるならそうしたいものです。
おまけにクラスを使っても書いてみよう。
class Matrix: def __init__(self, raw, col): self.Lx = raw self.Ly = col self.m = [[0 for i in range(raw)] for j in range(col)] def show(self): [print(i) for i in self.m] def puts(self, sup): import random k = 0 while k < sup: i, j = random.randrange(self.Lx), random.randrange(self.Ly) if self.m[i][j] == 0: k += 1 self.m[i][j] = 1 if __name__ == "__main__": a = Matrix(3,3) a.puts(3) a.show()
phpデビュー
- 「○○君、研究は後回しかい?(暗黒微笑)」
研究とは関係のない勉強第二弾としてphpをちょいと触ります。
pythonのフレームワークも触ってないのにphpばっかやっててもアレなんで、
まぁ、ちょっとおつまみ程度に。。
さて、こういう時、計算機科学専攻の友人(X君)がいると僕みたいな門外漢でもphpを弄れるようになります。
それは、、
僕「ねぇねぇ、X君、phpできる道具だしてよ~」
X君「しょうがないな~」(ピコピコン)
X君「Ubuntuサ~バ~」
僕「それどうやって使うの?」
X君「それはね~」
ざっとこんなもんよ。
phpのやり方知りたかった人はごめんなさい。他を当たってください。ググれば出てくるはず。
僕もよくわかってないけどsshでログインしてvimでphp書いたら動くようにしてもらいました。
環境構築は今度やります。
paizaハッカソンの問題(ペアプロ)
- ペアプログラミングをやってみよう
土曜日の夜、こんなものを見つけました。
女子大生とペアプロするだけの簡単なお仕事です!|paizaオンラインハッカソンVol.2
彼女はスマフォアプリでも作ってるのでしょうか。それならば、CやJavaが良いのでしょうが、僕はpythonでやってみました。
if __name__ == "__main__": H, W = map(int, raw_input().split()) mat = [map(int, raw_input()) for i in xrange(H)] for i in xrange(input()): S, T = map(int, raw_input().split()) pat = [[0]*S]*T HS = H + 1 - S WT = W + 1 - T mat1 = [mat[i:i+S] for i in xrange(HS)] tmp1 = [] for mat2 in mat1: tmp2 = [list(mat3) for mat3 in zip(*mat2)] tmp1 += [tmp2[i:i+T] for i in xrange(WT)] N = sum(1 if pat == i else 0 for i in tmp1) print N
キャンペーン終了してるので速度は測ってませんが。まーいいや。
この問題を解いていて面白かったのは、パターン認識の基本となるような問題であると思えた点です。(いやいや、こんなに簡単なものはコードパズルであって、パターン認識ではないという理解が普通か。。。)簡単なお題でありながら、結構骨が折れました。
パターン認識 - Wikipedia
動的計画法など別の解法はこちらへ(↓)
http://paiza.jp/poh/code_index
*1:python2で記述されています