/
ensemble_recommender.pl
121 lines (106 loc) · 2.58 KB
/
ensemble_recommender.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use strict;
use warnings;
use Repo;
use User;
use Lang;
use Result;
use Utils;
use constant {
DEF_K => 30
};
$|=1;
our @RECOMMENDER = (
{
file => "./results_forkbase.txt",
weight => 2.0,
K => DEF_K,
score => sub { 1.0 / (1.0 + $_[0]); }
},
{
file => "./results_co_occurrence.txt",
weight => 1.5,
K => DEF_K,
score => sub { 1.0 / (1.0 + $_[0]); }
},
{
file => "./results_author.txt",
weight => 0.6,
K => DEF_K,
score => sub { 1.0 / (1.3 + $_[0]); }
},
{
file => "./results_name.txt",
weight => 0.3,
K => DEF_K,
score => sub { 1.0 / (1.5 + $_[0]); }
},
{
file => "./results_popular.txt",
weight => 0.1,
K => 10,
score => sub { 1.0 / (1.0 + $_[0]); }
}
);
sub rank_score
{
my $rank = shift;
return (1.0 / (1.5 + $rank));
}
sub load_recommender
{
my $recommender = [];
foreach my $rec (@RECOMMENDER) {
print "loading.. $rec->{file}\r";
my $result = new Result($rec->{file}, $rec->{K});
my $weight = $rec->{weight};
push(@$recommender, { result => $result, weight => $rec->{weight}, K => $rec->{K}, score => $rec->{score} });
}
return $recommender;
}
ensemble_recommender:
{
print "$0: loading ..\r";
my $repo = new Repo("./download/repos.txt");
my $lang = new Lang("./download/lang.txt", $repo);
my $user = new User("./download/data.txt", $lang);
my $test = new Result("./download/test.txt", $lang);
my $count = $test->count();
my $i = 0;
my $recommender = load_recommender();
open(R, ">results_ensemble.txt") or die $!;
$repo->set_lang($lang);
$repo->ranking($user);
print "ok..\n";
foreach my $uid (@{$test->users()}) {
printf("$0: %.2f%% \r", 100 * $i / $count);
my @result_tmp;
my @result;
my %reco_repo;
my $user_repos = $user->repos($uid);
foreach my $reco (@$recommender) {
my $repos = $reco->{result}->repos($uid);
if (!defined($repos)) {
next;
}
for (my $i = 0; $i < $reco->{K} && $i < @$repos; ++$i) {
if (!exists($reco_repo{$repos->[$i]})) {
$reco_repo{$repos->[$i]} = 0.0;
}
$reco_repo{$repos->[$i]} += &{$reco->{score}}($i) * $reco->{weight};
}
}
foreach my $rid (keys(%reco_repo)) {
push(@result_tmp, { id => $rid, score => $reco_repo{$rid} });
}
@result_tmp = sort { $b->{score} <=> $a->{score} } @result_tmp;
foreach my $rid (@result_tmp) {
if (!Utils::includes($user_repos, $rid->{id})) {
push(@result, $rid->{id});
push(@$user_repos, $rid->{id});
}
}
print R Result::format($uid, @result);
++$i;
}
close(R);
}