2008年08月12日

集合知プログラミング

わかりもしないのに購入して
本棚に飾っていた集合知プログラミング

仕事に行き詰まって現実逃避代わりに読み始める。
取りあえずPythonは知らないので無理矢理PHPに訳して
11Pのユークリッド距離によるスコアのプログラムまで読んだ。

差の二乗の平方根で距離が分かるのは、昔高校でやったきがする。

さらに1を加えて、逆数を取ることで0-1の範囲に収まるのもなんとなく分かる。
差が0なら1になり後は徐々に差がつくたびに0に近づく

ただ、11Pのコードを読むと
平方根出さずにいるのが不思議だ。

あれか、2次元じゃないからかな?
要素数分の根?累乗根?を取ったら駄目なのか?
それはまた別のお話?



取りあえず適当にPHPでかいてみた。
本に合わせて「recommendations.php」としてみる。

<?php

$critics = array( 'Lisa Rose' => array( 'Lady in the Water' => 2.5,
'Snakes on a Plane' => 3.5,
'Just My Luck' => 3.0,
'Superman Returns' => 3.5,
'You, Me and Dupree' => 2.5,
'The Night Listener' => 3.0,
),
'Gene Seymour' => array( 'Lady in the Water' => 3.0,
'Snakes on a Plane' => 3.5,
'Just My Luck' => 1.5,
'Superman Returns' => 5.0,
'You, Me and Dupree' => 3.5,
'The Night Listener' => 3.0,
),
'Michael Phillips' => array( 'Lady in the Water' => 2.5,
'Snakes on a Plane' => 3.0,
'Superman Returns' => 3.5,
'The Night Listener' => 3.0,
),
'Claudia Puig' => array( 'Snakes on a Plane' => 3.5,
'Just My Luck' => 3.0,
'Superman Returns' => 4.0,
'You, Me and Dupree' => 2.5,
'The Night Listener' => 4.5,
),
'Mick LaSalle' => array( 'Lady in the Water' => 3.0,
'Snakes on a Plane' => 4.0,
'Just My Luck' => 2.0,
'Superman Returns' => 3.0,
'You, Me and Dupree' => 2.0,
'The Night Listener' => 3.0,
),
'Jack Matthews' => array( 'Lady in the Water' => 3.0,
'Snakes on a Plane' => 4.0,
'Superman Returns' => 5.0,
'You, Me and Dupree' => 3.5,
'The Night Listener' => 3.0,
),
'Toby' => array( 'Snakes on a Plane' => 4.5,
'Superman Returns' => 4.0,
'You, Me and Dupree' => 1.0,
),
);

// person1とperson2の距離を基にした類似性スコアを返す。
//返り値は0-1の範囲で1に近いほど類似性がある。
function sim_distance($prefs, $person1, $person2){
$si = array();

//二人とも評価しているアイテムのリストを得る。
foreach($prefs["$person1"] as $item => $val){
if(isset($prefs["$person2"]["$item"])){
$si["$item"] = 1;
}
}
if(count($si) == 0){ return 0;}

//すべての差の平方を足し合わせる。
//上のループでできるよな
$sum_of_squares = 0;
foreach($prefs["$person1"] as $item => $val){
if(isset($prefs["$person2"]["$item"])){
$sum_of_squares += pow( ( $prefs["$person1"]["$item"]
- $prefs["$person2"]["$item"]
),
2);
}
}

return 1/(1 + sqrt($sum_of_squares));

}
?>


で、実際結果を出してみる。


<?php
require("recommendations.php");

var_dump( sim_distance($critics,'Lisa Rose','Gene Seymour') );//0.148148148148?
var_dump( sim_distance($critics,'Lisa Rose','Lisa Rose') );
var_dump( sim_distance($critics,'Lisa Rose','Toby') );

?>


結果は・・・

float 0.14814814814815

float 1

float 0.22222222222222



最初の最後の桁は丸めてるのかな?
posted by Belial at 00:15 | Comment(0) | TrackBack(0) | | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。