package happy.research.tp;
import happy.coding.io.Logs;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
/**
* Implement Nguyen et al.'s approach in ICDM 2009:
*
* To Trust or Not to Trust? Predicting Online Trusts using Trust Antecedent
* Framework
*
* @author guoguibing
*
*/
public class TAF extends TrustModel {
public TAF() {
model = "TAF";
}
@Override
protected void global() throws Exception {
Logs.debug("Starting global evaluation ...");
// benevolence
for (String rv : rws)
rqs.put(rv, 0.0f);
// beta's value could significantly influence the convergence of digg's
// algorithm
// and the overall performance
float beta = 0.5f;
int iter = 0;
while (true) {
float err = 0f;
int pg_rv = 0, pg_user = 0;
// compute review quality
for (String rv : rws) {
if (pg_rv % 3000 == 0)
Logs.debug("Current progress: iteration {} with review: {}/{}",
new Object[] { iter + 1, pg_rv, rws.size() });
pg_rv++;
Map<String, Float> urs = ratings.column(rv);
String v = reviewUserMap.get(rv); // who write this review
float sum = 0f;
int cnt = 0;
for (Entry<String, Float> en : urs.entrySet()) {
String u = en.getKey();
float rate = en.getValue();
if (!lns.contains(u, v))
lns.put(u, v, (float) Math.random()); // lazy initialization
float ln = lns.get(u, v);
sum += rate * (1 - beta * ln);
cnt++;
}
if (cnt > 0) {
float rq = logic(cnt, 0.1f, 5) * (sum / cnt);
float last_rq = rqs.get(rv);
rqs.put(rv, rq);
float e = last_rq - rq;
err += e * e;
}
}
// update local leniency
for (String u : users) {
if (pg_user % 3000 == 0)
Logs.debug("Current progress: iteration {} with user: {}/{}", new Object[] { iter + 1, pg_user,
users.size() });
pg_user++;
for (String v : users) {
if (u.equals(v))
continue;
Collection<String> rvs = reviews.get(v);
Map<String, Float> rts = ratings.row(u);
float sum = 0f;
int cnt = 0;
for (String rv : rvs) {
if (rts.containsKey(rv)) {
float rt = rts.get(rv);
float rq = rqs.get(rv);
sum += (rt - rq) / rt;
cnt++;
}
}
if (cnt > 0) {
float ln = sum / cnt;
float last_ln = lns.get(u, v);
lns.put(u, v, ln);
float e = last_ln - ln;
err += e * e;
}
}
}
Logs.debug("Iteration: {}, Error: {}", ++iter, err);
if (err < 1e-5)
break;
}
// find out min, max of lns
float[] mms = minMax(lns.values());
min_lns = mms[0];
max_lns = mms[1];
// compute gls
for (String u : users) {
float sum = 0;
int cnt = 0;
for (String v : users) {
if (u.equals(v))
continue;
if (lns.contains(u, v)) {
float ln = lns.get(u, v);
sum += (ln - min_lns) / (max_lns - min_lns);
cnt++;
}
}
if (cnt > 0)
gls.put(u, sum / cnt);
}
Logs.debug("Done!");
}
@Override
protected float local(String u, String v) throws Exception {
float ab = 0f, be = 0f, in = 0f, tp = 0f;
Collection<String> rvs = reviews.get(v);
Map<String, Float> rts = ratings.row(u);
// ability
float sum = 0f;
int cnt = 0;
for (String rv : rvs) {
if (rts.containsKey(rv)) {
sum += rts.get(rv);
cnt++;
}
}
if (cnt > 0)
ab = (sum / cnt) * logic(cnt, 0.1f, 5); //TODO: 0.1 to 0.5
// benevolence
if (lns.contains(u, v))
be = (lns.get(u, v) - min_lns) / (max_lns - min_lns);
// integrity: based on number of users who trust this user
in = 1.0f; // no trust is assumed
// trust propensity
tp = gls.containsKey(u) ? gls.get(u) : 0f;
return ab * be * in * tp;
}
}