トップ «前の日(11-25) 最新 次の日(11-27)» 追記

日々の流転


2001-11-26

λ. 寒空の下のキャンパス

マクロ経済の補講で学校へ行った。どうでも良いことではあるけど、公定歩合はマルクス経済学では手形の再割引率であるとされていたらしい。こういうのって面白くって好き。それから、先生の研究室を見学して、ついでに春学期の「マクロ経済Ⅱ」のOHP(を印刷したやつ)を貰った。そういえば、今日はAmayaの開発者の人がSFCに来ると聞いてたけど、時間と場所を聞くのを忘れてた。しまったなぁ。Amayaのソースには文句を言わなきゃ気がすまないのにー と最初は思ったが、僕が文句を垂れたからといって直ぐに状況が改善するとも思えないし、時間と場所を誰かに訊いてまで会いに行くという行為がしだいにアホらしくなってきたので、適当に時間を潰してから帰る事にする。

λ. 情報通信セキュリティ論

拡大体GF(2m)上の演算が理解できてなかったんだけど、何度か読み直してやっと少しずつ分かってきた。これなら明日提出の宿題も何とかなるかな。つーか、ガロアすげーよ

本日のツッコミ(全2件) [ツッコミを入れる]

ψ 匿名希望 [がロスわかんねぇ〜。]

ψ さかい [「がロス」じゃなくて「ガロア」っすよ。> 匿名希望さん ってのは置いておいて、「何故そのように定義するのか?」とい..]


2002-11-26 logical monday

λ. 論理的月曜日

Happy Monday 法の影響で今日は月曜日の時間割。でも、所詮ローカル・ルールなので、学外での予定とコンフリクトしている教員が多そう。実際、僕の取ってる授業は2限のコンパイラ構成論以外ぜんぶ休講ですよ。あー、阿保らしー

λ. コンパイラ構成論

属性文法が0型文法と等価だというのが、いまいちピンと来ない。

λ. 蝶ネクタイ理論

23日の日記間リンクの話に関係して、Web全体の構造が蝶ネクタイ状になっているとの研究を加藤さんに教えてもらった。

λ. エニックスとスクウェア「来年4月に合併」

あの財務体質じゃねぇというのは置いておいて、FFドラクエよりもアクトレイザー3を出してくだせぇ。

Tags: 時事

λ. REXML

ふとXMLで書かれたファイルを扱いたくなってREXMLを試してみたけど、いまいち使いづらい。例えば、eachに引数を渡す使い方があるけど、これだとEnumerableの機能が使えないし……

Tags: ruby

λ. URI

URI::Genericをハッシュのキーに使おうとしてはまる。hashもeql?も定義されてないのね……

Tags: ruby

λ. 読書

『かってに改蔵 18』
久米田 康冶 [著]
Tags:

λ. ボーリング

katoken, wisteria, jn, sakaiでボーリングへ。katokenさん強いっす。スコア

λ. 世界制服もとい世界征服

世界征服の前に立ちふさがる最凶の問題はどうやら久野君らしい。敵に回すのは恐ろし過ぎるし、かといって懐柔しても寝首をかかれそうとのこと。

λ. Intuitionistic type theory

9/27に借りてから随分経ってしまったけど、ようやく読了。Wellorderingsの章を除けば大体理解できたと思う。身に付いているかは別だけど。(苦笑)

Wellorderingsに関してはこんど向井先生に訊いてみよう。

Tags:

λ. エスプレッソ

『「エスプレッソ」って最後の「ッソ」を省略すると「コスプレ」みたいだよね』と某氏のお言葉。


2007-11-26

λ. 「ガン検診」問題でPRISMを試す

一階述語論理と確率を統合したツールとしてPRISMというものがある。

前々から存在は知っていたけど、最近渕一博記念コロキウム『論理と推論技術:四半世紀の展開』(20071020)の「記号的統計モデリングの世界を探る」(佐藤泰介)という発表を聴き、また「コンピュータソフトウェア」(Vol. 24 No. 4 Oct. 2007)に載っていた「PRISM: 確率モデリングのための論理プログラミング処理系」(亀谷由隆, 佐藤泰介, 周能法, 泉祐介, 岩崎達也)を読んで面白かったので、ちょっと試してみようと思った。

まずは非常に簡単な例として、ベイズのルールの例としてよく出てくるガン検診の例を試してみる。 以下は、昔受講した井庭先生の「探索的モデリング」(2004年度)第3回「ベイズ確率 reloaded」より引用。

あるガン検診の方法は、ガンの人は0.95の確率でガン陽性と診断され、健康な人がガン陽性と誤診される確率は0.05だとする。(つまり、どちらにしても的中率95%) ガンにかかる確率を0.005とする。この検査の結果、「ガン陽性である」という診断がでたら、自分のガンの可能性をどの程度と疑うべきだろうか?

これをPRISMでモデル化すると以下のようになる。

% cancer.psm
target(p/2). % 確率事象を表現する述語の宣言
values(cancer, [t, f]). % 確率変数cancerのとる値
values(test(_), [positive, negative]). % 確率変数test(_)のとる値

p(CANCER, RESULT) :-
  msw(cancer, CANCER),       % CANCERは確率変数cancerの値
  msw(test(CANCER), RESULT). % RESULTは確率変数test(CANCER)の値

% 確率分布の設定
:- set_sw(cancer,  [0.005, 0.995]).
:- set_sw(test(t), [0.95, 0.05]).
:- set_sw(test(f), [0.05, 0.95]).

これをPRISMに読み込ませて、「ガン陽性である」という診断が出たときに実際にガンである確率(事後確率)を計算してみる。

[sakai@localhost ~]% prism
PRISM 1.11.1, Sato Lab, TITECH, All Rights Reserved. Nov 2007
B-Prolog Version 7.0, All rights reserved, (C) Afany Software 1994-2007.

Type 'prism_help' for usage.
| ?- prism(cancer).
prism(cancer).

compiled in 0 milliseconds
loading::cancer.psm.out

yes
| ?- chindsight_agg(p(_, positive), p(query, _)).
chindsight_agg(p(_, positive), p(query, _)).

conditional hindsight probabilities:
  p(f,*): 0.912844036697248
  p(t,*): 0.087155963302752

yes
| ?-

事後確率が計算され、実際にガンである確率が約9%、実際にはガンでない確率が約91%という結果が得られる。 つまり、このモデルだと、ガンと診断されても実際にはガンでない可能性の方が遥かに高いわけですね。

うん、確かに非常に手軽に色々出来そうだ。 というか、確率推論や確率の学習を行うだけなら、探索的モデリングの授業で使ったBayonetよりもずっと手軽そうだ。 グラフ構造を推定したりしたいような場合には使えないとは思うけど。

λ. Re: EXPTIME とか PSPACE とか

あろはさんのホワット・ア・ワンダフル・ワールド 真面目に計算の複雑性の理論を勉強してこなかったツケがより。

非常にわかりやすくて、勉強になる。交替性有限オートマトン(Alternating Finite Automata, AFA)にはお世話になっているけど、交替性チューリング機械なんてのも存在して、計算量理論で意味を持っていたとは。

ちなみに、SFCでは [Chandra-Kozen-Stockmeyer] を教えてくれるどころか、計算量理論を扱う授業自体が無かった…… orz


2008-11-26

λ. 舎利禮文 【初音ミク×M@STER_fonts Pv】

このセンスは凄いな。

Tags: ネタ

λ. 今日も泳いできた

今日も帰りに泳いできた。 だんだん、1km泳いでもそんなにバテないようになってきた。


2009-11-26

λ. 祖父の葬儀

(後で書く)


2013-11-26

λ. 自動微分を使って線形回帰をしてみる

Conal Elliott の Beautiful differentiation の論文を読んだ話 の続き。 自動微分の機械学習系での応用は分かるという話で、せっかくなので一番簡単な線形回帰でも使って試してみることに。

データ例

例としては、Rでお馴染みのgaltonのデータを使う。 これは、リンク先にも書いてあるけど、Galtonさんが1885に両親の身長と子供の身長の関係を分析したデータセットで、928サンプルが含まれている。RのUsingRパッケージに含まれているので、これをRで以下のようにして、galton.csvに保存しておく。

> install.packages("UsingR")
> library(UsingR)
> data(galton)
> write.csv(galton, "galton.csv", row.names = FALSE)

せっかくなので、Rで線形回帰をして散布図上にプロットしておく。

> lm <- lm(galton$child ~ galton$parent)
> summary(lm)

Call:
lm(formula = galton$child ~ galton$parent)

Residuals:
    Min      1Q  Median      3Q     Max 
-7.8050 -1.3661  0.0487  1.6339  5.9264 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)   23.94153    2.81088   8.517   <2e-16 ***
galton$parent  0.64629    0.04114  15.711   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 2.239 on 926 degrees of freedom
Multiple R-squared: 0.2105,	Adjusted R-squared: 0.2096 
F-statistic: 246.8 on 1 and 926 DF,  p-value: < 2.2e-16

> plot(galton$parent, galton$child, pch=19, col="blue")
> lines(galton$parent, lm$fitted, col="red", lwd=3)

自動微分のコード

Conal Elliott のコードを使おうかと思ったけれど、Hackageにekmettプロダクトのadパッケージがあったので、それを使うことに。バージョンは3.4を使う。 そういえば、先日開催されていたekmett勉強会でも、@nebutalabという方がadの紹介をしていた。

最急降下法

で、grad関数で自動微分して勾配を求めて、それを使って最急降下法するコードを自分で書こうと思ったら、ちょうど都合の良いことにgradientDescentという関数が用意されていた。 なので、これを使うことにして書いてみたのが以下のコード。 gradientDescentには普通に目的関数costと初期値を引き渡しているだけで、勾配を計算するための関数などを全く引き渡していないことに注目。

-- Galton.hs
module Main where

import Control.Monad
import Numeric.AD
import Text.Printf
import qualified Text.CSV as CSV

main :: IO ()
main = do
  Right csv <- CSV.parseCSVFromFile "galton.csv"
  let samples :: [(Double, Double)]
      samples = [(read parent, read child) | [child,parent] <- tail csv]      
      -- hypothesis
      h [theta0,theta1] x = theta0 + theta1*x
      -- cost function
      cost theta = mse [(realToFrac x, realToFrac y) | (x,y) <- samples] (h theta)
  forM_ (zip [(0::Int)..] (gradientDescent cost [0,0])) $ \(n,theta) -> do
    printf "[%d] cost = %f, theta = %s\n" n (cost theta :: Double) (show theta)

-- mean squared error
mse :: Fractional y => [(x,y)] -> (x -> y) -> y
mse samples h = sum [(h x - y)^(2::Int) | (x,y) <- samples] / fromIntegral (length samples)

実行結果

それで、コンパイルして実行してみると……

[0] cost = 3156.057306315988, theta = [2.6597058526401096e-2,1.8176025390625015]
[1] cost = 2146.158122210389, theta = [4.6848451721258726e-3,0.3193588373256373]
[2] cost = 1459.9671459993929, theta = [2.2758658044906822e-2,1.5543558052476183]
[3] cost = 993.724511817967, theta = [7.872126807824226e-3,0.5363518751316139]
[4] cost = 676.9290401789791, theta = [2.0154694031410444e-2,1.3754888484523264]
[5] cost = 461.6776592383078, theta = [1.0041866689573948e-2,0.6837909525010937]
[6] cost = 315.42191649062323, theta = [1.8389486179011837e-2,1.2539549823963831]
[7] cost = 216.0462832295627, theta = [1.1520222735584755e-2,0.783970560056418]
[8] cost = 148.52403553080242, theta = [1.719418363575862e-2,1.1713769350191798]
[9] cost = 102.64504299700745, theta = [1.252880777988588e-2,0.8520390200495115]
…
[100] cost = 5.391540483678139, theta = [1.5252813280501425e-2,0.9963219150471427]
[101] cost = 5.391540272870362, theta = [1.5259169016306468e-2,0.9963197390947276]
[102] cost = 5.391540062688162, theta = [1.5265580330093717e-2,0.9963213622860531]
[103] cost = 5.3915398529310075, theta = [1.5271945828031475e-2,0.9963198538562846]
[104] cost = 5.391539446704301, theta = [1.5284752349382588e-2,0.996321999765866]
…
[1000] cost = 5.3913214546153885, theta = [2.195100305728909e-2,0.9962239448356897]
[1001] cost = 5.39132107512034, theta = [2.19637098242177e-2,0.9962195158083134]
[1002] cost = 5.391320924102971, theta = [2.1976643022454955e-2,0.996230564935548]
[1003] cost = 5.391320615754077, theta = [2.198280974693417e-2,0.9962155918323486]
[1004] cost = 5.391320339333709, theta = [2.1989373588151114e-2,0.9962277637190161]
…
[10000] cost = 5.389137897180453, theta = [8.88298535971496e-2,0.9952457730583962]
[10001] cost = 5.38913768668423, theta = [8.8836182876215e-2,0.9952431313378857]
[10002] cost = 5.389137477124735, theta = [8.884258017163454e-2,0.995245138984378]
[10003] cost = 5.389137268201876, theta = [8.884892139830691e-2,0.995243314173662]
[10004] cost = 5.389136870256361, theta = [8.886169628000305e-2,0.9952459827149522]

全然収束しない。収束遅すぎだろ。めげずにさらに放置してると……

[100000] cost = 5.367962167905593, theta = [0.7474196350908293,0.9856182795949244]
[100001] cost = 5.367961856713982, theta = [0.7474255920526732,0.9856022065240108]
[100002] cost = 5.367961582358961, theta = [0.7474319755635072,0.9856152902779793]
[100003] cost = 5.367961333033166, theta = [0.747438007468459,0.9856043401613668]
[100004] cost = 5.367961100713857, theta = [0.7474443291979176,0.9856132010817849]
…
[1000000] cost = 5.210315054542271, theta = [6.411550087218479,0.9027479380474824]
[1000001] cost = 5.210314936517216, theta = [6.411554713147153,0.9027442449249086]
[1000002] cost = 5.210314820386824, theta = [6.411559435811994,0.9027471642783936]
[1000003] cost = 5.210314705543812, theta = [6.411564078735267,0.9027446329906037]
[1000004] cost = 5.210314591575562, theta = [6.411568787386962,0.9027465946477329]
…
[5000000] cost = 5.0177281352658305, theta = [18.890815946868038,0.7201815311956332]
[5000001] cost = 5.017728123133143, theta = [18.890817258298373,0.7201790053001258]
[5000002] cost = 5.017728111906337, theta = [18.89081863661461,0.720181051408368]
[5000003] cost = 5.017728101294881, theta = [18.89081995979637,0.7201793288296293]
[5000004] cost = 5.01772809110162, theta = [18.890821328424636,0.7201807127666369]
…
[10000000] cost = 5.001070611475556, theta = [22.875383075131683,0.6618880826205324]
[10000001] cost = 5.00107061095209, theta = [22.87538335250446,0.6618875866914469]
[10000002] cost = 5.001070610463426, theta = [22.875383643001708,0.6618879878893927]
[10000003] cost = 5.001070609998513, theta = [22.875383922680363,0.6618876495886096]
[10000004] cost = 5.001070609549686, theta = [22.87538421127661,0.6618879208540909]

まだかかるのかよ……

[15000000] cost = 5.000328380487849, theta = [23.716478910924902,0.6495830291863548]
[15000001] cost = 5.0003283804652, theta = [23.71647896958202,0.6495829318117019]
[15000002] cost = 5.000328380443848, theta = [23.71647903081446,0.6495830104741416]
[15000003] cost = 5.000328380423461, theta = [23.716479089924043,0.6495829440298111]
[15000004] cost = 5.000328380403642, theta = [23.71647915078346,0.649582997196493]
…
[20000000] cost = 5.0002953079344685, theta = [23.894024471635685,0.6469855785633368]
[20000001] cost = 5.000295307933508, theta = [23.894024484038532,0.64698555944479]
[20000002] cost = 5.000295307932569, theta = [23.89402449694667,0.6469855748657359]
[20000003] cost = 5.0002953079316805, theta = [23.894024509438292,0.6469855618158963]
[20000004] cost = 5.000295307930787, theta = [23.89402452227324,0.6469855722344278]
…
[22987995] cost = 5.000294005873883, theta = [23.922778217862263,0.6465649143875803]
[22987996] cost = 5.000294005873744, theta = [23.922778220364872,0.6465649143543949]
[22987997] cost = 5.000294005873735, theta = [23.922778220366094,0.6465649143543771]
[22987998] cost = 5.000294005873733, theta = [23.922778220367316,0.6465649143543594]
[22987999] cost = 5.000294005873733, theta = [23.922778220367316,0.6465649143543594]
[22988000] cost = 5.000294005873733, theta = [23.922778220367316,0.6465649143543594]

やった! 収束した!

Rだと一瞬だったところ、1.5日くらいかかったし、Rで計算した theta0=23.94153, theta1=0.64629 とはちょっとずれてはいるけれど。

感想

Courseraの Machine Learning のコースで、最急降下法で線形回帰を実装したときは1000ステップくらいで収束してたので、これもそれくらいで収束するかと思ってたんだけれど、こんなにかかるとは以外だった。 gradientDescent関数(ソース)の実装に何か問題があるのか、それともそもそも素朴な最急降下法には荷の重い問題だったのか分からんけれど、2パラメータのこの程度の問題でこれは流石に酷い。

本当はこの後は、ロジスティック回帰とニューラルネットの例も何かやってみようかと思ってたのだけれど、その前にそっちを何とかしないといけないかも。 Machine Learning のコースでも最初は簡単な再急降下法を自前で実装させていたけれど、その後は最適化は予め用意してある実装(fmincg.m)を使うようになってたからなぁ。 まあ、時間かかりすぎて疲れたので、また今度。

【追記】頂いたコメンドなど

【追記】 解決策

本日のツッコミ(全2件) [ツッコミを入れる]

ψ mkotha [入力をおおざっぱに正規化(68を引いてから4で割る)してから最適化したところ、99ステップで(Doubleの最後の桁..]

ψ sakai [おお〜! そういえば、Courseraの講義でも feature scaling が勾配法の収束の速度に効いてくると..]