use strict;
use warnings;
use List::Util qw/sum/;
use Data::Dumper;
my @data = (
{ A => 4, B => 5, C => 2, D => 4, F => 5 },
{ A => 2, C => 3, D => 4, E => 3 },
{ A => 1, B => 4, D => 5, E => 3, F => 4 },
{ B => 5, E => 2, F => 4 },
{ B => 3, C => 1, D => 3, F => 3 }
);
my @items = (qw/A B C D E F/);
my $ave = {};
for (0..$#data) {
$ave->{$_} = sum(values %{ $data[$_] }) / $#data;
}
my $dev = {};
for my $i (0..$#items) {
for my $j ($i+1..$#items) {
my $item1 = $items[$i];
my $item2 = $items[$j];
my $r = 0.0;
my $n = 0;
for my $k (0..$#data) {
my $user = $data[$k];
if(defined $user->{$item1} and defined $user->{$item2}) {
$r += $user->{$item2} - $user->{$item1};
$n++;
}
}
$r /= $n if $n > 0;
$dev->{$item1}->{$item2} = [$r, $n];
$dev->{$item2}->{$item1} = [-$r, $n];
}
}
my $a;
for (0..$#data) {
my $u = $data[$_];
my @user;
for my $item (@items) {
push @user, $item unless defined $u->{$item};
}
for my $user (@user) {
my $p;
my $r1 = 0.0;
my $r2 = 0.0;
for my $key (keys %{ $u }) {
my ($d, $n) = @{ $dev->{$key}->{$user} };
$r1 += ($d + $u->{$key}) * $n;
$r2 += $n;
}
$a->{$_}->{$user} = $r1 / $r2;
}
}
print Dumper $a;