今週やったこと
2013/10/19
今日は環境構築をしました。
集合知プログラミングを勉強しようとして、同時にGAE,AngularJSの習熟も出来たら良いじゃないか?と思い立った。
GAE開発サーバーにてAngular-seedを動かすところまで完了。
2013/10/20
ユークリッド距離とピアソン相関係数について読み、AngularJSで表示、Pythonコード例をJavascriptに手直しして計算をした。
ユークリッド距離はレビュー評価値の付け方に値の大小があると類似性の有無を求められない。代わりに計算が楽。
ピアソン相関係数は値の大小があっても類似性を求められる。代わりに計算量が少々多い。
function RecommendationsCtrl($scope, recommendations) {
// サクッと結果確認するための初期値
$scope.person1 = "Lisa Rose";
$scope.person2 = "Gene Seymour";
$scope.critics = recommendations.getCritics();
$scope.sim_distance = function() {
// 2人共評価しているアイテムのリストを得る。
var si = 0;
var person1 = 0;
var person2 = 0;
for(var i=0; i<$scope.critics.length; i++) {
if(person1==0 && $scope.critics[i].name==$scope.person1) {
person1 = $scope.critics[i];
}
if(person2==0 && $scope.critics[i].name==$scope.person2) {
person2 = $scope.critics[i];
}
}
for(var i=0; i<person1.marks.length; i++) {
for(var k=0; k<person2.marks.length; k++) {
if(person1.marks[i].title==person2.marks[k].title) {
si++;
}
}
}
// 両者共に評価しているものが1つもなければ0を返す。
if(si==0) {
$scope.similarity_score = 0;
return false;
}
// すべての差の平方を足し合わせる。
var sum_of_squares = 0;
for(var i=0; i<person1.marks.length; i++) {
for(var k=0; k<person2.marks.length; k++) {
if(person1.marks[i].title==person2.marks[k].title) {
sum_of_squares += Math.pow(person1.marks[i].score-person2.marks[k].score, 2);
}
}
}
$scope.similarity_score = 1/(1+sum_of_squares);
};
$scope.sim_pearson = function() {
// 両者が互いに評価しているアイテムのリストを取得。
var si = {}
var p1 = 0;
var p2 = 0;
for(var i=0; i<$scope.critics.length; i++) {
if(p1==0 && $scope.critics[i].name==$scope.person1) {
p1 = $scope.critics[i];
}
if(p2==0 && $scope.critics[i].name==$scope.person2) {
p2 = $scope.critics[i];
}
}
for(var i=0; i<p1.marks.length; i++) {
for(var k=0; k<p2.marks.length; k++) {
if(p1.marks[i].title==p2.marks[k].title) {
si[p2.marks[k].title] = {"p1": p1.marks[i].score, "p2": p2.marks[k].score};
}
}
}
// 要素の数を調べる。
var n = 0;
for(var key in si) {
n++;
}
// 共に評価しているアイテムがなければ0を返す。
if(!n) {
$scope.pearson_score = 0;
return false;
}
// すべての嗜好を合計する。
var sum1 = 0;
var sum2 = 0;
for(var key in si) {
sum1 += si[key].p1;
sum2 += si[key].p2;
}
// 平方を合計する。
var sum1Sq = 0;
var sum2Sq = 0;
for(var key in si) {
sum1Sq += Math.pow(si[key].p1, 2);
sum2Sq += Math.pow(si[key].p2, 2);
}
// 積を合計する。
var pSum = 0;
for(var key in si) {
pSum += si[key].p1*si[key].p2;
}
// ピアソンによるスコアを計算する。
var num = pSum-(sum1*sum2/n);
var den = Math.sqrt((sum1Sq-Math.pow(sum1,2)/n) * (sum2Sq-Math.pow(sum2,2)/n));
if(den==0) {
$scope.pearson_score = 0;
return true;
}
$scope.pearson_score = num/den;
}
}