Seeking for my unique color. このページをアンテナに追加 RSSフィード Twitter

| R | Ruby | C++ | Perl | 勉強会 | Java | Python | lab | アイデアマラソン | | Emacs | Tsukuba.R
| 理論統計学 | 実解析 | PRML | 集合位相入門| 意味が分かる位相空間論 | 機械学習 | NLP
この日記のはてなブックマーク数 My Profile by iddy
2006 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 09 |

2012-09-19

生存報告 + 引っ越し報告

久しぶりの日記です。いつの間にか学生から社会人になってます。相変わらず京阪奈にいます

大分日記を書いていないようですが、手元のDayOneでは4月から毎日日記を書いているので、むしろ前より書くようになっています。久しぶりなので、最近のことを書いてみると

という感じで、事前の予想とは違い充実&楽しんだ4ヶ月でした。研究所に戻ってきてからはどう使っていたか忘れた研究脳のリハビリをしつつ、という感じで。研修中に感じていたジレンマっぽいものを打破できるのはやっぱりここだなーという感じがするので、やっぱりここは楽しいです。

そんなわけでBlog引っ越しのお知らせです(唐突)。

ベタなmarkdownファイルが一枚置いてあるだけで、rssとかコメントもないWeb 1.0に戻ったような感じになってますが、元から自己満日記なので要するに自分が使いやすければ何でもいいんです(ぉ。研究の内容とかは書いてよさそうとか書いちゃダメっぽいとか考えるのも面倒なので書かないと思いますが、最近買ったカメラの遊び場とclojureのかきだめっぽい感じになるかなーと思ってます

2012-01-15

[][]ikoma-sicp + github

修論が終わったくらいからSICPの勉強会をやろうというのを計画している。Facebookで適当に募集して、自分を含めて6人でやることに。最初は松本研の人多めでやろうかと思っていたんだけど、ozaさんが最初に速攻反応してくれたのと、松本研の興味持ってくれそうなM1に声をかけてみたけど振られたりなどで松本研からはid:keiskS君のみの参加となった。あとはまぁ、あれこれでゆかりのある人で構成されています。skypeでやる予定ですが、skypeで勉強会をやるのはPRML勉強会以来か。PRMLは数式オンパレードだったのを考えると、SICPのほうがやりやすいかもしれない。難しいことには変わりないんだけど。

練習問題のコードとかを共有できると便利だなと思ってgithubにリポジトリを作ることに。1人ではいつも使っているが、多人数で使うときにはorganizationというのがあるらしく、それを使えばよいらしい(ozaさんに手伝ってもらった。ありがとうございましたー)。

で、今気がついたのだが、リポジトリ毎にあるwikiはこれ自体のリポジトリになっていて、cloneしてaddしてpushしたりするとwiki自体も変更されたり、誰かが変更を加えた状態でpullすると変更点をもってこれたりしてこれ自体がすごく便利。リポジトリはいいので、wikiだけprivateでこういうのが欲しい感じ(いくつか既存のシステムはあるのは知っている)。

2012-01-11

[][]DVDをmpegにしておく

英語の勉強ということでフレンズを購入。

フレンズ I 〈ファースト・シーズン〉 セット1 [DVD]

フレンズ I 〈ファースト・シーズン〉 セット1 [DVD]

来年度からたぶん通勤生活になりますし、iPhoneなりのスマフォで見れると便利。ということでmpegファイルに落とす。Mac標準のソフトではできないようなので、HandBrakeというのをインストール。GUIで適当に選んでいけばできるっぽい。

苦労しないでできるかなと思ったが以外と苦戦。落とせたと思ってもiPhone上では何も表示されなかったりなどした。どうやるのがいいのかよく分からないけど、Video CodecというのをH.264からMPEG-4に変更。

HandBrake

あと、フレンズは英語字幕が見れるのでsubtitlesのところをクリックして英語を選択しておく。

HandBrake

iPhone用とかiPad用とかのいくつかのpresetsが用意されているが自分はとりあえずApple => Universalを選んでおいた。

[]pvaluesとか

clojureは並行処理を得意としているので各処理が独立してできる場合、並行で処理をさせると高速化できる場合があります。代表的な関数としてはpmap、pvalues、pcallなど。

pmap

vectorの各要素に関して、ある処理を回したいとかの場合、pmapがよいでしょう。たぶん一番これがよく使う。

user=> (pmap #(+ 1 %) [1 2 3 4 5])
(2 3 4 5 6)

ここでは+1するだけの軽い処理ですが、pmapをするような場合はある程度重い関数でないとオーバーヘッドのほうが大きくなってしまいます。そういう場合はよくsequenceをpartitionしてからpmapし、flattenするというのがよくやられます(たぶん)。元々のseqがネストしてたりするとflattenした場合予想以上にflattenされてくるので、注意が必要。

(def N 10000)
(def long-seq (range N))
(flatten (pmap #(map + %) (partition (/ N 5) long-seq)))

この場合は5分割してやっている例。使えるコア数とかに応じて変えるとよい。

pvalues

並行で処理したいのがvectorの要素、とかではなく、いくつかの式を並行でやりたい場合に使う。こんな感じ。

(pvalues (heave-calc1 x y) (heave-calc2 x y) (heave-calc3 x y))

pcalls

引数と取らない関数を並行で処理させたい場合に使う。こんな感じ。

(pcall function-1 function-2 ...)

pvaluesの中身を見るとpcallsで定義されているのが分かる。

(defmacro pvalues
  "Returns a lazy sequence of the values of the exprs, which are
  evaluated in parallel"
  {:added "1.0"
   :static true}
  [& exprs]
  `(pcalls ~@(map #(list `fn [] %) exprs)))

[]Clojureのソースコードを読む

プログラム言語のソースコードを読もうとしたのはRが一番最初だったと思いますが、あのときはCの知識がろくにないまま戦っていた気がします。Clojureのソースコードを読んでみようと思ったけどRのときよりは割と読めるようになっている気がするし、clojure自体で書かれていることも多いので勉強になることが多い。今日はpsummaryとかをさらっと眺めてみた。

2012-01-04

[]openしたらcloseを忘れないようにしましょう

Rubyだと

File.open("hoge.txt", "w") {|file|...}

のようにやっておけばcloseして片づけてくれます。後片付けがきちんとできない人間にも安心ですね。

ところで、clojureのjsonライブラリを使っていたのですが、書き出すときにハッシュの終わりが閉じていないという事例が発生。ライブラリ側とかを疑ってみたりしたけど、最終的にはFileWriterオブジェクトをcloseしていないというアホなことが原因でした。上のRubyのように終わったら後片付けしてくれるように書けばよいのですが、closeでも似たようなことができる。

(with-open [w (java.io.FileWriter. (str base-dir "/filtered_docs/all.json"))]
      (json/encode-to-writer result w))

FileReaderでも同じような感じでできるので、使うときは上のをやるように習慣付けるようにしたほうがいいですね。

2012-01-02

[]clojureオブジェクトからjson形式へ

メモメモ

% java -server -Xmx1024m -cp lib/clojure-1.2.0.jar:lib/clojure-contrib-1.2.0.jar clojure.main 
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Clojure 1.2.0
user=> (use 'clojure.contrib.json)
nil
user=> (json-str {:hoge 1})
"{\"hoge\":1}"

[]clojureスクリプトっぽいこと(?)をする

Leiningenは依存しているものを自動に取ってきてくれたりして便利。jarで配布するときなどはproject.cljに

(defproject HogeProject "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.2.0"]
		 [org.clojure/clojure-contrib "1.2.0"]
		 [org.apache.commons/commons-math "2.0"]
		 [clojure-opennlp "0.1.7"]]
  :dev-dependencies [[swank-clojure "1.3.2"]]
  :jvm-opts ["-Xmx1g" "-server" "-Dfile.encoding=UTF-8"]
  :main HogeProject.core)

という感じでmainにエントリポイントを作ったりするとよい。しかし、それ以前に下処理などをしたい、というときにこれだけだとちょっと困る。java...という感じで指定すればいいのだがLeiningenは依存ファイル関係も見てくれるのがよいところなので、それを使いたい。どういう風にするか。こういう風に実行すればよいらしい。

lein run -m HogeProject.extract_content

extract_contentはただの例なのでここを適当に変えればよい。

2011-12-30

[]Clojureにヒアドキュメント的な機能を追加しつつ、compojureでコードを埋め込んでsyntax highlightを効かせる

タイトルが長い。compojure(clojuresinatra likeなことができる)でwebサイトを作っていたが、RubyやらClojureやらのコードを埋め込みたい。要ははてなのsuperpre記法っぽいものが欲しかったのである

clojureに標準でヒアドキュメント的なことはできないが、リーダーマクロで怪しいことをすればそれっぽいことができるようになる。

これでclojureコード内にrubyやらなんやらのコードを埋め込めるようになった。

syntax highlightにはSyntaxHighlighterが有名そうなのでこれを使うことにする。compojureでcssやらjsを扱うためにはrootディレクトリにpublicというディレクトリを作って、その中に入れていけばよい。syntaxhighlighterをダウンロードして(リネームして)、compojureを使っているコードのヘッダに相当するところでこんな感じに書く。

(defn head [title]
  [:head
   [:meta{:charset "utf-8"}]
   [:title title]
   [:link{:rel "stylesheet"
	  :href "stylesheet.css"
	  :type "text/css"}]
   [:script{:type "text/javascript"
	    :src "/syntaxhighlighter/scripts/shCore.js"}]
   [:script{:type "text/javascript"
	    :src "/syntaxhighlighter/scripts/shBrushRuby.js"}]
   [:script{:type "text/javascript"
	    :src "/syntaxhighlighter/scripts/shBrushClojure.js"}]
   [:script{:type "text/javascript"
	    :src "/syntaxhighlighter/scripts/shBrushCpp.js"}]
   [:link{:type "text/css"
	  :rel "stylesheet"
	  :href "/syntaxhighlighter/styles/shCore.css"}]
   [:link{:type "text/css"
	  :rel "stylesheet"
	  :href "/syntaxhighlighter/styles/shThemeEclipse.css"}]
   [:script {:type "text/javascript"}
    "SyntaxHighlighter.all()"]])

ちなみにsyntaxhighlighterにはダウンロードした状態だとclojure用のものは入っていない。が、公開してくれている人がいるので、syntaxhighlighter/scripts以下にjsファイルを放り込んでおく。

はてな記法のsuper pre記法っぽく使えるように適当関数を用意しておく。gutterなんとかっていうのは行番号を表示しない、というやつのようだ。

(defn spre [lang body]
  (vector :pre
	  (hash-map :class (str "brush: " lang "; gutter: false"))
	  body))
   (spre "ruby" (str #-EOM
#!/usr/bin/ruby
require 'enumerator'

STDIN.each_line do |line|
  words = line.split(/\s/)
  words.each_cons(2) do |word|
    unless word.empty?
      a, b = word
      printf("%s\s%s\t1\n", a, b)
    end
  end
end
EOM))

するとこんな感じできれいに埋め込めて幸せになれる。

Publication

うほほい。

2011-12-27

[]lsとかをMB単位GB単位で出す

0が大量に並ばれても僕にはよく分からないので単位変換して出してくれるとうれしい。特にファイル置きすぎてMBなのかGBなのかも分からなくなったようなディレクトリだとw。

ls場合

オプションにhを付けるだけで、BMだったりGBだったりを付けてくれる。便利。

% ls -lha data
合計 5.7M
drwxr-xr-x+ 2 yasuhisa-y    8 2011-01-04 00:39 .
drwxr-xr-x+ 8 yasuhisa-y   15 2011-01-04 06:18 ..
-rw-r--r--+ 1 yasuhisa-y 1.2K 2010-11-29 21:57 README
-rw-r--r--+ 1 yasuhisa-y 1.9M 2011-01-03 23:28 gold.txt
-rwxr-xr-x+ 1 yasuhisa-y 1.3K 2010-11-10 16:44 grade-bayes-hmm.pl
-rw-r--r--+ 1 yasuhisa-y 1.1M 2010-11-10 13:06 wiki-sample.example
-rw-r--r--+ 1 yasuhisa-y 753K 2010-11-10 13:04 wiki-sample.word
-rw-r--r--+ 1 yasuhisa-y 1.9M 2010-11-10 13:04 wiki-sample.wordpart

しかし、ディレクトリがあると再帰的にサイズ計算して足してくれる、ということはやってくれないのでちょっと不便。

duの場合

そういうときには下のduに-shオプションを付けてやればよい。hはls場合と同じで、sはサブディレクトリは表示しない、みたいな感じ。詳しくはmanで。

% du -sh data
5.7M    data

ただし、GB単位のやつだと結構時間がかかるのが難点。。。

[]rsyncの使いどころについて

プログラムのファイルとかだったらgitのpush&pullでどうにかなるし、データだったらscpとかでよくね?と思っていたが、結構容量を食うようなデータについてscpをしていると死ぬから差分だけ更新したいみたいなことがある。そういうときはrsyncが結構便利そう。データをサーバーでクロールしまくっててどっかに持ってきたい、みたいなときはたぶんこのケースに当てはまる。逆に素性抽出みたいなやつは変えると全部変わってしまうので向かない(こういうのが多かったので今までrsync使う機会があまりなかった)。

rsync -ave ssh --delete XXX@XXX.sakura.ne.jp:/home/XXX .

2011-12-26

[]Clojureではまること

関数の引数やletの中で"vec"とかっていう変数を使った後で戻り値を返すときに関数としての"vec"を使ったりするとエラーが意味分かない感じになってしまうので無駄に解読に時間がかかってしまった(例えば"Key must be integer"とかと言われる)。かれこれ3回目くらいである、はまるの。同様の問題がagentとかでも容易に起こってしまいうるが、Clojureでそういう問題にぶち当たらないように変数名の付け方に指針があるようだ、ということを本で思い出した。

プログラミングClojure

プログラミングClojure

[]ネストしたvector or hashmap

機械学習とかで隠れ変数を扱っているときに、「隠れ変数zに割り当てたサンプルの数を保存しておきたい」みたいな要望に答えるにはvectorやhashmapを使うのが上等手段だと思うが、隠れ変数が2段、3段となっていくとそれらの構造もネストしていってしまうわけで、インクリメントやデクリメントなどのアップデートが結構面倒なことになる(自分の場合3つくらい隠れ変数があった)。Clojureは注意しないと(注意しても、かもしれない)どんどん横に長くなってしまうが、ネストしたケースだとどうしようもなく長くなってしまいがち。

「うひょー、なんか逃げる方法ないの?」と思っていたらまさにどんぴしゃな関数があったのでメモ。

"assoc-in"、"update-in"、"get-in"。覚えましたし。適当に試してみたところ、mapがnestした場合だけでなく、vectorが混じってても大丈夫らしい。素晴らしい。

(assoc-in {0 {1 2}} [0 1] 100) ; {0 {1 100}}
(assoc-in {0 [0 1 2]} [0 1] 100) ; {0 [0 100 2]}

この付近のvector、list、map、set付近のデータ構造に関するユーティリティ関数はまさに生産性に関わってくるところなので早めに抑えておきたいところですね。語彙力っぽい感じ。ちなみに自分は下のcheatsheetをiPadに入れて気が向いたら眺めたりしています。

walk系は全然使ったことがないので抑えておきたいところ。

その他知らない関数メモ

sequence関係のユーティリティ関数で自分がよく知らないものをまとめておく。

reductions

reduceしていくときの中間値みたいなのも戻り値の要素に加えておいてくれる。Rでいうところにcumsumっぽいことが簡単にできて便利。reduce likeな関数なので初期値ももちろん取れる。

(reductions + [1 2 3]) ; (1 3 6)
zipmap

intoも似たようなことしなかったっけ...と思って違いを押さえる。intoはvectorをつなげていく。zipmapは最初のvectorをkeyにして二つ目をvalueにしたmapを返す。keyが被ってたら後ろのが生き残るらしい。intoとconcatは何が違うねん、、、と思ったけど、concatのほうはlazylistを返すそうなので、lazyなのが欲しいかそうでないかでintoとconcatを使い分けるとよいのかな。

(zipmap [:a :b :c :d :e] [1 2 3 4 5]) ; {:e 5, :d 4, :c 3, :b 2, :a 1}
(zipmap [:a :a :b :b :c] [1 2 3 4 5]) ; {:c 5, :b 4, :a 2}
(into [:a :a :b :b :c] [1 2 3 4 5]) ; [:a :a :b :b :c 1 2 3 4 5]
(concat [:a :a :b :b :c] [1 2 3 4 5]) ; (:a :a :b :b :c 1 2 3 4 5)
group-by

第二引数に渡したcollectionを第一引数fに渡したに適用した結果で分類してmapで返す。キーは当然ながらfを適用した結果。

(group-by count ["a" "as" "asd" "aa" "asdf" "qwer"]) ; {1 ["a"], 2 ["as" "aa"], 3 ["asd"], 4 ["asdf" "qwer"]}
(group-by odd? (range 10)) ; {false [0 2 4 6 8], true [1 3 5 7 9]}
(group-by :user_id [{:user_id 1 :uri "/"}
		    {:user_id 2 :uri "/foo"}
		    {:user_id 1 :uri "/account"}]) ; {1 [{:user_id 1, :uri "/"} {:user_id 1, :uri "/account"}], 2 [{:user_id 2, :uri "/foo"}]}
keep

exampleを見たら「それfilterと何が違うん...?」って感じだったけど、keepのほうはtrue falseでfilteringするのではなくnilかどうかでやる関数らしい。ちなみに似た関数にkeep-indexedというのがあって、これは無名関数のほうにindexも使えるようにした感じのものらしい。

(keep #(if (odd? %) %) (range 10)) ; (1 3 5 7 9)
(filter #(if (odd? %) %) (range 10)) ; (1 3 5 7 9)


(keep-indexed #(if (odd? %1) %2) (range 0 10)) ; (1 3 5 7 9)
(keep-indexed (fn [idx v]
		(if (pos? v) idx)) [-9 0 29 -7 45 3 -8]) ; (2 4 5)
split-at

指定した位置でcollectionをぶったぎる。split-withだと指定した条件を初めて満たすところでぶったぎる。take nとdrop nの組み合わせみたいなもの。

(split-at 2 [1 2 3 4 5]) ; [(1 2) (3 4 5)]
(split-with (partial >= 3) [1 2 3 4 5]) 
iterate

いかにもclojureらしい関数。無限リストを生み出すのだが、関数fと初期値xに関してx、(f x)、(f (f x))、(f (f (f x)))...というようなsequenceを作る。使うときにはtakeとかと合わせて、という感じかな。

(take 3 (iterate inc 0)) ; (0 1 2)
mapcat

複数のcollectionを引数に取り、それぞれをmapした結果を連結する。下のmapしてapply concatと等価、だと思う。

(mapcat reverse [[3 2 1 0] [6 5 4] [9 8 7]]) ; (0 1 2 3 4 5 6 7 8 9)
(apply concat (map reverse [[3 2 1 0] [6 5 4] [9 8 7]])) ; (0 1 2 3 4 5 6 7 8 9)
interleave

2つ、またはそれ以上のsequenceを受け取り、それらの要素を交互に持つようなlazy listを返す。これは例を見ればすぐ分かる。

(interleave '[1 3 5] '[2 4 6]) ; (1 2 3 4 5 6)
(interleave '[1 4 7] '[2 5 8] '[3 6 9]) ; (1 2 3 4 5 6 7 8 9)
interpose

リストの間に一個置きに何か要素を差し挟む関数。my-stringsの例は別途他の関数があるのでそちらを使えばいいが、まぁ例ということで。

(interpose 3 '[1 1 1 1]) ; (1 3 1 3 1 3 1)

(def my-strings ["one" "two" "three"])
(interpose ", " my-strings) ; ("one" ", " "two" ", " "three")
(apply str (interpose ", " my-strings)) "one, two, three"

2011-12-24

[]Clojureにおける関数の部分適用について

取る引数が複数あって、どれかだけ固定して残りはまだ引数になってる(説明の仕方が悪い)ようなときにはpartial関数が便利。"+"とか"*"のような順序を交換しても結果が変わらないような関数に関してはpartialはとても便利なのだが、"-"とか"/"とかはどっちを固定するかで結果が変わってくる。一箇所だけ固定して残りは無名関数で返せばそれはそれで仕事が終わりなのだが、なんか面倒。と、思ったらpartialの変種版があるようでそちらを使えば解決しそうだ。

;; (use '[clojure.contrib.str-utils2 :only (partial)])
;; ぶつかるのに注意が必要な気がする
((clojure.core/partial / 3) 6) ; 1/2
((clojure.contrib.str-utils2/partial / 3) 6) ; 2
((clojure.core/partial str "a") "b" "c" "d") ; "abcd"
((clojure.contrib.str-utils2/partial str "a") "b" "c" "d") ; "bacd"

(defn three-terms [a b c]
  (str a b c))
(three-terms "a" "b" "c") ; "abc"

;; 任意のところをfixするには...?
(defn fix-first-and-third [a c]
  #(three-terms a % c))
(fix-first-and-third "a" "c") ; #<user$fix_first_and_third$fn__15462 user$fix_first_and_third$fn__15462@70f28b3a>
((fix-first-and-third "a" "c") "b") ; "abc"

任意の位置であれこれしたければやはり関数を返すような関数を自分で作るしかないのかなー。

それにしてもなぜstr-utils2に入っているのか謎い。。。

[]transientとpersistentについて

Clojureの1.1から使えるようになった機能。Clojureの公式サイトから引用すると

If a tree falls in the woods, does it make a sound?

If a pure function mutates some local data in order to produce an immutable return value, is that ok?

Clojure - transients

最初のやつはなんと訳していいのかよく分からんけど、2つ目のやつは「(関数型言語は同じ入力を入れたら同じ出力を返して欲しいわけだけど)、immutableな出力を得るのに、localなデータだったら変更したりしてもいいんじゃね?(パフォーマンスとかを求めて)」という感じのニュアンスだと思う、たぶん。

コードを見たほうがたぶん早い。Clojureの公式サイトのほうは空配列からconjしていく例で書いてあるけど、本当に変更されてないのかetcを見る場合にはよく分からんので下のような例を書いてみた。

(def x '[0 1 2 3 4])
(let [tmp (transient x)]
  (persistent! (assoc! tmp 0 100))) ; [100 1 2 3 4]
x ; [0 1 2 3 4]

transientしてやったオブジェクトはassoc!やconj!のような関数をかましてやると上のようにできる。最後はpersistent!を使って状態不変なClojureの世界に逃げ込ませる。元々のオブジェクトは変わっていないことに注意。

The Joy of Clojureのchapter 12にも書いてあるが、ちっこいvectorとかを変更しまくる場合には返って遅くなる場合がある。大きいvectorとかをいじる場合には早くなる場合がある。そこに書いてある"THE RULE OF TRANSIENTS"によると

Write your code so that it's first and foremost correct using immutable collections and operations; then, make changes to use transients for gaining speed.

だそうです。

The Joy of Clojure

The Joy of Clojure

2011-12-22

[]UTF-8-MAC問題を解決する

大分前から使っている白MacBookのHDD容量が最近足りなくなってきていて、走らせてたプログラムが容量足りずに途中で死んだり、Emacsのバッファが保存できないレベルまできていたので、データを退避させることに。Ubuntuのサーバーに取り敢えず置いておくことにしたのだが、Ubuntu上にデータを持っていくと濁点がなんか文字化け(?)っぽいことになっているのに気がついた。そもそもファイル名に日本語使うなや、って話かもしれないが、自炊した本の名前とかは日本語のほうが分かりやすいのでこの場合しょうがない、と自分は考えている。このままだとMac側からscpしたときにFile not foundと言われてどうしようもなくなってしまうので問題を解決しなければならない。

あれこれ調べていると、これはUTF-8-MACと言われる問題らしい。svnとかで問題になっていたときがあったとか。iconvを使えば解決できるらしいが、Ubuntu側のiconvではUTF-8-MACに対応していない。Mac側でやるのも手だが、すでに結構Ubuntuに転送してしまった状況。twitterでtsuneさまがconvmvというのがあるのを教えてくれた。

convmv -r -f utf-8 --nfd -t utf8 --nfc ./* --notest

などとやるとカレントディレクトリのファイルを全部変換してくれるようで助かった。

Snow LeopardからLionに上げようと思っているんですけど、修論の前に上げるのはリスキーなのでまだやめておく。。。

[]threading macros便利

clojureを書いていると(reduce f4 (filter f3 (map f2 (map f1 lis))))みたいなのがネストしまくって、ソースが横に長くなるときがある(というかよくよくある)。clojureにはそういうのを解決してくれるマクロがいてそれは"->"と"->>"。名前はthread-first macroとthread-last macroだそうだ。括弧のネストした一番深いところから上がっていく順に書いていけばいい。firstとlastの違いは二つめも引数を固定にするか一つ目を固定にするか、という感じらしい。

例えばこんなtwitterのjsonデータからtweetの部分と取り出して、単語に分割、全部小文字にする、というのをマクロを使わずに書いてみる。

;; not so bad
(def words-in-tweets
     (map lower-case
	  (flatten (map (fn [tweet] (split #"\s" tweet))
			(map (fn [tweet] (tweet :text)) tweets-in-english)))))

(take 10 words-in-tweets)
; ("vanaaf" "eventjes." "kleren" "uit" "zoeken" "voor" "stage" "+" "school" "feest")

見たまんまとは言え、かなり横長である。これをthread-last macro(mapのlist部分、すなわち第二引数が省略された感じになっている)を使うと

(def words-in-tweets
     (->> (map (fn [tweet] (tweet :text)) tweets-in-english)
	  (map (fn [tweet] (split #"\s" tweet)))
	  (flatten)
	  (map lower-case)))

というようにすっきりと処理の流れが見え、かつ横長にならないというのを達成できる。素晴しい。てか、Rにも同様のことがすごい起きるのでRにも欲しい。。。

[]atomの配列と配列のatom

Clojureは基本的にmutableなものを許さない設計になっているので、do-syncなどのトランザクションの中でrefを変更するコストは結構高い(はず)。ドランザクションではないけど、atomの場合でちょっと実験してみる。

atomの配列と配列のatomを用意。要素をランダムに置き換えていくような実験の設定。

(def x (atom '[1 2 3]))
(def y [(atom 1) (atom 2) (atom 3)])
(def N 100000)

(println "x")
(dotimes [_ 5]
  (let [rand-seq (doall (vec (map (fn [_] (rand-int 3)) (range N))))]
    (time (dotimes [i N]
	    (let [n (nth rand-seq i)]
	      (swap! x assoc n n))))))

(println "y")
(dotimes [_ 5]
  (let [rand-seq (doall (vec (map (fn [_] (rand-int 3)) (range N))))]
    (time (dotimes [i N]
	    (let [n (nth rand-seq i)]
	      (reset! (y n) n))))))

要素のatomを持たせたほうが変更のときのコストが小さいようだ。

x
"Elapsed time: 261.819 msecs"
"Elapsed time: 251.127 msecs"
"Elapsed time: 242.16 msecs"
"Elapsed time: 240.869 msecs"
"Elapsed time: 256.606 msecs"
y
"Elapsed time: 108.052 msecs"
"Elapsed time: 119.755 msecs"
"Elapsed time: 79.847 msecs"
"Elapsed time: 82.929 msecs"
"Elapsed time: 79.497 msecs"

要素にatomを持たせるとメモリを結構食いそうな気がするが、今考えているやつだとメモリよりも実行時間のほうが重要なので、要素にatomのほうの設計がいいかもしれない(もちろん、配列の要素間で変なことが起きたりすると困る例では要素毎にatomは論外だろう)。

違う設定で実験

配列の長さをもっと増やしてみた。

(def x (atom (vec (range 10000))))
(def y (vec (for [i (range 10000)] (atom i))))

(def N 100000)

(println "x")
(dotimes [_ 5]
  (let [rand-seq (doall (vec (map (fn [_] (rand-int 10000)) (range N))))]
    (time (dotimes [i N]
	    (let [n (nth rand-seq i)]
	      (swap! x assoc n n))))))

(println "y")
(dotimes [_ 5]
  (let [rand-seq (doall (vec (map (fn [_] (rand-int 10000)) (range N))))]
    (time (dotimes [i N]
	    (let [n (nth rand-seq i)]
	      (reset! (y n) n))))))

やはり配列のatomのほうが遅くなっている度合いが大きいた思ったほどでもなかったような気がする。

x
"Elapsed time: 780.831 msecs"
"Elapsed time: 701.475 msecs"
"Elapsed time: 695.271 msecs"
"Elapsed time: 651.421 msecs"
"Elapsed time: 646.095 msecs"
y
"Elapsed time: 187.253 msecs"
"Elapsed time: 201.147 msecs"
"Elapsed time: 151.437 msecs"
"Elapsed time: 126.56 msecs"
"Elapsed time: 126.16 msecs"

2011-12-10

[]Clojure + swank + slimeでのプログラミングの感覚はR on ESSに似ている

最近でこそ使わなくなったものの、自分にとってRは母国語(第一言語?)みたいなもので結構影響を与えている。Rの言語として好きなところ(例えばapplyで行毎にばさっと関数適用してplotしてデータの様子をさくっと眺めるとか)もあるが、データ解析言語としてのRを支えているのはそのインタラクティブ性だと思う(あれこれ仮説を試しながらデータの性質を見ていく探索的データ解析)。Rによるインタラクティブな解析を支えているものの一つとしてESSを忘れてはいけない。ESSについてはTsukuba.RのLTで(若干宗教っぽく)紹介しているし、RubyでESSに近い環境を作りたいと思ってちょっとしたelispを書いたりしていた。

関数のヘルプがさくっと引けたり、そのついでに関数のexampleを実行できたりなどなどそれはそれはとても素敵なものです。RubyやC++を使うようになってからそれなりに環境を整えたものの、ESS上でのRの使い勝手には遠く及びませんでした(だけど、Rを使わなくなっていったのはnlpとの相性などがあったから、ですが...)。

ESS的な環境にせまるものはもう出てこないのか...と思っていましたが(大袈裟)、Clojure + swank + slimeはかなりESSに近い使い方ができれこれは当たりだと思った。

この環境では、リージョンで囲ったところを実行したり(C-c C-r)、ポイントを置いてる関数のhelpを引いたり(C-c C-d C-d)などよく使う機能にすぐアクセスできる。group-by関数でデータを因子毎にまとめて、frequenciesで頻度を集計して上位10件を眺めたり(take 10 lis)、でかいデータも遅延評価で必要な分だけ処理できる。Incanter: Statistical Computing and Graphics Environment for Clojureを使えば簡単に可視化もできる。Rと違って速度も相当早い(JVM上で動くし、型ヒントなどを与えることもでき、pmap関数などで並行処理も容易に行なえる)ので*1、解析もさらにやりやすくなる。データ解析はデータの整形(logスケールにしたり)、フィルタリング(異常値の削除)、集計(平均や分散などの基本統計量を求める)などからなっているといっても過言ではないが*2、Clojureは整形、フィルタリング、集計に対してmap、filter、reduceという対応する関数を持っている。このことからもClojureがいかにデータ解析に向いている言語であるというのが伝わってくるんじゃなかろうか(ドヤッ)。

唯一おしいなと思うのがexampleが見れないことか...。と、文句を付けるところがこれくらいしか見つからないくらい(前置記法とか3日もすれば慣れる)には快適に解析ができるので相当お勧め。

参考

プログラミングClojure

プログラミングClojure

7つの言語 7つの世界

7つの言語 7つの世界

The Joy of Clojure

The Joy of Clojure

Clojure in Action

Clojure in Action

*1:RもC拡張などを使えばかなり高速化できるが、clojureは別言語を使う必要がないのはかなりうれしい

*2:ちょっと言い過ぎかもしれない...

2011-12-01

[][]On Lispを読み返す

最近Clojureに手を出してみようかなぁと思っているので、On Lispを読み返してみた。

On Lisp

On Lisp

日記を調べてみると、On Lipsを買ったのは4年前のようで、買ったはいいが(全く!)理解できなくて積読になっていた本の一つであった。大学には2005年入学だからこれを書いたのはB3の頃のはずで、RやRubyやPerlを触り始めた(そしてJavaを触らなくなってきた)頃。当時の知識からすると理解できなくて無理はないなぁと思う...(オブジェクト指向をようやく理解し始めた付近)。

4年間の間で

  • Gaucheを触って、forを使わないで再帰で表現することを知ったり
    • Gaucheを触っていた頃には気づかなかったけど、それによって参照透明性が確保できることを知ったり
  • Haskellを触って、関数型の凄さを知り、モナドは結局理解できないままだったり(あれぇー)
  • Rをもっと深く知るようになり、関数をオブジェクトとして普通に扱えるようになり、中身がLispで驚いたり
  • NLPをやるようになって、再帰的構造の奥深さを知るようになったり

などなどが変化としてあった。4年も経ってるのか...と考えると成長あんまり早くない気もするけど、前に進んだのは確実だろう。

現状の理解、面白いと思ったところ

On Lisp、まだまだちゃんとは理解できていないが、現状の理解だったり面白いと思ったところを書き出しておこうと思う。

  • マクロの凄さ。構文木を直接書き変えることによってできる柔軟さ
    • メタプログラミングとはまた違ってくるのかな
  • 非決定性。7つの言語 7つの世界でPrologのところを読んでて、「どう解くか」ではなくて、定義を書いたら問題が解けているというのを知って驚いたが、Lispを使ってそれを再現している
  • 最後にオブジェクト指向Lispが紹介されているが、「オブジェクト指向をLispが取り込み始めた」とか書かれているのではなく、「Lispは拡張可能な言語で、その内部でオブジェクト指向が用意に行なえる」というような書き方をしていて、オブジェクト指向を推奨しているのではなく、Lispの柔軟性を示す一つの例として取り上げられていて面白かった

[]Clojure始めます

NLPの下のレイヤー(segmentationやparsing)で公開されているプログラムはC++やJavaであることが多い。XXXの(Ruby|Python|Perl) bindingみたいなのが用意されていることもあるが、そうでないものも多い。あるいはbindingには公開されてない情報も使いたいとかそういうこともある(ここまで真っ当な理由)。C++のプログラムの場合、自分でなんとかできるようになってきたが、Javaはもう5年くらい書いていない。まぁJavaを再度勉強すればいいのだが、それは割と退屈な気もする(こんなことをいうと怒られる)。

Dave Thomas(達人プログラマー―システム開発の職人から名匠への道の人)が「年に一度は新しい言語を習得しましょう」と言っているし、Java以外からJavaの資産を使える言語にしよう(この付近から目的と手段が入れ替わるw)。Javaの資産が使えるものとして、Jython、JRubyなどがあるが、それだとあまり新しい言語を学んでいる感がしない。候補としてScalaとClojureが候補に上がってきた。双方共に並行プログラミングを容易にすることができ、データをばしばし処理したいNLPerとしては嬉しい要素が詰まっている。

ClojureとScala比較

Clojureのほうは

  • かなり関数型言語の要素が強い
  • Javaのオブジェクトを使うときなどにはmutableなものを許すが、基本的にはimmutableなものを使う
    • 変更する際には明示的に書かなければならないようになっている
  • Lispなので「データとしてのコード」の思想が流れている
    • 強力なマクロももちろん使える
  • 並行プログラミングを可能にするためにSTM(ソフトウェアトランザクショナルメモリ)というものを用意している
    • SMTじゃないよ!!!(分かってるって)
  • JVM上で動く制約として末尾再帰の付近がちょっと使いづらい感じになっているが(recurとか)、どうやら遅延評価で解決させることが多いらしい
  • 動的言語である(が、速度を上げるために型の情報を教えてやることもできる)

という感じで、Sclarのほうは

  • シンタックスはJavaに近い感じがするので、Clojureよりはとっつきやすそう
  • Clojureよりオブジェクト指向よりだが、関数型言語の側面も持つハイブリッドな言語
  • Clojure同様、immutableなオブジェクトを普通は使う
  • 並行プログラミングを可能にするためにアクターモデルというものを採用している
    • Erlangもアクターモデルだが*1、そもそもErlangを触ったことがない。。。
  • 型推論(あんまりよく知らない...C++のautoみたいなやつでしょうか)というのをやってくれる
    • 静的型付け言語
  • パーザーのライブラリが標準で付いてる
    • 本質ではないかもしれないけど、id:kisさんが最近やられているみたいで興味がある

という感じらしい。自分が特に気になっている点としては2点あって

  • オブジェクト指向と関数型のバランスの取り方(Sclarのほうがよりオブジェクト指向に近く、Clojureのほうが関数型に近い)
  • 並行プログラミングを可能にしている仕組みの違い(STMとアクターモデル)

静的な言語か動的な言語かも気になる点ではある。昔は動的言語のほうが型とか気にしなくてばしばし書けていいじゃんって思ってたけど、C++をやるようになってから

  • この関数は副作用を起こす関数なのかが分かる(const)
    • Rubyの"!"とかではなく「保証」してくれる
  • 関数の入力に取る型が分かるので、使うときや読むときに(情報が多い分)やりやすい
    • 特に書いてる時間より読む時間のほうが長いので、型の情報は結構ありがたい
  • コンパイル時に分かるエラーはそこで弾いてくれる
    • まぁ、C++のエラーは読めたもんじゃないと思うんですが...
  • 入力時に型を利用した補完ができる
    • 個人的にはEmacsのauto-completeを使うことが多いのであんまり活用してないが...
  • 動的言語、ではないけどテンプレートやgeneriticsもある

と思うようにもなったので、一長一短だが、どちらかというと最近は静的型付け言語のほうが好きかもしれない。使っている人口はSclarのほうが多そうで、Clojureは結構マイナーな感がある*2

完璧な言語などありはしないし、目的に応じて正しくお使いくださいということなので、今回の目的を確認すると

  • NLP関係で公開されているJavaのライブラリを違和感なく触れる
  • 新しい風を自分の中に吹き込んでくれる

という2点が大きい。ScalaもClojureも前者に対してはたぶん大丈夫で(Clojureは前置記法なのでメソッドチェーンとかやりづらそう、と思ったけど、違和感なくできるようにするためのマクロがちゃんと用意されている)、後者も並行プログラミングだったりで色々勉強になりそうなのだが、より自分が知らない要素が強そうなClojureのほうを勉強してみることにしようかと思います。

参考

あれこれ調べたりするのに以下の本をちょっと読みました。Scala、Clojureに限らず色々なパラダイムの言語が出てきて読んでて面白かったです。

7つの言語 7つの世界

7つの言語 7つの世界

*1:というかSclarのほうが借りてきているのかな

*2:NLPに限るとどっちもあまり使われていない気もするけど...萩原さんがClojure使われているのくらいしか知らないw

2011-11-25

[][]木構造に対してイテレータを作る

Rubyistなら知ってて当然みたいな内容かもしれませんが、自分で作るのはたぶん初めてのように思うのでメモ。本当はC++で同様のことがやりたいのだが、Rubyのほうがぱっとやるには早いのでとりあえずRubyにて。

状況、モチベーション

Rubyにしろ、C++にしろコンテナ(ArrayだったりMapだったりSetだったり)にはイテレータが付いている。これがあるおかげで僕らはその内部構造を特に意識せずにeachだったりBOOST_FOREACHみたいなことができる恩恵を受けている。が、自作したクラスや構造体に対してはそのような便利なイテレータは用意されていないので、自分で用意する必要がある。

今回は木構造に対してそれが必要になった。木を走査するには例えば幅優先探索や深さ優先探索のような基本的なアルゴリズムがあるので、それを使えばいいのだが、「ちょっとだけ」違う操作を木のそれぞれのノードに対してやりたい(例えばprintしたいとかノードの値をaccumulateしたいなどの要求が複数ある)場合、ほとんど同様のことを何回も書くはめになるので、バグが出てくるかもしれないしとりあえずかっこ悪い。そういう状況で木構造に対するイテレータが必要となった。

Rubyの場合について

Treeクラスにeachメソッドを生やしてやればよい。eachで必要になるそれぞれの変数はyieldで返してやればよい。yieldは慣れないとなかなか分かりにくいが、何か操作をやっていて、一回止めて途中から戻ってくる、みたいなイメージである。下の2冊の(どっちか|両方)を読んだりすれば分かってくるようになるんじゃないんでしょうか。

プログラミング言語 Ruby

プログラミング言語 Ruby

初めてのRuby

初めてのRuby

class Tree
  attr_accessor :val, :level, :l, :r
  def initialize(val, level, l, r)
    @val = val; @level = level; @l = l; @r = r
  end
  def each
    stack = []
    stack.push self
    explored = []
    while !stack.empty?
      u = stack.shift
      if !explored.include?(u)
        explored.push u
        yield u
        stack.unshift u.l unless u.l.nil?
        stack.unshift u.r unless u.r.nil?
      end
    end
  end
end

tree = Tree.new("World", 0,
                Tree.new("Asia", 1,
                         Tree.new("Japan", 2, nil, nil),
                         Tree.new("China", 2, nil, nil)),
                Tree.new("Europe", 1, 
                         Tree.new("Dutch", 2, nil, nil),
                         Tree.new("Portugal", 2, nil, nil)))

tree.each {|node|
  puts "\s" * node.level + node.val
}

今回はスタックに積んでいくという形を取っているので深さ優先探索になりますが、キューに置いていくようにすれば(たぶん)幅優先探索での実行が簡単にできるようになると思います*1

実行結果

ちゃんと深さ優先で木を走査できていることが確認できる。

/Users/yasuhisa/ruby% ruby traverse_tree.rb
World
 Europe
  Portugal
  Dutch
 Asia
  China
  Japan

C++の場合

Rubyの場合は簡単にイテレータを作ることができたのだが、C++で自分でイテレータをどうやって作ればいいのかよく分からない。調べてみるとBoostにそれっぽいのがあるらしい。

begin()はrootノードを返すようにするとして、end()の実装はどうすればいいかなぁ(適当にNULLでいいの?)。incrementするときにスタックから取り出してexpandする、というようなイメージ。

*1:最初「ん、再帰じゃないと深さ優先書けなくね?」と思ったのは内緒w

2011-11-10

[][]Plaintextがやってくれた。。。

朝にPlaintextとDropboxを同期していたらDropbox側のファイルが全部消えていて焦った。調べてみると同様の現象が起こっている人がいた。同期しているときにスリープしたりするとやっかいなことになるらしい。。。

Dropboxはファイル単位ではgitのようにバージョン管理ができるのだが、フォルダ単位でいつのバージョンに戻す、ということができなくてちょっと困った。結局、一回管理しているフォルダを削除してからrestoreすることでどうにかなった。全く。。。

Dropboxの側にもgitのフォルダを作っているけど、もう消してもいいかも(さくらサーバー側から削除するのも忘れないこと => 削除した)。

2011-11-09

[]find + xargs

よく使う割に全然覚えてないというあれ。日本語や空白が入っているとxargs rmとかやったときにうまく行ってくれないということがあるので調べた。

$ find . -name \*~ -print0 | xargs -0 rm

結局、以下で対処した。

find . -type f -name \*conflicted\*.txt -print0 | xargs -0 rm

いい加減覚えたい。

2011-11-08

[][]はてな記法で書いたテキストローカルプレビューする

ホテルネット絶望的に遅くて、はてな(グループ)にLogを書くときに非常にストレスフルなわけなのでして、どうにかしないと死ぬ。前も似たような感じで、ローカルはてなダイアリーっぽいことをやってた。

が、検索とかいらないので、とにかくプレビューだけしたいんじゃごらぁということでもっとお手軽な感じでやりたい。前はtext-hatenaというRubyはてな記法のパーザーを使っていたが、今回はhparserというやつを代わりに使ってみる。で、以下のコードを~/bin/txt2hatenaという感じで保存して実行権限を付与(chmod +x)。

#!/opt/local/bin/ruby1.9
# -*- coding: utf-8 -*-
require 'hparser'

puts HParser::Parser.new.parse(STDIN.read).map {|e| e.to_html }.join("\n")

で、お手軽監視スクリプトであるkansitを使って以下のコマンドを走らせておくと、ローカルはてな記法で書いたテキスト更新されたときブラウザプレビュー更新されるという感じの仕組みになっている。

echo ~/Dropbox/PlainText/hatena/syou6162/group/syou6162/2011-11-08.txt | xargs -I% kansit % -c "cat % | txt2hatena > /tmp/txt2hatena.html && open -g /tmp/txt2hatena.html"

kansitのcommandオプションであれこれできないっぽかったのでxargsでどうにかしのぐ。openについてるgのオプションバックグラウンドで開け(たぶんMacしか動かない)、という意味でして、これがないと画面のフォーカスを取られてしまうので非常にストレスフルな感じになってしまう。

未だにはてな記法以上に頭使わないでばしばしとメモを取れる記法がない気がしているので、はてな記法を気持ちよく書ける環境というのは生命線なのでありますはてな中の人はてな記法をconvertするエディタとか出してApple Storeとかで売ったりしたらどうでしょうか(マニアックすぎる)。

2011-11-07

[]動的にメンバ変数を生やす

メタプログラミングメモ

# -*- coding: utf-8 -*-
class MyClass; end

hash = {:test => "テストだよ"}

MyClass.class_eval do 
  hash.each_pair do |k, v|
    define_method(k) { v }
  end
end

my_class = MyClass.new
puts my_class.test

2011-11-06

[][][]メタプログラミングRubyをさらっと読んだ

さらっと、というよりは一発では分かりそうになかったので、というほうが正しいw。ちなみに本書を読む前の自分が持ってた知識レベルは動的ディスパッチ*1とevalの初歩ってくらいです。

メタプログラミングRuby

メタプログラミングRuby

メタプログラミングかいうとevalとか黒魔術っぽいものを思い浮べるが、そういう技術ばっかり載っているのではなく、強力過ぎる道具で自分の足元撃ち抜かないための線引きがきちんと書いてあったり*2Rubyの中のことがきちんと知れる構成になっていてよい本だと思った。

Rails付近の章はまだ全然読んでないけど、それ以外のところで「おおっ」と思ったようなところをメモ特にスコープのフラット化の付近は読んでて一人ですごいすごい言っていたw。

続きを読む

*1Perlとかで昔書いた記憶がある

*2:「やれるのは分かったけど、実際にやっていいの?」とかそういうの

2011-11-02

[][]MSRAインターン記事がアップロードされました

滞在中に書いたMSRAの紹介記事をUniversity Relations in Japan, Microsoft Research Asia | MSRの最新情報をお届けします。アップロードしてもらいました。

選んだ写真がいまいちな感がしますが、他の写真万里の長城の寒さやら歩き疲れたやらでろくな顔しておらず残ったのがこれです(苦笑)。いっぱい取ってもらったはずなんだけどなぁ...。

内容はあんまり特別なことは書いてないですが、3行でまとめると

といった感じ。色々あるけど、やっぱり同世代の超優秀な人らが周りにわんさかいるってのがMSRAの一番の特徴じゃないでしょうか。世界で一番熱いラボ伊達じゃない。自分以外の方も記事載せていらっしゃいますし(そして僕より役に立つこと書いてらっしゃいますし...)、それらも参考にしながらピンときた人はCVを書き出してみるといいんじゃないんでしょうか。

自分はあと残り一ヶ月。頑張ります

[][][]mapとunordered_mapの違いについてまとめておく

NLPだとstd::mapとtr1::unordered_mapなら後者を使うことになることが多いと思うけど、あれこれ混乱してきたのでメモる。NLPerなら押さえておくべき常識のはず。。。

それぞれの特徴

データ構造std::maptr1::unordered_map
実装黒木ハッシュテーブル
findlog nAverage case: O(1), Worset case: O(n)
insertlog nAverage case: O(1), Worset case: O(n)
deletelog nAverage case: O(1), Worset case: O(n)
メリットキーソート済みなことが保障されているので、ある範囲でiterationさせたいときdeleteするなどの操作効率的に行うことができるバケット数を最初にきちんと設定しておけば大体の操作が定数で済む*1mapよりもメモリが少なくて済む

にはmapソート済みvectorに置き換えよう、ということが書いてあったりして、なんだかmapさんがかわいそうに思えてきた。。。ちなみにmapvectorを走査するときの速度の違いはこの辺に。

参考

*1:3/4くらい埋まるとrehashする仕様みたい。Rehashは重い操作なので、なるべく回数を少なくしたい

2011-10-30

[][][]stlコンテナgdbできれいに表示する

vectorの要素を見たいんですよ。こんな風にできる。

(gdb) p f.c.x
$2 = std::vector of length 2, capacity 2 = {1.4141999999999999, 3.1415000000000002}

gdbのversionを上げて(macportで入れていたのを上げたんだが、上がっていなくて何が起こったかと思ったらggdbになっていた)から、.gdbinitに書いてあるpythonスクリプトを追加すればおk

追記

vectorprintがきれいにできるようになってハッピーと思ったのだが、macportで入れたgdb 7.3.1やらソースから入れたgdbではstep inがなぜだかできず使いものにならない。。。結局、"gdb-stl-views"付近を入れる。printするときにpvectorとか打つのだが、僕はコンテナが何であるかを考えずにpをしたいんですよねえええ。。。人間様がコンテナ毎に打ち変えるとかありえない。型読んで欲しい。

2011-10-29

[][]スイッチを読んだ

スイッチ!

スイッチ!

個人、組織社会など様々な事例を挙げながら「変えたくても変えられない」人たちへ向けて実践的なコツを紹介している本。ちと長いので(と言っても350ページくらいだが)、かなりはしょりながら読んだ。

以下、自分メモ

続きを読む

2011-10-25

[][]Subvocalizationをやめるには...?

読みたい本がばらばらとあるのですが、平日はインターン仕事などでそれほど時間が取れない => 読むスピードそもそも上げれば状況改善されるんじゃね?と単純な思考に至りました。まずは現状を知ることが重要だ、ということで自分の読む速度をはかってみる。高速に読みたい本の種類は洋書が多いので、ここでは英語速読することについて考える。iPhoneのQuickReaderというアプリを入れてみて、自分洋書を読む速度をはかったところ毎分190-200 wordsという感じで、平均的なアメリカ人が200 wordsらしいので遅くはないけど、早くもない、といった感じらしい。本が今の3倍くらい早く読めるようになるとうれしいな、ということで毎分600 wordsがどんなもんかをQuickReaderで試してみる...速すぎて笑えるw。が、慣れてくるとスピード自体はありえなくはないな、という感じに思えてくるけど、ほぼ意味はつかめない。この付近を読んでいると「読み返し」や「subvocalizing」が問題になってくるそう。「読み返し」はほとんどやってないので、ボトルネックは「subvocalizing」のようだ。確かに音が入ってくるので処理が遅くなるのは分かるんだが、昔からそうしてしまっていることもあり、なかなか難しそうだ。

毎分600 wordsが慣れるとそんなに早くないなと思ったのは日本語テキストだとそれくらいの速度で読んでいるから*1。じゃあ、日本語だと「subvocalizing」しないかと言われるとそんなこともないのだが*2、文全体をsubvocalizingしてはいなくてところどころをsubvocalizingしているようなイメージ。ただ、それでも意味は掴める。英語でも慣れればそんな感じでいけるんだろうか。もっと使う洋書を簡単なやつにすればいいのかな。訓練でsubvocalizingをやめることに成功した人、どんな感じでやったか教えてもらえるとうれしいです。1週間くらいしかやってないので、もうちょいやれやというのがもっともな声かもしれない。

とりあえずこれとかも読んでみることにする。

Breakthrough Rapid Reading

Breakthrough Rapid Reading

*1日本語でさらに3倍速で読むには毎分2000語近く処理できるようにならないといけないと考えると結構大変そうに思える...

*2:content wordを素早く抽出する分類器が発達している、って感じだろうか

2011-10-21

[][]「マイクロソフトでは出会えなかった天職」を読んだ

一気に読んでしまった。ぶるぶるきた。これは間違いなく良書。

Microsoftの幹部社員だった著者がMicrosoftを辞めてNGO(Room to Read)を立ち上げたことに関することが書かれているのだが、色々な方面でのエッセンスが詰まっていた。Microsoftインターンやっていながら読むのはどうよと一瞬思ってしまったが、なるほどこれはMicrosoftで幹部をやっていた彼だからこそできる仕事なんだなと思ったのでMicrosoftインターン行っている人(もちろんそれ以外の人にもw)にもお勧めできる。

気にいった言葉メモを書いておく。

合わせて読んでる

原書で読んでますが、翻訳版もあります(中国にいるので、kindleで買うしかない)。

世界で生きる力――自分を本当にグローバル化する4つのステップ

世界で生きる力――自分を本当にグローバル化する4つのステップ

2011-10-17

[][]最近読んだ本

ホテルネットがお世辞にも早いとは言えないので、ネットgdgdと見る時間が減って読書にあてる時間が増えたのはよいことの一つかなと思います。

コンピュータが仕事を奪う

コンピュータが仕事を奪う

自然言語処理と機械学習を専門にやっている自分としては特に目新しいことがなかったけど、何よりも説明が分かりやすいなというのが印象に残った。自分がやろうとしていることを例えば自分の親に分かりやすく説明する、みたいなときにすごいよさそうな本である。機械学習が入ってくることにより、何が可能になってそれでも何ができないのか、人間がやるべきことはどんなことなのかということは機械学習を知らない人にとっても重要(自分の仕事は機械に置き変えられるものなのかetc)なので、専門でない人にもお勧めできる。

なんだか結構正確に書いてあるなぁと思ったら著者は国立情報学研究所の教授だった。全然知らなくてすいません...。Researchmapの開発とかもやっておられたようです。Special thanks的なところにも例えば言語処理関係だと宮尾先生、影浦先生、相澤先生の名前があった。

小飼弾のアルファギークに逢ってきた (WEB+DB PRESS plusシリーズ)

小飼弾のアルファギークに逢ってきた (WEB+DB PRESS plusシリーズ)

たぶん一度どこかで読んだことがある気がするけど。後半はちょっとぐだぐだになってしまっている感があるけど

  • Ruby on Rails開発者 David Helinmeier Hansson(この前読んだ37 signalsの人)
    • 「アーキテクト」って言葉を使ったら負け
  • Perl開発者 Larry Wall
    • 優れたソフトウェアも、文化を持たなければ普及しない
  • 「達人プログラマ」著者 Dave Thomas
    • コーディングを続けるという情熱が重要。それ以外は取るに足りない

の付近は今読み返しても読む価値があると感じた。

Mind パフォーマンス Hacks ―脳と心のユーザーマニュアル

Mind パフォーマンス Hacks ―脳と心のユーザーマニュアル

エンジニアのための時間管理術

エンジニアのための時間管理術

いわゆる時間管理術的な2冊。Mind Hacksもさらっと眺めてみたが、脳科学系の本を最近割と読んでいたのでそっちはお腹いっぱい...。そういう知見を頭に入れた上でどう生かせるかを知りたいなと思ってMind パフォーマンス Hacks ―脳と心のユーザーマニュアルを読んでみてた。自分用のメモを書いておく。

  • 要素の組み合わせ
    • 真に新しいように見えるものも既存のものの組み合わせ。パーツに分解してパーツを色々組替えてみるとどうなるか考えてみる
    • SCAMPER
      • substitute、combine、adapt、modify、put to another use、eliminate、reverse
  • 知性の曲を奏でる
    • 知的活動に役立つ音楽、聞くことでより集中して思考できる
  • 夢日記
  • アイデアに到達した経路を確認(Hack #32)
  • 人工言語を学ぶ(Hack #51)、エスペラント語
  • 感情のABCモデル(Hack #57)
    • 我々が幸せであるかどうかを決めるのは置かれた環境ではなく、環境に対する我々の捉え方。精神的な苦痛のもとになっている非理性的な思考の存在を突き止めれば、思考や行動をもっと客観的な状況にあったものにできる
  • 4倍呼吸(Hack #59)
  • 自分にインタビューする(Hack #63)

エンジニアのための時間管理術はシステム管理者用に徹底したような本で、相当の割り込みが入ることを想定して書かれているので、研究者には合わないところも多々あるかもしれないけど、それなりに使えるところがあったように思う。

  • atコマンド
  • サーカデイアンリズム(柔らか頭の時間)
  • ビジネスサイクル(今いるところの周期的なサイクルを知る。なければ作る。ルーティーンに落して考えなければならないことを減らす)
  • 人生の目標
    • 達成したい目標は何なのか、いつまでに達成したいのか。それを達成するためには具体的に何が必要なのか
  • ストレスの管理
簡単に、単純に考える (PHP文庫)

簡単に、単純に考える (PHP文庫)

対談形式だからか分からないけど、ちょっとびみょい。自分は対談形式があんまり好きじゃないようだ(前にも似たようなことを書いた)。

働きマン(1) (モーニングKC (999))

働きマン(1) (モーニングKC (999))

働きマン(2) (モーニングKC (1453))

働きマン(2) (モーニングKC (1453))

働きマン(3) (モーニング KC)

働きマン(3) (モーニング KC)

働きマン(4) (モーニングKC)

働きマン(4) (モーニングKC)

2011-10-16

[]10年振りの万里の長城

今月末でまた日本人インターンが数人いなくなってしまう&新しく2人こられた、ということで皆さんと万里の長城に行ってきました。万里の長城は高校の修学旅行*1で一回行ったことがあるので、10年振り。I端さんの研究室の同期の中国人の方に案内してもらってすごく助かりました。

最初電車で行こうとしていたけど、めっちゃ待たないといけないということでバスに乗ろうということに。しかし...

f:id:syou6162:20111017030329j:image

f:id:syou6162:20111017030333j:image

バスで行こうとするもめっちゃ混んでいて笑うしかないの図。ディズニーアトラクションのようでした。結局タクシーで向かうことに。「なんかこのタクシー道逆走してね?」だったり*2エンストして車押すことになったりしたのも今となってはいい思い出ですね。

f:id:syou6162:20111017030801j:image

焼き鳥的な何か。翌日お腹があれしたのであたったっぽいです...。

f:id:syou6162:20111017025639j:image

f:id:syou6162:20111017025635j:image

f:id:syou6162:20111017025631j:image

f:id:syou6162:20111017025628j:image

f:id:syou6162:20111017025624j:image

お昼御飯。

f:id:syou6162:20111017031208j:image

入口付近。お店がいっぱい並んでいるが、10年前はそんなになかった気がする。

f:id:syou6162:20111017033048j:image

f:id:syou6162:20111017031204j:image

f:id:syou6162:20111017033052j:image

f:id:syou6162:20111017033059j:image

入口。この辺から風がめっちゃ強くかなり寒くなってきた。

f:id:syou6162:20111017033527j:image

チケット。40元くらいでそれなりにする。

f:id:syou6162:20111017033538j:image

f:id:syou6162:20111017033535j:image

f:id:syou6162:20111017033940j:image

まだ余裕がある序盤戦。

f:id:syou6162:20111017034449j:image

f:id:syou6162:20111017035144j:image

f:id:syou6162:20111017034857j:image

f:id:syou6162:20111017034452j:image

f:id:syou6162:20111017034843j:image

途中。滑り台で降りていくようなやつがあった。なんでもありだな。斜面の角度がやばくてひーひー言い始める。

f:id:syou6162:20111017034847j:image

日曜だったのもあるのか観光客めっちゃいました。日本語もちらほら。

f:id:syou6162:20111017035524j:image

頂上付近。他にも写真取ってもらったけど、寒くてか疲れてか顔が引きつっているものが多い。。。

f:id:syou6162:20111017023859j:image

出口付近。なぜか熊がいた...。

f:id:syou6162:20111017023906j:image

帰りは皆様で一心という日本料理が食べれるところで晩御飯。皆様お疲れ様でした。

*1:普通の公立高校ですが

*2普通に逆走だった。しかし、よくあることっぽい...

2011-10-03

[][][][]内定式と昔の仲間

gdgd

奈良では合宿の話や(主にM1の人らと)研究の話をできて割と満足したので、土曜の昼から東京へ向かう。夕方頃に東京某所に着きid:yag_aysid:wakutekaid:mickey24で飯。Tsukuba.Rの愉快な仲間達という感じで気心が知れているので落ち着く。その後id:reposeid:tor_ozakiが合流。id:yag_ays宅で電脳コイルを見ながらgdgdと話すというなんとも非生産的時間を過ごす(笑)。いや、この時間を過ごすことが目的だったのでいいんです。

yaotti

日曜は上京してきたばかりのid:yaottiと食事。てっきり大学院でこっちに進むんだとばかり思っていたが、大学院には進まず自分会社を作ることにしたそうでびっくりした。Qiita(キータ)というエンジニア向け問題解決サイトを作っているそうな。

昔ビジコンを一緒にやっていた仲間と作るそうで、道は険しそうだが応援したい。自分来年から企業(分類するなら大企業になると思う)の基礎研究をする人になるので、id:yaottiとは進む方向が真逆になるのかなと思ったが、共通して必要になるところもかなりあるなぁと感じた。彼とはもう4年目くらいの付き合いになる(会うのは半年に一回くらいの頻度だが)が、会う度に刺激をもらっている気がするので、自分も刺激を与えれる存在でありたいなと思ったり。

内定式

月曜は内定式内々定から内定者に進化しました。半年から社会人と言われても全然ピンときません...。研究所全体だと90人近くということでかなり大規模だと思うのだが、自分が行きそうな研究所だとめっちゃ少ないと思われるので、色々な人に話しかけてみたり(それにしても自然言語処理機械学習のどちらかがメインという人は1人しかまだ会っていないのだが、全体としては何人いるのだろうか)。と言っても数人はtwitterとかで話していたりしていた人もいるのでオフラインしか聞けないというか聞きにくいことを聞いてみたりなど。ちょっと前にtwitterで話題になっていた記事に関して本音を聞いてみたいところが2点ほどあったのだ(書かないけど)。

あっ、某研究所じゃなくなってしまった。

その後、泊めてもらっていたid:yag_ays宅にてあれこれ面白そうな本の話をしたりなど。人の本棚に並んでいる本はどれも面白そうに見える(笑)。

形態の生命誌―なぜ生物にカタチがあるのか (新潮選書)

形態の生命誌―なぜ生物にカタチがあるのか (新潮選書)

インターネットのカタチ―もろさが織り成す粘り強い世界―

インターネットのカタチ―もろさが織り成す粘り強い世界―

スカイライナーとか北京行きの飛行機の待ち時間で下の2つを読んだ。どちらもかなり面白かった。

進化しすぎた脳―中高生と語る「大脳生理学」の最前線 (ブルーバックス)

進化しすぎた脳―中高生と語る「大脳生理学」の最前線 (ブルーバックス)

池谷さんの脳の本は高校生向けの講義ベースにしているというだけあって、生物とかの知識が中学生で止まっている自分にも分かりやすかった。分かりやすいだけでなく、最近NatureやScienceに出たような最新の研究の話も随所に盛り込んであり、分かりやすいというより結構興奮しながら読めた。これはかなりの良書。

37signalsのほうは一見かなりぶっとばしているように見えたが、かなり納得。本の元になっている37signalsベンチャー企業になると思うのだけど、これから研究者を目指していく自分にも大いに役に立つと思うことがsimpleだけど力強く書いてあった。例えば、目次から抜粋すると

  • 見直す
  • 先に進む
  • 進展
    • 制約を受け入れる
  • 競合相手
    • 製品をありふれたものにしない
    • 真似てはいけない
    • けんかを売る

などなど。id:yaottiと話したときに被ってくるところと書いていた付近もこの辺が多い。MSRAにくる前にアドバイスもらったことや、MSRA内の講演でも上で書いたもののいくつかの話を聞いたりしたこともあるし、色々なことのエッセンスが詰まっていると思う良書。はてなインターンに行く前も行った後も強く思ったことだが、「あなたに必要なものを作る」のところは自分としてはかなり重要というか譲れないことだと思っているので、自分の手で自分はどういうものが欲しいのかをしっかり考えてこの手で実現していきたい(それと同時に自分製品は何なのか、顧客は誰でどこを向いて研究をしていくのかなどなども考えていかないといけない要素だと思う)。

2011-09-29

[]修士論文中間発表

修論中間発表と内定式のために日本一時帰国しています。MSRAの仕事のほうは最初は設定とかにつまづいたりして時間食ってましたが、ベースとなるプログラムを書いてしまって、今後の方針が立ったかなという感じの実験の結果は得られたので、出出しとしては割と(意外と...?)順調かなという感じです。北京にくる前にやっていた仕事はなかなか進まず、今回も似たような感じになったらどうしようと内心相当冷や冷やしていたので、少し安心しています^^;

修論の中間発表は結局AAAIの時のネタ。実は違うネタでやろうとしていたんですけど、さっぱり(!!!)うまく行かず、これだと卒業が危ねぇ...という感じだったので安全側に倒した感じです(11/30までMSRAにインターンに行っている時点で危険側に倒しているという説もある)。去年のゼミナール発表のときもAAAIのときとは違うネタでやっていて、こっちはそれなりに見込みあるかなと思っていたのですが、似たようなネタが今年に入って見つかってしまってお蔵入り...。ということで修士の間は3個ネタやって1個がうまいこと当たってくれたかなという感じです。研究なので打率10割というのはありえないし、3割あればいいのかなぁとも思ったりしますが、母数が3しかないというのがとにかくいかんかなと思っています打率の上限は割と早めに見えてくる気はするので、数多く打席に立つしかない。そのためには実装速度の向上やうだうだしている時間を減らしていかないとなーと思います(OBの人のアドバイスでもある)。MSRAでは全然別のことをやっているので4個目か。こっちをうまいことやって1年に一本コンスタントに国際会議、を目指して今年は頑張ろうと思います

中間発表自体はAAAIのときと同じ感じのスライドでやったんですが、発表時間12分とめっちゃかいので時間内に収めるのに苦労。最初の概論で3分実験の前で7分ペースでくればちょうどいい感じに終わると練習のときデータから分かっていたので、時間内に終わる&&オーバーせずな感じで終わったのはよかったけど、M1の人とかから特に質問は来ず...。席は結構満席決みだったんだけど。質疑こんだけこないなら発表15分にして欲しいなと思いつつもそういうわけにはいかないんだろうなー(質問の練習も兼ねているので)。

発表終わった後は同じ評判分析タスクインターンでやってきたというhirotsugu-e君の話を聞きながら議論。ちょっと聞くつもりだったが、あれこれ聞いていたら90分くらい立ち話をしていたw。M1だけど、自分なりに工夫して頑張っていて素晴しい。夕食の後は統数研に行っていたmotonobu-k君の話を聞いたり。カーネルベイズの話。新しいモデルの話かと思っていたんだけど、推論を早くする系の話らしい。いまいちイメージできないところがあったりしたので、カーネル変えたりprior変えたりすると普通のやつとどう違ってくるのか見せてとせがんでおいたw。昨日はryo-ko君やkeisuke-sa君と話をしていたが、今日takuo-h君と話していると意外と同じトピックに興味を持っているということが判明。お互いは見ている方向やモチベーション大分違ったりして、相手が話しているとき自分が興味持っているものだと気づいていなかったようだったので、教えてみたり。12月に戻ってきたらなんか面白い発展があっているといいですが。

9月NAISTは若手の会に研究室合宿にと色々面白い行事があったにも関わらず中国にいたので参加できなかったけど、関係する色々な話を聞けて結構満足。MSRAにいるときに聞けるトピックとも大分違うので話せたり聞けたりして大分満足した。長々と付きあってもらってありがとうございましたー。

2011-09-24

[][]sinatraが動かなくなったので、でっちあげで動くようにする

年次大会の優秀発表賞を受賞したのを自分ホームページに書くかーと思ってさくら自分ホームページ更新したりしていて、あれこれしていたら動かなくなったorz。先週末潰しても解決できず、今日やっと解決したのでメモ的に残しておく。明らかに対処法としては正しくなさそうな気がするが、ホテルネット環境越しで作業するのはきついので、暫定的にこれでいいや...。tiltを入れたかっただけなのにどうしてこうなった

環境

Ruby自体やgem関係は~/localに入れている。

www1275 /home/syou6162% ~/local/bin/ruby -v
ruby 1.9.2dev (2009-07-18 trunk 24186) [i386-freebsd7.1]

LOAD_PATHを読みに行ってくれない

以前は

$LOAD_PATH.unshift '/home/syou6162/local/lib'

とやっておけばライブラリを読みに行ってくれていたのだが、あれこれやっているうちに読みに行ってくれなくなった。絶対正しくないと思いつつも

$LOAD_PATH << "/home/syou6162/local/lib/ruby/gem/gems/haml-3.1.3/lib"
$LOAD_PATH << "/home/syou6162/local/lib/ruby/gem/gems/rack-1.4.0/lib"
$LOAD_PATH << "/home/syou6162/local/lib/ruby/gem/gems/sinatra-1.2.6/lib"
$LOAD_PATH << "/home/syou6162/local/lib/ruby/gem/gems/tilt-1.3.3/lib"
$LOAD_PATH << "/home/syou6162/local/lib/ruby/gem/gems/sass-3.1.7/lib"

パスを直書きして暴力的に対処orz。こんなことしていたらライブラリバージョン上げる度にLOAD_PATHいじらないといけないので絶対違うんだけど、動かねぇ。。。

URI#decode_www_form_componentがないと言われる

パスを読みに行ってくれるようにはなったもののURI#decode_www_form_componentがねぇぞこらと怒られる。色々調べていると、以下に辿りついた。

1.9.1と1.9.2との互換性がどうの...と書いてあるが、結局どうすればいいかよく分からず。1.9.1をアンインストールして1.9.2をインストールしてみたが、そうすると他のライブラリがこけ始めて嫌になってきたので、クラスを上書きすることにしてしまった(ぇ。以下から足りないと言われているメソッド自分のstart.rbとかその付近に上書きしてしまった。

sassのメドッドがprotected

上のを修正しているとやっとホームページは見れるようになったのだが、cssを今度は読みに行ってこけている。エラーを読むと

NoMethodError - protected method `visit' called for #<Sass::Tree::Visitors::CheckNesting:0x28fd0714>:

となっている。この辺からネット環境も遅いのでイライラが頂点に達し、sassのVisitors以下のクラスのprotectedをコメントアウトしてしまった。絶対違うと思いつつも元気が残されていなかったのでこうしてみた。動いたら正義(ぇ。

[]お勧め中国語辞書アプリ on iPhone

中国語は発音が難しい言語ピンインと声調が重要(らしい)言語ピンインは練習してたりはするものの、まだまだ慣れない。中国語テキストに音声CDがついているので、そちらを参考にしようと思うが、CDのセクション分けがかなりいいかげんで目的の箇所に行くまでに結構時間がかかってしまってイライラ...(ピンインの練習、単語の発音、会話くらいが1セクションに入っていて目的の場所になかなか辿り付けない。日本の教材はよく考えて作られているなと思います)。やはり最初のうちは辞書自体に音声が付いているものがよいように思う。

iPhoneは常に持ち歩いているので、iPhoneアプリとして中国語辞書が入っていると便利。しかし、いくつか適当に探してみるが、音声付きである程度項目数がある辞書がほとんどない...(音声なしならばKTdic C-Eが無料の割に充実しているようでお勧め)。が、そんな中でよさそうなものを見つけた。中日ではなく中英だが、まぁ問題ないですよね。

無料バージョンでは音声は付いておらず、アドオンとして購入しないと音声のは付いてこない。iPhoneアドオンで1000円を越すと大分高いと感じてしまうが、普通に辞書を購入するんだったら余裕でそれ以上かかることを考えると十分安い。とりあえず自分が調べたいレベルの中国語単語に関しては発音が99%付いているので非常に助かる。

ネットで調べてみるとこのアプリ、(リアルタイム)OCR機能が付いているということで有名らしい漢字入力する手間が省けるくらいか...と思っていたが、中国語そもそも単語境界が分からないので、ピンインも分からなければどれが単語なのかも分からないということが結構問題で、OCR機能を使うと単語分かち書きもしてくれた上で単語意味を引いてくれるので、単語をほとんど知らなくて分かち書きできない中国語初心者にはうれしい機能であるということが発覚した。

その他、辞書エントリ単語帳につっこむことができ、それもかなり使い勝手がよいように思うので、中国語勉強し始めてiPhone持ってる人にはお勧めできるアプリなんじゃないかなと思います。

2011-09-19

[]lgammaの差を早く計算したい

休館話題(になってない)。

ベイズを使った研究ではよく多項分布ディリクレ分布を使い、パラメータ積分消去したりするので、ポリヤ分布が頻出する。ポリヤ分布のcomponentはガンマ関数からなっており、普通対数を取って計算することが多いので、ガンマ関数対数の差(lgammaの差と以後書く)をよく計算することになる。collapsed LDAのようなケースでは対数尤度を計算するときだけこのlgammaの差が登場するが(sampling時には特に関係ないということ)、普通はここでボトルネックになることは少ない。しかし、例えばnested Chinese Restaurant Process(nCRP)のようなケースではパスサンプリング式の一部で

p(¥mathbf{w}_d | ¥mathbf{c}_{d}, ¥mathbf{c}_{- d}, ¥mathbf{w}_{-d}, ¥mathbf{z}) = ¥prod_{l=1}^L ¥left(¥frac{¥Gamma{(¥{N_{c_{d, l}}¥}_{-d} + V ¥eta_l )}}{¥prod_{v=1}^V ¥Gamma{(¥{N_{c_{d, l}, v}¥}_{-d} + ¥eta_l )}} ¥frac{¥prod_{v=1}^V ¥Gamma{(N_{c_{d, l}, v} + ¥{N_{c_{d, l}, v}¥}_{-d} + ¥eta_l)}} {¥Gamma{(N_{c_{d, l}} + ¥{N_{c_{d, l}}¥}_{-d} + V ¥eta_l)}} ¥right)

というような式が登場し、サンプリングの度にlgammaの比を計算しなければならない(サンプリングのlogsumexpを使う関係で対数を取っている)。サンプリング計算MCMC時間がかかるところなので、lgammaの差を高速にできるようになることは重要(なはず)。サンプリングの式にlgammaの差が登場するのはnCRPだけかというとそうではなくて単語レベル以外に例えば文に隠れ変数がいるようなモデルではサンプリング式にガンマ関数が登場するので、そこそこよくあるケースだと思う(ベイズ修士学生なら在学中に3回くらいは遭遇するはず)。

そもそもnCRPのような例でなぜlgammaの差が登場してしまうかというと、ガンマ関数の性質

¥Gamma(n + 1) = n ¥Gamma(n)

がうまく利用できないからである(キャンセルアウトでガンマ関数が消えてくれる、ということがない)。しかし、上の性質が全く利用できないかと言われるとそんなこともない。両辺に対数を取って移項すると

¥log ¥Gamma(n + 1) - ¥log ¥Gamma(n) = ¥log n

という関係式を得ることができる。計算したいのはlgammaの差であるが、これを

¥log{¥Gamma{(a + b)}} - ¥log{¥Gamma{(a)}}

とする。¥log ¥Gamma(n + 1) - ¥log ¥Gamma(n) = ¥log nをうまく利用して、¥log{¥Gamma{(a + b)}} - ¥log{¥Gamma{(a)}}を捻り出すことを考える。持ってる関係式は一個づつの差なのだからb回くらい*1繰り返せば出てきそうなので繰り返してみる。

  • ¥log ¥Gamma(a + b) - ¥log ¥Gamma(a + b - 1) = ¥log{(a + b - 1)}
  • ¥log ¥Gamma(a + b - 1) - ¥log ¥Gamma(a + b - 2) = ¥log{(a + b - 2)}
  • ...
  • ¥log ¥Gamma(a + 1) - ¥log ¥Gamma(a) = ¥log{(a)}

bはそもそも整数でいいのかという疑問があるが、nCRPのようなケースだとbはXXXの回数となっているようなもので置けるので問題ない(ハイパーパラメータのほうは実数だが、それはaに入れてあげればよい)。上の式を全部足してみると、あれやこれやとキャンセルアウトが起こって

¥log{¥Gamma{(a + b)}} - ¥log{¥Gamma{(a)}} = ¥sum_{i=0}^{b-1} ¥log{(a + i)}

という式を得ることができる。問題はこの対数の和がlgammaの差より早いのかどうかということであるが、手元で簡単に実験してみたところ対数の和にしたほうが3倍くらい早かった。実際の値でも一致していたので、上の計算もたぶん合ってるはず...。論文とか読んでると実際の実装どうしたとかあまり書いてなくて、こういう早くする話がどっかにあってもいいんじゃないかと思ったので書いてみた次第です。

全然詳しくないが、数値計算で近似して早くしている人たちもいるみたい。が、lgammaの差に持っていける場合は上で導出した式のほうがまだ早い感じ。

*1:正確にはb-1回

2011-09-18

[]

  • 未だに電気で走っている自転車っぽいのを日本の自転車の速度だと思ってしまって事故りそうになるときがある
  • 空気が大変やばいと聞いていたが、初日以降は@BeijinAirを見ている限りはそんなにやばくはなさそうに見える
  • 中国語、単語に分かち書きされていないとそもそも辞書が引けないのがなかなかつらい
    • 辞書に載っていないとき人名だと気づくのに割と時間がかかる
  • 北京の都心部しか見ていなからだろうけど、生活は本当に日本とほとんど変わらない
    • 一度都心部から離れたところを見に行くのがいいのかもしれない

文法

SVOっぽい。

保罗 是 留学生ポールは留学生だ
我 学习 汉语中国語を勉強してる
她 很 漂亮彼女はとても美しい

メモ帳

ピンインで入力すると発音の勉強にもなって音と漢字の対応も勉強できるという気がしてきたので練習がてらテキストをtypeしてみる。完全に自分用のメモ。

  • 你们 好
  • 认识 你们 很 高兴
  • 我 是 国 留学生
  • 我 学习 汉语
  • 我 是 A 班 的 学生
  • 这 是 我们 的 老师
  • 那 是 我 朋友 西蒙
  • 他们 也 是 留学生
  • 他们 都 不 是 国人

-

-

-

-

-

-

-

-

-

-

-