Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kuniyoshi/3684962 to your computer and use it in GitHub Desktop.
Save kuniyoshi/3684962 to your computer and use it in GitHub Desktop.
Calculate Euclid, and Pearson Distance
-module(reco_cons).
-compile(export_all).
read() ->
{ok, D} = file:consult("reco.cons"),
D.
get_persons(Data) ->
{critics, D1} = lists:keyfind(critics, 1, Data),
[K || {K, _} <- D1].
calc_sim_distance([Data, PersonA, PersonB, euclid]) ->
calc_euclid_distance(prepare_calc(Data, PersonA, PersonB));
calc_sim_distance([Data, PersonA, PersonB, pearson]) ->
calc_pearson_distance(prepare_calc(Data, PersonA, PersonB)).
prepare_calc(Data, PersonA, PersonB) ->
{critics, D1} = lists:keyfind(critics, 1, Data),
{PersonA, PdA} = lists:keyfind(PersonA, 1, D1),
{PersonB, PdB} = lists:keyfind(PersonB, 1, D1),
Keys = lists:filter(fun (Key) ->
lists:keymember(Key, 1, PdB)
end, [Key || {Key, _} <- PdA]),
[PdA, PdB, Keys].
calc_euclid_distance([_, _, []]) ->
0.0;
calc_euclid_distance([PersonDataA, PersonDataB, Keys]) ->
lists:sum(lists:map(fun (Key) ->
{Key, VA} = lists:keyfind(Key, 1, PersonDataA),
{Key, VB} = lists:keyfind(Key, 1, PersonDataB),
1 / (1 + math:sqrt(math:pow(VA, 2) + math:pow(VB, 2)))
end, Keys)).
calc_pearson_distance([_, _, []]) ->
0.0;
calc_pearson_distance([PersonDataA, PersonDataB, Keys]) ->
VLA = [V || {_, V} <- [lists:keyfind(Key, 1, PersonDataA) || Key <- Keys]],
VLB = [V || {_, V} <- [lists:keyfind(Key, 1, PersonDataB) || Key <- Keys]],
SA = lists:sum(VLA),
SB = lists:sum(VLB),
SAP = lists:sum([math:pow(V, 2) || V <- VLA]),
SBP = lists:sum([math:pow(V, 2) || V <- VLB]),
SM = lists:sum(lists:map(fun (Key) ->
{Key, VA} = lists:keyfind(Key, 1, PersonDataA),
{Key, VB} = lists:keyfind(Key, 1, PersonDataB),
VA * VB
end, Keys)),
Length = length(Keys),
N = SM - (SA * SB / Length),
D = math:sqrt((SAP - math:pow(SA, 2) / Length) * (SBP - math:pow(SB, 2) / Length)),
case D of
0.0 ->
0.0;
_ ->
N / D
end.
%% reco.cons
%% {critics, [{"Lisa Rose",
%% [{"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",
%% [{"Lady in the Water", 3.0},
%% {"Snakes on a Plane", 3.5},
%% {"Just My Luck", 1.5},
%% {"Superman Returns", 5.0},
%% {"The Night Listener", 3.0},
%% {"You, me and Dupree", 3.5}]},
%% {"Michael Phillips",
%% [{"Lady in the Water", 2.5},
%% {"Snakes on a Plane", 3.0},
%% {"Superman Returns", 3.5},
%% {"The Night Listener", 4.0}]},
%% {"Claudia Puig",
%% [{"Snakes on a Plane", 3.5},
%% {"Just My Luck", 3.0},
%% {"The Night Listener", 4.5},
%% {"Superman Returns", 4.0},
%% {"You, Me and Dupree", 2.5}]},
%% {"Mick LaSalle",
%% [{"Lady in the Water", 3.0},
%% {"Snakes on a Plane", 4.0},
%% {"Jus My Luck", 2.0},
%% {"Superman Returns", 3.0},
%% {"The Night Listener", 3.0},
%% {"You, Me and Dupree", 2.0}]},
%% {"Jack Matthews",
%% [{"Lady in the Water", 3.0},
%% {"Snakes on a Plane", 4.0},
%% {"The Night Listener", 3.0},
%% {"Superman Returns", 5.0},
%% {"You, Me and Dupree", 3.5}]},
%% {"Toby",
%% [{"Snakes on a Plane", 4.5},
%% {"You, Me and Dupree", 1.0},
%% {"Superman Returns", 4.0}]}]}.
@kuniyoshi
Copy link
Author

--- output sample
62> f().
ok
63> c(reco_cons).
{ok,reco_cons}
64> PA = lists:nth(1, reco_cons:get_persons(reco_cons:read())).
"Lisa Rose"
65> PB = lists:nth(2, reco_cons:get_persons(reco_cons:read())).
"Gene Seymour"
66> reco_cons:calc_sim_distance([reco_cons:read(), PA, PB, euclid]).
0.9331349018354814
67> reco_cons:calc_sim_distance([reco_cons:read(), PA, PB, pearson]).
0.547619047619046
68>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment