Displaying posts written by

tkyk

who has written 156 posts for へびにっき.

予想通りに不合理

予想どおりに不合理―行動経済学が明かす「あなたがそれを選ぶわけ」の感想。経済学が想定する「合理性」人間とは、しばしば誤解されるような「あらゆる情報を加味して損得計算ができる」ことではなく、せいぜい「自分にとって何が特で何が損かは、自分が一番良く知っている」程度の意味だと、『世界一シンプルな経済入門』にはあった。これは一見無理のない想定に思えるが、しかし本書によれば、現実の人間はその程度の緩い想定すら満たさないほど、合理性とはかけ離れた存在であるらしい。つまり自分で自分が何をどの程度求めているか分からず、様々な要素(相対性や社会規範や一時の感情など)に支配されて容易に不合理な選択をして失敗して、しかもそのことに気がつかない。 ただし著者らによる多くの実験が明らかにするところによれば、その不合理さには秩序がある。失敗の仕方に規則性があり、予想通りの仕方で失敗する。まさに「予想通りに不合理」というわけだ。だから「合理的な」人間の代わりに「予想通りに不合理な」人間という想定を組み込むことで、経済学を改良できるのではないか。そして不合理さ故に手つかずになっている部分を改善することで、ある種の”フリーランチ”が手に入るのではないか。それが「行動経済学」というもののアプローチだという。 いくつか特に印象深かった点。 保有効果(主に7章) 人が何かを手に入れると、他の人よりもその「何か」を高く評価するようになる。早い話、愛着が湧くとそれ以前よりも良く思えるということ。またそれ故に、人は得ることよりも失うことの方に大きな感情を抱く。 この保有効果を商売に利用したものとして、組み立て式の家具(苦労するほど所有意識が高まる)、ネットオークションや大部分の広告(所有する前に所有意識を発生させる)、無料お試し期間(一旦所有意識を植え付けてしまえば離れにくくなる)、などが紹介されている。 所有意識は物質的なものに限らず、思想や宗教、アイデアなどにも当てはまる。一旦それを手に入れてしまうと、その思想なり何なりを失うことに耐えられず、実際以上にありがたがってしまう危険がある。これは「アイデアと結婚してはいけない」という『まぐれ』に書いてあった警句とも符合する。 知識、予測と経験(主に9章、10章) 美味しそうだと思って飲むと美味しく、不味そうだと思って飲むと不味くなる。「そういう意見を持つようになる」という意味ではなく、実際に味覚が変わってしまう。 「自分がどのようなステレオタイプで見られているか」認識するだけで、行動が変わるといったことも起こる。またブラセボやブラセボ手術が実際に効いてしまうのも同様の現象と言える。近年に入るまで、ほとんどの薬はブラセボだったらしい…。また薬よりさらに実験するのが難しい「手術」については、現代でも多くのブラセボが含まれている可能性があるとのこと。この点はいずれ研修医の友人に意見を聞いてみたいところだ…。

グローバル関数のMockを作る

CakePHP 1.3 + SimpleTestでグローバル関数をMock化するためのラッパークラスを作ってみました。libs/ に置いて使用します。 global_function.php – gist 次のように任意の関数を呼び出せます。 //bootstrap.php 等で読み込んでおく App::import(’Lib’, ‘GlobalFunction’);   GlobalFunction()->env(’REMOTE_ADDR’); GlobalFunction()->gethostbyname(’example.com’); テストケースでMockを使用したいとき、GlobalFunction::registerMock を呼び出します。戻り値はMockオブジェクトです。 function testRegisterMock() { //使用する関数名を引数に渡す $mock = GlobalFunction::registerMock(’env’, ‘gethostbyname’);   //通常のmockと同様に使用できる $returnValue = ’192.168.0.1′; $mock->expectOnce(’env’, array(’REMOTE_ADDR’)); $mock->setReturnValue(’env’, $returnValue, array(’REMOTE_ADDR’)); $mock->expectNever(’gethostbyname’);   $this->assertEqual($returnValue, GlobalFunction()->env(’REMOTE_ADDR’));   //ClassRegistry::flush を呼び出せば元に戻る ClassRegistry::flush();   //本物の関数envが呼ばれる $addr = GlobalFunction()->env(’REMOTE_ADDR’); } 注意:参照を引数に取る関数(array_push など)は使用できません。

mod_rewriteを使ってドキュメントルートを分割する

(特にCakePHPに限定される話題ではありませんが、CakePHPの.htaccessを例に説明します) 通常、Webアプリケーションを構成するファイルは全てソースコード管理システムの管理下に置き、何らかのデプロイツールを用いて本番環境に転送します。本番環境でファイルを直接編集することはしません。 しかし時には一部の画像ファイルやCSSファイルを管理から除外して、自由に編集できるようにしたい場合があります。そういう場合は mod_rewrite を活用して、本来のドキュメントルートの他にもう一つ別のディレクトリを実質的なドキュメントルートとして割り当てることで、高い柔軟性を持たせることができます。 前提 CakePHPで構築したアプリケーションが /var/www/cake にあり、ドキュメントルートは /var/www/cake/app/webroot である。CakePHPデフォルトの .htaccess は次の通り。 RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] やりたいこと /home/files/public に置いたファイルに対して、あたかもドキュメントルートに置いたかのようにアクセスさせたい。 例) /home/files/public/css/main.css に対して http://example.com/css/main.css でアクセスできる。 シンボリックリンクの作成とmod_rewriteの設定 まずドキュメントルート内に /home/files/public に対するシンボリックリンクを適当な名前で作成します。当該ディレクトリに対して Options FollowSymlinks の権限が必要です。 ln -s /home/files/public /var/www/cake/app/webroot/__files 次に mod_rewrite の設定を追加します。 RewriteEngine On RewriteCond %{DOCUMENT_ROOT}/__files/%{REQUEST_URI} -d [OR] RewriteCond %{DOCUMENT_ROOT}/__files/%{REQUEST_URI} -f RewriteRule [...]

第5回CakePHP勉強会に参加してきました

5月29日の『第5回CakePHP勉強会』に参加してきました。 京都から東京まで移動するため、今回初めて夜行バスを使ったのですが……失敗でした。想像以上に揺れがひどくて椅子が堅くて、ほとんど眠れなかったのです。おまけに東京はあまり天気がよくなくて、汗だくになったかと思うと寒くて震えるというような気温の変化が連続して、勉強会会場にたどり着いたときには既に満身創痍という有様でした。 そんなこんなで、プレゼンのたび電気が消されるたびに意識が飛びそうになるのを懸命に堪えつつ、きっちり懇親会まで参加してきました。その感想です。 技術ネタ 全部は書ききれないので、私がコメントできそうなものを選んで感想を書いています。プログラムの全体はEvent Entry::第5回CakePHP勉強会@TokyoおよびMASA-Pさんのブログ記事をご覧ください。 CakePHP1.3の概要 市川さん(@cakephper) betaのころから1.3を使っていたので、発表中いくつかの機能については「そういえばこれは1.3の新機能だったな」と妙な感慨を持って聞いていました。それだけ1.3の新機能は利便性が高く、一度使えば当たり前になるということです。 一方で、それら新機能の実践的なノウハウについてはまだまだこれから発見・共有されていく段階だな、とも感じました。例えば当日 #cakephpstudy のTLでは「libsとverndorsの使い分けはどうするの?」という疑問が流れていましたし、スライド中routeClassの例として『Using custom Route classes in CakePHP』から転載されたコードは、直接Modelをnewしているためにテスタビリティに難があります。そうしたノウハウはいずれこのブログなどでもまとめていければと思います。 Ktai Library on CakePHP1.3 滝下さん(@ecworks_masap) 幸か不幸かまだ本格的な携帯サイトを作った事はないのですが、将来作るとなったらほぼ間違いなくお世話になるであろうライブラリなので、興味深く聞くことができました。最新版ではktai-devという形でライブラリ統合済のCakeコアも配布しているとのことで、もはや一ライブラリというよりも「CakePHPをベースとした用途特化型フレームワーク」に近づきつつあると言えそうです。それすなわち、CakePHP 1.xの成熟度が一定のレベルに達した証左だと言えるかもしれません。 ただそうして「ライブラリ」がカバーする範囲が大きくなればなるほど、ソフトウェアとしての Responsibility も大きくなります。その点については懇親会で直接お話しさせていただく機会があったのですが、やはり既存のライブラリ・サービスとの兼ね合いや、本来キャリアが提供すべき情報をどこまでサポートすべきかといった点について苦労されているようでした。 コアライブラリのエレガントなハック 清水紘己さん(@hiromi2424) 「Cakeコアの構成要素をいかにエレガントに置き換えるか」という、なかなか聞く人を選ぶ話題でした。個人的には大好物です。特にコンポーネント初期化処理をハックする苦労を味わった同士として、懇親会では固い握手を交わさせていただきました。 CakePHP2.0の概要を見たときに「エイリアス」というのがイマイチ何なのかピンと来なかったのですが、この発表を聞いていてよく理解できました。静的型付言語でいうと置き換えられる「名前」がインターフェイスを規定し、置き換えるクラスが実装クラスという事になります。依存関係が生ずる対象がクラスではなく「名前」なので、コア内部の依存関係であっても後から置き換える事が可能になります。 「CakePHPでjQueryを使ってみた(仮)」 – @nano_eightさん CakePHPでjQueryを使うなら下手にHelperなど使うよりも直接JavaScriptを書いた方が早い……と考えていたので、flashとelementの組み合わせ+SCRIPTタグべた書きという手法は目から鱗でした。Cake/PHP, JavaScriptそれぞれを分けて考えるのではなく、トータルで最も効率の良い方法をこそ考えていくべきなんだな、と認識を改めました。 「WordPressの管理画面のプラグインにCakePHPを使う」- 原さん(@kara_d) 「あのCMS eZ publishをCakePHPのModelにしちゃう」- @leebennyさん 他のPHP製ソフトウェアとCakePHPを組み合わせて使用する、というアイデアは多くの人が検討したことがあるだろうと思います(私もあります)。@kara_dさんのWordPressプラグインではDispatcherを無効にしたindex.phpを読み込むという大胆な手法で、@leebennyさんのeZ publishではDataSourceを実装するという正攻法で、これを実現されていました。いずれも他のソフトウェアに応用可能な方法だろうと思います。またCakeとは直接関係ありませんが、eZ publishの概略について学べたのも良かったです。 会場・コミュニティの雰囲気など 発表の様子は常時Ustreamで配信され、全国各地のサテライト会場に中継がつながっており、海外からの発表がSkype経由で行われ、会場では記念ロゴ入りのマシュマロが配られ……「コミュニティーベースの勉強会でここまでのことができるようになったのか!」と感嘆せずにはいられませんでした。 この種の勉強会に参加するのが初めてということもあり、正直なところ、ちょっと距離感を掴むのに戸惑ったというのも事実です。ただ懇親会で近くで飲んでいた@nano_eightさんのところに「プレゼン良かったですよ!」と多くの人が集まるのを見て「うらやましいなー」と思ったのもまた事実で、次の機会にはぜひ発表者として参加しよう!と思いました(実は今回もLTのお誘いは受けていたのですが、忙しさと不慣れを理由に断っていたのです)。 …… 東京散策ではiPhoneが超役に立ちました。慣れない都市で迷わずに動き回るコツは「自分の勘を一切信用しないこと」なのです。午前中は国立新美術館で開催中の「オルセー美術館展」を堪能しました。モネの『ロンドン国会議事堂、霧の中に差す陽光』とゴッホの『星降る夜』には魂が震えました。もう一回見に行きたいくらいです。久しぶりに歩き回った東京は広々としていました。京都と比べればほとんどどんな土地も広々と感じるのですが、東京も例に漏れず、ずいぶんと空間に余裕があるなあ、と思いました。

find(‘list’) で集約関数を使用する方法

単に field パラメータに指定するだけではうまく動作しないので、一旦 find(‘all’) で結果を取得してから Set::combine を使って同等の構造を得る。 // user_id => 件数 $tmp = $Post->find(’all’, array(’fields’ => array(’user_id’, ‘COUNT(*) AS posts_count’), ‘group’ => ‘user_id’)); return Set::combine($tmp, ‘{n}.Post.user_id’, ‘{n}.0.posts_count’); Set::combine は恐ろしく多機能なので、find(‘list’) をそのまま使うよりずっと多くの事ができる。例えば次のように、複数カラムで GROUP BY した結果をフラットな配列にまとめることができる。 // "user_id:category_id" => 件数 $tmp = $Post->find(’all’, array(’fields’ => array(’user_id’, ‘category_id’, ‘COUNT(*) AS posts_count’), ‘group’ => array(’user_id’, ‘category_id’))); return Set::combine($tmp, array(’{0}:{1}’, ‘{n}.Post.user_id’, [...]

jQuery History is now on Github

I created a fork of jQuery History plugin on Github. http://github.com/tkyk/jquery-history-plugin (the latest source code) Issue Tracking System: http://github.com/tkyk/jquery-history-plugin/issues Test page: http://www.serpere.info/jquery-history-plugin/sample/ Though this is just a fork for now, Mikage Sawatari, the original author of this plugin, and I agreed that it could be the mainstream in the near future. I’ve already done some [...]

メールの送信をテストする

環境: CakePHP1.3 ComponentTestCaseを使ってメールの送信をテストする方法をまとめておきます。Qdmailerを使うことを前提としていますが、標準のEmailComponentなど他のコンポーネントでも同じようにテストできると思います。 単純なケース メール送信をテストする上で最も重要なことは、メールの種類ごとにコンポーネントを作るということです。 まずメール送信コンポーネントに共通の振る舞いを定義するため、以下のような Mailer クラスを app/libs に作ります。 実際のインターフェイスや初期化処理などは自分のアプリケーションに合わせて調整してください。 abstract class Mailer extends Object { var $components = array(’Qdmailer.Qdmailer’); var $_controller; var $_settings;   function initialize($controller, $settings=array()) { $this->_controller = $controller; $this->_settings = $settings; }   function create() { }   protected function _rawSend() { $this->Qdmailer->send(); }   function send() { $this->Qdmailer->resetHeaderBody(); $args [...]

『Webを支える技術』のER図が変な件

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESSプラスシリーズ) すごく良い本なんですが、どうしても気になってしまったので、この部分だけ先に書きます。297ページ、17.2『関係モデルからの導出』で示されている郵便番号の関係モデルは変だと思います。ER図は次のようになっています: これのどこが変かというと……要するに正規化が不十分なので、いろいろなところが変です。 郵便番号エンティティが都道府県エンティティと市区町村エンティティを別々に参照しているので、「東京都のIDと大阪市のIDをもつ郵便番号」のようなものが作れてしまいます。 市区町村エンティティが都道府県エンティティに依存していないので、「どの都道府県にも属さない市区町村」が作れてしまいます。 町域エンティティが郵便番号エンティティに入り込んでいます(町域名フリガナは町域名に関数従属する) 町域と都道府県-市区町村の関係が保証されていないので、「東京都のIDと大阪市のIDと愛知県の町域名」みたいなものが作れてしまいます。 実装のことはさておき、純粋にデータの数的な関係に着目するなら、モデルは次のようになるのではないかと思います。 (モデルの”意味”を明確に示すために、あえて数値のIDではなく都道府県名や郵便番号などをそのままPRIMARY KEYとしています。また町域と郵便番号の関係などは日本郵便のサイトを参考にしています) 『Webを支える技術』300ページでは「階層構造は関係モデルからはわかりにくい」とありますが、それは誤解だと思います。普通は正規化を進めれば進めるほどエンティティの階層は深くなっていくはずです。市区町村->町域という階層も上のモデルからは自明です。むしろいかに階層を(正規化を)崩してリソースを抽出するかのほうが難しいと思います。 私はモデリングの専門家ではありませんので、勘違いしている点があったら教えてください。

まぐれ—投資家はなぜ、運を実力と勘違いするのか

『まぐれ―投資家はなぜ、運を実力と勘違いするのか』の感想。 著者は『ブラック・スワン』のナシーム・ニコラス・タレブ氏。この本は『ブラック・スワン』の一つ前にあたる著作。 日本語の副題「投資家はなぜ、運を実力と勘違いするのか」が的確に内容を要約している。哲学やら社会学やら心理学やら、かなり幅広い話題を扱っているが、結局のところ「市場においてトレーダーはどう振る舞うべきか」というテーマが中心にあって、トレーダーとしての自身の経験と運用哲学が根底にある。非合理的な振る舞いを繰り返す同僚たちをバカだアホだとこき下ろしながらも、実はその一部は自分自身のことで、人間はどうやっても合理的になりきれないと告白する。自分が愚かであることを理解し、受け入れた上で、うまく向き合っていく方法を身につけるしかないのだと。 この本は著者がそういう自分のやり方に、自分で納得するために書いているのではないか、と思える部分がある。結構ドギツイ文章を書く人で、読んでいてうんざりしてしまうことも多かったが(特に前半)、実際はとても正直な人なのだろう。 以下、特に印象に残った内容を6章以降から。この本は6章から俄然面白くなるので、6章までは頑張って読み進めることをお勧めする。 「確率」と「期待値」を混同してはいけない。0.7の確率で1%の上昇、0.3の確率で10%下落なら、期待値は2.3%の下落だから下落にかけた方が良い。勝つ可能性が高くても、それで儲かるとは限らない。 確率と期待値を混同してしまう原因の一つは、確率を習うときにコインの裏表のような対称な分布を使うから。正規分布も典型的に対称な分布。 稀な事象は、めったに起こらないというだけで、起こるときには起こる。そしていつも思いがけないときに起こるので(そうでなければ稀な事象ではない)、起こったときには心理的なバイアスによって適正な値段がつかないことが多い。よって大きく儲けるチャンスがある。 人間は刺激の大きさよりも刺激の有無に敏感な傾向がある。だからトータルで利益が出るかどうかではなく、「損失の回数が少なく、利益の回数が多い」ような戦略を選んでしまう(日本で毎月分配型の投資信託が好まれる理由?) ある理論が「検証可能」であるということは、数量的な要素に分解して統計的に調べることができるということ。よって間違っていると証明すること(反証)はできるが、正しいと証明することはできない。「(今まで)〜ということはなかった」は「(これからも)〜ことはない」とイコールではない。 科学的と言える理論は2種類しかない。(1).反証されて、間違いであることが分かっている理論。(2).まだ反証されていないが、いずれ反証される可能性のある理論。反証できない理論は科学ではない。 取引戦略を立てる時も反証可能性について考えることは重要。どういう状況になったら自分の戦略が間違っていたことになるのかをはっきりさせておき、そうなったときには即座に手仕舞う(ストップロス)。 そして個人的にこの本の中で最も面白いと思ったのは、無限匹のサルがタイプライタを叩く話(170ページ)。サルが無限匹いれば、中には偶然に名作を書き上げてしまう奴が必ず一匹は現れる。ここまでは割とよく聞く例え話だ。しかしここからが面白い:名作を書き上げたその一匹があなたのもとを訪れて、自分で書き上げたその「過去の実績」を示し、パトロンになってくれと頼んできたらどうだろう!そのサルがその名作を書き上げたのは紛れもない事実なのだ。そしてその他大勢のサルたちは皆(特に目立った成果を挙げられなかったのだから当然)どこかに行ってしまった。あなたの目の前にいるのは”奇跡のサル”だけだ……。 どんなに無能な集団でも、母集団が十分大きければ、必ず一定数は成功する。成功しなかった大多数は消えてしまうので、あとから見ると成功した一部しか目に入らない(これを生存バイアスという)。よって「過去にどれだけの実績を上げてきたか」が分かっても意味がない。当初その人が属していた母集団の大きさをこそ知らなければいけない。

複雑なコンポーネントの単体テスト

環境: CakePHP1.3 単純な場合のテスト方法はクックブックに載っていますが、 より複雑な場合(コントローラや他のコンポーネントと連携する場合)は多くの準備作業が必要です。 その作業を省略するための ComponentTestCase クラスを作りました。ソースコードはとりあえずgistに置いておきます。 component_test_case.php 適当な場所 app/tests/libs などに置いてテストファイルの中で読み込んでください。 Fooコンポーネントをテストする場合の例は次のようになります。 require_once (TESTS .’libs/component_test_case.php’);   class FooTestCase extends ComponentTestCase { //コントローラの $components と全く同じ書式 var $components = array(’Foo’ => array(’a’ => ‘b’));   function testAdd() { //$this->Controller でコントローラにアクセスできる $this->Controller->set(array(’var1′ => 1, ‘var2′ => 2));   //$this->{コンポーネント名} でコンポーネントのインスタンスにアクセスできる $this->assertEqual(3, $this->Foo->add());   //Fooの中で別のコンポーネントBarを読み込むことも可能 //$components = array(‘Bar’); $this->Foo->Bar->barmethod(); [...]