コンピュータやソフトウェアのあれこれ@道民(&元道民)
Posts tagged all
第26回北海道開発オフに参加してきた
4月 8th
[math][scala]超幾何分布と二項分布
4月 6th
非復元抽出とは、有限個のものから複数個を抽出する際に、抽出したものを戻さずに2回目以降の抽出を行うこと。こうすると二回目以降の試行の確率はだんだんと変化していくことになる。
復元抽出する場合は二項分布となるが、非復元抽出をすると超幾何分布となる。が、全体数に比べて試行回数が十分に小さい場合は、非復元抽出を二項分布で近似できる。
試しに、白玉100個、赤玉900個から玉を取り出す試行を10回行う場合に白玉が二個以下である確率を求めてみると、二項分布でも超幾何分布でも同じ値になることが分かる。
---*snip*--- def hypergeometricDistribution( n: Int, N: BigInt, Np: BigInt ): (Int) => Double = { import scala.math.pow def distribution(x: Int): Double = (combi(Np, x) * combi(N - Np, n - x)).toDouble / combi(N, n).toDouble distribution _ } val n = 10 val N = 1000 val p = 0.1 val binomial = binomialDistribution(n, p) val hypergeometric = hypergeometricDistribution(n, N, (N.toDouble * p).toInt) println("hypergeometric: %.2f" format ((0 to 2).map {hypergeometric(_)}.sum)) println("binomial: %.2f" format ((0 to 2).map {binomial(_) }.sum))
hypergeometric: 0.93 binomial: 0.93
[math][scala]二項分布とポアソン分布
4月 4th
二項分布は試行回数が多くなると階乗周りの計算量が多くなる。一回の事象の発生確率pが十分に小さければ、ポアソン分布で近似ができる。
例えば、5枚の硬貨を投げてすべて表がでるかどうかを64回やったときの分布を二項分布とポアソン分布で比較すると、以下のように高い精度で近似できていることがわかる。
import scala.math.BigInt def factor(n: BigInt): BigInt = if (n <= 1) 1 else n * factor(n - 1) def combi(n: BigInt, m: BigInt): BigInt = factor(n) / factor(m) / factor(n - m) def binomialDistribution(n: Int, p: Double): (Int) => Double = { import scala.math.pow def distribution(x: Int) = combi(n, x).toDouble * pow(p, x) * pow(1 - p, n - x) distribution _ } def poissonDistribution(m: Double): (Int) => Double = { import scala.math.pow def distribution(x: Int) = pow(m, x).toDouble / pow(2.71828, m).toDouble / factor(x).toDouble distribution _ } val n = 64 val p = 1.0 / 32.0 val binomial = binomialDistribution(n, p) val poisson = poissonDistribution(n * p) (0 to 10).foreach {n => println("[n=%d]".format(n)) println("binomial: %.3f".format(binomial(n))) println("poisson: %.3f".format(poisson(n))) }
[n=0] binomial: 0.131 poisson: 0.135 [n=1] binomial: 0.271 poisson: 0.271 [n=2] binomial: 0.275 poisson: 0.271 [n=3] binomial: 0.183 poisson: 0.180 [n=4] binomial: 0.090 poisson: 0.090 [n=5] binomial: 0.035 poisson: 0.036 [n=6] binomial: 0.011 poisson: 0.012 [n=7] binomial: 0.003 poisson: 0.003 [n=8] binomial: 0.001 poisson: 0.001 [n=9] binomial: 0.000 poisson: 0.000 [n=10] binomial: 0.000 poisson: 0.000
第26回北海道開発オフに参加しました
4月 3rd
3月31日(土)に行われた第26回北海道開発オフに参加しました。
なかなか自分のやりたいことにまとまった時間を取る事ができなかったので、まったりと有意義に過ごす事ができました。
シェルスクリプト事始め
Software Design 2011年3月号に載っている「シェルスクリプト事始め」の第一部を読みながら、シェルスクリプトを書いてみました。
ロジックが必要なシェルスクリプトを書いた事がなかったので、新鮮な気持ちで臨みました。
最終的に書いたのはこんな感じでファイルに実行権を与える事のできるスクリプト。
#!/bin/sh
for file
do
if [ -x $file ]
then echo "$file には実行権があります"
else echo "$file には実行権がありません"
echo -n "実行権を付与しますか?[y/n]"
read answer
case $answer in
y) chmod +x $file
echo "$file に実行権を与えました"
ls -l $file
;;
*) echo "$file は変更されませんでした"
;;
esac
fi
done
echo "$# 個のファイルを処理しました!!!"
気になった事
- 何故 if の終わりが fi なのか?
- 何故 case の終わりが esac なのか?
歴史的背景があるのかなあ。esacは覚えられない。
モチベーション3.0を読む
先日行われたAgileJapan札幌サテライト。その中の基調講演で紹介されていた本、気になったので購入しました。
講談社
売り上げランキング: 1117
手元に届いたのが開発オフの前日だったので、じっくり読みました。
まだ、第1部の途中までです。
今は「目の前に人参をぶら下げられただけでは、人間のやる気が上がらない(むしろ逆効果になることもある)」という話を事例とともに分析していっているあたりを読んでます。
開発オフの最後の発表では本に載っていた以下の2つの例を話ました。
人間は自分の利益になることであれば必ず実行する?
Aさんが1万円をBさんにあげるとします。
そのとき、AさんはBさんに条件をつけました。
- Bさんはそのお金をいくらかCさんに分けなければいけません。
- BさんがいくらCさんに分けるかはBさんの言い値で決まります。
- ここで、Bさんの言い値にCさんがOKすれば、AさんはBさんにお金を払い、BさんはCさんにお金を分けます。
- しかし、Bさんの言い値にCさんがNOと言えば、Aさんはお金をあげません。BさんCさん共にお金をもらえません。
このような条件下で実験を行ったとき、Bさんの言い値が1万円の5〜6割であれば、交渉が成立し、BさんCさん共にお金をもらえる確率は高かったのですが、Bさんの言い値が1〜2割だと、交渉が決裂し、両者ともにお金をもらえないケースが多かったそうです。
ここで、考えたいのはCさんの立場です。
Cさんは元々もらえる予定のなかったお金が手に入るわけですから、割合がいくらであっても「自分の得になる事」のはずです。
しかし、なぜ、1〜2割だと自分の利益をふいにしてしまうのでしょうか。
・・・というようなところから、「人間は利益になる事であれば必ずモチベーションが上がるのか?」という話につながっていきます。
楽しいことか仕事か?
幼稚園児を複数のグループに分け、次のような実験をしました。
1日目。あるグループには「絵を描いたらご褒美をあげるよ」と教えます。そして実際にご褒美をあげます。
別のグループにはなにも伝えず、ご褒美もあげません。
2日目。両方のグループにご褒美をあげません。
そうすると、1日目にご褒美をもらっていたグループの子供達は絵を描く事に対する意欲が少なくなったそうです。
ご褒美をもらっていないグループは2日目も楽しく絵を描いていました。
「報酬が発生する時点で、楽しいと思っていた事も仕事になる、その瞬間、内部からやりたい!と思う気持ちが薄れる?」というところから、モチベーション2.0と呼ばれる現代の「飴と鞭」のシステムのよくない点を分析していきます。
事例はだいぶはしょっているので、詳しく知りたい人はぜひ本を読んでみると良いと思います。
個人的にはこの本は小説と同じ、右開き・縦書きで、非常にしっくりと読みやすいです。
時間をみて読み進めたいと思います。
開発オフ恒例ランチ
今回もスープカレーで。カリー・ディ・サヴォイ Curry Di. SAVOY というお店に行きました。
トマトと湯葉と豆腐のスープカレーです。
湯葉としっかりした豆腐と豆腐ハンバーグみたいなものが入っており、けっこうお腹いっぱいになります。
辛かったのだけど、もう少し辛いのも食べてみたくなりました。
あと、キーマカレー気になった。
スペアリブもかなり気になった。
今回も楽しかったです。30回目指して!ゆるーく続けていきたいですね。
[PHP]Symfony2/SilexのControllerResolverを読む2
4月 1st
ところで、Silex\ControllerResolverにはこんなコードがあるんですがこれは何をやってるんでしょうねえ。
protected function doGetArguments(Request $request, $controller, array $parameters)
{
foreach ($parameters as $param) {
if ($param->getClass() && $param->getClass()->isInstance($this->app)) {
$request->attributes->set($param->getName(), $this->app);
break;
}
}
return parent::doGetArguments($request, $controller, $parameters);
}
引数の$requestは当然リクエスト、$controllerは通常Silexでは無名関数、$parametersはReflectionFunction#getParameters()の戻り値で、ReflectionParameterの配列です。
http://jp2.php.net/manual/ja/reflectionfunctionabstract.getparameters.php
$param->getClass()->isInstance($this->app)
の部分ですが、ReflectionParameter#getClass()はReflectionClassのインスタンスを返すので、ReflectionClass#isInstance()が呼ばれています。これはこう書き換えることができます。
is_a($this->app, $param->getClass()->getName())
つまり、コントローラの仮引数がApplicationクラスであれば、$request->attributesにセットしている。で、最後にparent::doGetArguments()を呼び出しているということはもしかして、、、
コントローラの仮引数に"Application $app"って書いておけば勝手に渡ってくるってこと!?
つまり実は前回のコードはこれでいいってことか。
<?php require_once __DIR__.'/../vendor/.composer/autoload.php'; use Silex\Application; class LeapYearController { function indexAction(Application $app, $year) { //... } } $app = new Application(); $app->get('/is_leap_year/{year}', 'LeapYearController::indexAction'); return $app;
あーこれなら書いてみる気になりますね。よくできてるなーって関心しかけたけどいやいやいやいやちょっと待って。ってことは
$app->get('/hello/{name}', function($name) use($app) {
return 'Hello '.$app->escape($name);
});
じゃなくて
$app->get('/hello/{name}', function(Application $app, $name) {
return 'Hello '.$app->escape($name);
});
でも良かったってことじゃん!!
まだ続くかも。
[math][scala]3囚人問題
3月 31st
こちらはモンティ・ホール問題より有名だと思う。
ある監獄にA、B、Cという3人の囚人がいて、それぞれ独房に入れられている。罪状はいずれも似たりよったりで、近々3人まとめて処刑される予定になっている。ところが恩赦が出て3人のうち1人だけ助かることになったという。誰が恩赦になるかは明かされておらず、それぞれの囚人が「私は助かるのか?」と聞いても看守は答えない。
囚人Aは一計を案じ、看守に向かってこう頼んだ。「私以外の2人のうち少なくとも1人は死刑になるはずだ。その者の名前が知りたい。私のことじゃないんだから教えてくれてもよいだろう?」すると看守は「Bは死刑になる」と教えてくれた。それを聞いた囚人Aは「これで助かる確率が1/3から1/2に上がった」とひそかに喜んだ。果たして囚人Aが喜んだのは正しいか?
まず「Bが死刑になる確率」と「Bが死刑になることを知る確率」が別の物だと気がつくことが大事。通常は「Cが恩赦のとき、Bが死刑になることを知る確率」と「Aが恩赦のとき、Bが死刑になることを知る確率」は同じと考えるべき。しかし、この問題文のような質問の仕方をしてしまうと、「Cが恩赦のとき、Bが死刑になることを知る確率」は1であり、「Aが恩赦のとき、Bが死刑になることを知る確率」は1/2であって、ズレが起こってしまう。
この説明でも怪しいと思う人は、やっぱりシミュレーションして試すとよい。
import scala.util.Random._ val A = 0 val B = 1 val C = 2 def playRole(keeperDecision: Array[Boolean] => Boolean): (Boolean, Boolean) = { val whoAlives = nextInt(3) val isDeath: Array[Boolean] = (0 to 2).map((x: Int) => x != whoAlives).toArray val hearBsDeath: Boolean = keeperDecision(isDeath) (hearBsDeath, isDeath(A)) } def whichIsDeath(isDeath: Array[Boolean]) = { if (! isDeath(C)) true else if (! isDeath(B)) false else nextBoolean() } val leakRate: Double = 0.8 def withNoAssumption(isDeath: Array[Boolean]) = if (isDeath(B) && nextDouble() < leakRate) true else false def statistics(keeperDecision: Array[Boolean] => Boolean): Double = { val results = (1 to 10000).map(_ => playRole(keeperDecision)).toList val resultsKnowOfB = results.filter(_._1) val numOfDead = resultsKnowOfB.count(_._2) numOfDead.toDouble / resultsKnowOfB.length.toDouble * 100 } println("normal situation: %.2f %%" format statistics(withNoAssumption)) println("ask which is death: %.2f %%" format statistics(whichIsDeath))
結果はほぼ理論値通りで、何も仮定しないと死刑となる確率は1/2になるが、この問題の仮定の場合は死刑となる確率は2/3のまま変化しない。
normal situation: 49.51 % ask which is death: 66.85 %
[math][scala]モンティ・ホール問題
3月 31st
3囚人問題は有名だけど、こちらを見かけたのは恥ずかしながら初めて。
「プレイヤーの前に3つのドアがあって、1つのドアの後ろには景品の新車が、2つのドアの後ろにはヤギ(はずれを意味する)がいる。プレイヤーは新車のドアを当てると新車がもらえる。プレイヤーが1つのドアを選択した後、モンティが残りのドアの内ヤギがいるドアを開けてヤギを見せる。
ここでプレイヤーは最初に選んだドアを、残っている開けられていないドアに変更しても良いと言われる。プレイヤーはドアを変更すべきだろうか?」
答えは、変更した方が勝率が高くなる。ベイズの定理できちんと考えれば答えは出るのだけど、非常に嘘っぽく感じてしまうのがこの問題の特徴*1。嘘っぽいなら実際やらせて確かめてみればいい。
import scala.util.Random._
def didWinGame(isChange: Boolean): Boolean = {
val doors: Array[Boolean] = Array(false, false, false)
doors(nextInt(3)) = true
val playerChoice = nextInt(3)
def tryChoosing(): Int = {
val choice = nextInt(3)
if (choice != playerChoice && ! doors(choice))
choice
else
tryChoosing()
}
val montyChoice = tryChoosing()
val finalAnswer =
if (isChange) List(0, 1, 2).filter(
(x: Int) => x != playerChoice && x != montyChoice
)(0)
else playerChoice
return doors(finalAnswer)
}
def winningRate(doGame: () => Boolean) = {
val total = 10000
val winCount = (1 to total).map(_ => doGame()).count((x: Boolean) => x)
winCount.toDouble / total.toDouble * 100
}
println("not change: %.2f %%".format(winningRate(() => didWinGame(false))))
println("change: %.2f %%".format(winningRate(() => didWinGame(true))))
実行するとほぼ理論値となる。
not change: 33.18 % change: 66.38 %
*1:この嘘っぽさは、引用した問題文だけだと前提条件が説明不足だってのもあるけど
「色のユニバーサルデザイン」
3月 29th
ぶっちゃけ、本の紹介なんですけどね。
「色のユニバーサルデザイン」
グラフィック社 (財)日本色彩研究所 (著), (社)全国服飾教育者連合会 (監修)
とは言うものの、感想は最後に。
では、昔話の始まり、始まり。
前に居た会社にデザイン課があって、そこにいた女性がこの手のことに詳しくて。
詳しいといっても、学生の頃に専攻してたとか、なんとか。
それから、少し気になっていたのですが、
最近だと自分も怪しいので、買ってみることにしました。
飛蚊症は、あまり色には影響ないみたいですが、まぶしいのは苦手です。
まぶしく感じるのも老化みたいですね、ちょっと悲しいです。
そんなこんなで、ちょっと他人事には思えないし、せっかくなので紹介します。
内容は、色弱者から見ると、どのように変化するのか?
それに対して、どのような解決策があるのかが書かれています。
フルカラーなので、とても分かり易いです。
液晶ディスプレイの機能に、こういうのがあった気がしますが、
今回、はじめて目の当たりにして、いろいろ学ぶものがありました。
これを読んで思い浮かんだのは、外観を変更できるアプリの配色を考えるときに、
こういうのを参考にした選択肢があると良いなーって思いました。
エディタのプリセットにも、そういうのがあると良いですよね。
おしまい。
第17回アジャイルサムライ読書会 @札幌道場 開催
3月 29th
第17回アジャイルサムライ読書会 札幌道場を開催しました。
参加者は9名。少し短めの第11章をやりました。
個人的にはAgile Samurai Dojo Gatheringの熱冷めやらぬ状態での参加となりました。
今回の範囲で「グっときた」ところ
仲間を探してみよ
会話を重ね、説明を続ける
うまくいかないときの根本原因は、感情に起因していることがおおいものだ
今回はマスターセンセイがいい事を言っていた。
勉強会として
「現場の状況を目に見えるようにする」というタイトルで書かれているやり方の色々。
正直に現場の状況を経営者に見せるため、チームで状況を共有するため、風通しを良くするため、最終的には良いプロジェクト運営をするため、必要な事ばかりです。
特に、[11.3チームの意思を明確にする]で書かれていた
- チームの約束
- チームが大事にすること
を「チームで話し合って」決めるというのは、とても大切な事だなと思いました。
言い出しっぺが先頭に立っていろいろな事をはじめるのはちょっと頑張ればできる。
でも、それを浸透させて、継続させるためには、全員が「なぜ?」を考えて、腑に落ちて、やろうとおもって実行しなければいけない。(それはまさに、先日のスライドで伝えた自分が抱える課題そのものです)
それを解決する、モチベーションを上げる方法の一つとして、自分たちの決まりは自分たちが話し合って(そして全員が納得して)決めるというのはよいのではないかな。
少なくても、「チームで大事にしたい事をチームで決めよう」となったときに、全員が自分から話し合いのテーブルにつく事ができれば、一歩前進できるように思う。
あと、ストーリーボードとカンバンの違いについて話し合っているうちに、先日の事例紹介で話したものはカンバンという名前で呼んでいたけれど、どちらかというとストーリーボードだったんだな、と気がついたりもしました。
運営の立場で
道場主の仕事の都合上(勤務地と勤務時間が変わりました)、今回からしばらく開始を19時半とすることにしました。
終了時間はなるべく21時を変えないようにと思っているのですが、短い章だった今回でも15分くらいは延びてしまいました。
分量と時間についてはもうちょっと気にしていかないといけないな。
でも、今回の量(ページ数で言うと10ページくらい)がじっくり話し合うのにちょうど良いかもしれない。
ディスカッションとしては、だれる事なく、ちょうど良く充実していたのではないかなと思います。
せっかく差し入れやお土産があったのに、おやつを食べる時間を作る事ができなかったのが非常に心残りです。
本日のディスカッションはこちらにまとめてあります。
https://github.com/agile-samurai-ja/support/wiki/Readingagilesamuraiinsapporo20120327
時間内にだいぶまとめる事ができるようになってきたのは良い兆し。
最後に、今回も会場を提供してくださった弊社に感謝。
あせらず、しっかりと続けていきたいと思います。
第25回釧路OSSコミュニティ勉強会を開催しました。
3月 28th
すみません。すっかりご報告が遅くなってしまいました!
3月13日(火)19:00よりわっとにて第25回釧路OSSコミュニティ勉強会を開催しました。
参加は、さいとーさん、いけださん、きしさん、しむらさん、やっちさん、らあくん、やはたの7名。
前半は前回に引き続きDBの基本ということで、
何か具体的なテーマを決めて実際に動くものを創りながら、
その過程で学んで行こうということになりました。
テーマとしては勉強会の日程を決めるのにも、
とても役立っているウェブサービス「伝助」の機能を、
PHPとMySQLで自分たちで創ってみようということになりました。
やはたとやっちさんの宿題として作ってきた途中経過を、
次回の勉強会のときにみなさんにご報告させていただいて、
いろいろつっこんでいただくという流れになります。
次回が楽しみであります。
後半は今年のイベントのスケジュールの確認となりました。


