MoleTrust

MoleTrust is a local trust metric proposed by Paolo Massa and Paolo Avesani.

Users are ordered based on their distance from the source user, and only trust edges that go from distance n to distance n+1 are regarded. The trust value of users at distance x only depend on the already calculated trust values at distance x-1. The scores that are lower than a specific threshold value are discarded, and the trust score is the average of the incoming trust statements weighted over the trust scores of the nodes at distance x-1. It is possible to control the locality by setting the trust propagation horizon, I.e. the maximum distance to which trust can be propagated.

Input trust network
digraph G { node [style=filled fillcolor="#ffBB88"] ratio="0.6"; Alice -> Bob [label="0.8"]; Alice -> Carol [label="0.1"]; Alice -> Dave [label="1.0"]; Bob -> Carol [label="0.5"]; Bob -> Eve [label="0.6"]; Carol -> Bob [label="0.9"]; Carol -> Eve [label="1.0"]; Carol -> Ivan [label="0.9"]; Dave -> Eve [label="0.9"]; Frank -> Ivan [label="1.0"]; Frank -> Gina [label="0.8"]; Gina -> Hugh [label="0.7"]; Hugh -> Gina [label="0.3"]; Ivan -> Jane [label="0.5"]; Jane -> Ivan [label="0.9"]; }

Moletrust first step (with active user "Alice", trust propagation horizon set to 2 and trust threshold set to 0.5)
Users are sorted based on shortest distance from the active user "Alice". Only users inside the trust propagation horizon are kept. Only trust edges going from users at distance n to users at distance n+1 are kept. Only trust edges greater than the trust threshold are kept.

digraph G { graph [overlap=false] node [style=filled fillcolor="#ffBB88"] ratio="0.6"; rankdir=LR; { rank=same; Alice; } { rank=same; Bob;Dave;Carol } { rank=same; Eve;Ivan; } { rank=same; Jane;Frank;Gina;Hugh;} Alice -> Bob [label="0.8"]; Alice -> Dave [label="1.0"]; Alice -> Carol [label="0.1"]; Bob -> Carol [style="invis"]; Bob -> Eve [label="0.6"]; Carol -> Bob [style="invis"]; Carol -> Eve [label="1.0"]; Carol -> Ivan [label="0.9"]; Dave -> Eve [label="0.9"]; Frank -> Ivan [style="invis"]; Frank -> Gina [style="invis"]; Gina -> Hugh [style="invis"]; Hugh -> Gina [style="invis"]; Ivan -> Jane [style="invis"]; Jane -> Ivan [style="invis"]; }

Moletrust second step
The predicted trust score of a user is the average of all kept incoming trust edge values, weighted by the trust score of the user who has issued the trust statement.

For example, the predicted trust score of Eve is (0.8*0.6+1.0*0.9)/(0.8+1.0) = 0.767

digraph G { graph [overlap=false] node [style=filled fillcolor="#ffBB88"] ratio="0.6"; rankdir=LR; { rank=same; Alice [label="[1.0]\nAlice"]; } { rank=same; Bob [label="[0.8]\nBob"]; Dave [label="[1.0]\nDave"]; Carol [label="[0.1]\nCarol"]; } { rank=same; Eve [label="[0.767]\nEve"]; Ivan [label="[?]\nIvan"]; } { rank=same; Jane [label="[?]\nJane"]; Frank [label="[?]\nFrank"]; Gina [label="[?]\nGina"]; Hugh [label="[?]\nHugh"]; } Alice -> Bob [label="0.8"]; Alice -> Dave [label="1.0"]; Alice -> Carol [label="0.1"]; Bob -> Carol [style="invis"]; Bob -> Eve [label="0.6"]; Carol -> Bob [style="invis"]; Carol -> Eve [label="1.0"]; Carol -> Ivan [label="0.9"]; Dave -> Eve [label="0.9"]; Frank -> Ivan [style="invis"]; Frank -> Gina [style="invis"]; Gina -> Hugh [style="invis"]; Hugh -> Gina [style="invis"]; Ivan -> Jane [style="invis"]; Jane -> Ivan [style="invis"]; }

Some Python code
def moletrust_generator(horizon = 3, pred_node_trust_threshold = 0.5,                       edge_trust_threshold = 0.0): """Generate moletrust trust metric functions.

Parameters:

horizon: how many levels deep to search the network for a path (the bigger the horizon the slower the calculation)

pred_node_trust_threshold: if an edge in the calculated chain has a trust value below this it will be discarded, because we     know from this node on the chain is distrusted.

edge_trust_threshold: an edge with trust < edge_trust_threshold will be thown out. """   def moletrust_tm(G, a, b):        debug = False        if debug:            print "predict trust from", a, "to", b

# Do something with connected_components here? # UG = G.to_undirected # subgraphs = connected_component_subgraphs(UG) # find a       # if b not in subgraph_with_a: #  return None # path_length_dict and trust_map should be cached in a very smart way path_length_dict = path.single_source_shortest_path_length(G, a, horizon) if b not in path_length_dict or path_length_dict[b] > horizon: return None path_length_list = [(y,x) for x,y in path_length_dict.items] path_length_list.sort # order by distance

# initialize trust map with node a and a bunch of empty dicts trust_map = [{a: 1.0}] + [{}] * horizon

for (dist, node) in path_length_list[1:]: useful_in_edges = [x in G.in_edges(node) if x[0] in trust_map[dist-1]] # We have to benchmark this, it could be a lot faster? #if len(useful_in_edges) == 1: #   pred_trust = G.trust_on_edge(useful_in_edges[0])

# not considering the negative trust (or e.g. <0.5) # statements, very good for our accuracy! yay! big hugs! useful_in_edges = [x in useful_in_edges if G.trust_on_edge(x) >= edge_trust_threshold] for edge in useful_in_edges: if debug: print "useful edge:", edge, "predecessor tvalue", trust_map[dist-1][edge[0]] pred_trust = weighted_average([(G.trust_on_edge(x), trust_map[dist-1][x[0]])                                          for x in useful_in_edges]) if node == b:               return pred_trust

# only keep edges over pred_node_trust_threshold if pred_trust >= pred_node_trust_threshold: trust_map[dist][node] = pred_trust return None return moletrust_tm