基于Epinions数据集的MoleTrust推荐系统信任值计算错误排查求助
Let's break down the issues in your code step by step, since you're getting only 0/1 values instead of the fractional trust scores expected from the MoleTrust algorithm:
1. Integer Division is Causing Truncated Results
The biggest culprit here is integer division in your trust value calculation. In Java, when you divide two integers, the result is always an integer (truncated towards zero). For your formula (horizon - dist +1)/horizon:
- When
dist = 1, you get(horizon -1 +1)/horizon = horizon/horizon = 1 - For any
dist >1,(horizon - dist +1)will be less thanhorizon, so the division result truncates to 0
Fix: Cast one of the operands to double to force floating-point division:
double trust_value = (double)(horizon - dist + 1) / horizon;
2. You're Ignoring the Original Direct Trust Values
According to the MoleTrust logic and your referenced paper, the propagated trust score should combine the direct trust value from the source user's neighbor with the distance-based decay factor. Right now, you're assigning only the decay factor to trust_value, completely ignoring the actual trust values stored in trust_data.
Fix: Multiply the decay factor by the direct trust value from trust_data:
double directTrust = tns.get(tu); double trust_value = directTrust * (double)(horizon - dist + 1) / horizon;
3. You're Overwriting Trust Scores for Users with Multiple Paths
Your current code overwrites the trust score for a target user (tu) every time it's encountered via a different source user (su). But MoleTrust typically aggregates scores from multiple paths (e.g., keeping the maximum score, which is common in trust propagation algorithms).
Fix: Only update the trust score if the new calculated value is higher than any existing score for that user:
double directTrust = tns.get(tu); double trust_value = directTrust * (double)(horizon - dist + 1) / horizon; if (!trustScores.containsKey(tu) || trust_value > trustScores.get(tu)) { trustScores.put(tu, trust_value); }
4. Redundant edges Collection
You spend time building the edges map in Step 1, but it's never used in Step 2 to calculate trust scores. You can safely remove this unused code to clean up your implementation.
Modified Step 2 Code Snippet
Here's how the corrected trust score calculation section should look:
/* Step 2: Evaluate trust score */ dist = 0; HashMap<String, Double> trustScores = new HashMap<>(); trustScores.put(sourceUser, 1.0); while (dist < horizon) { dist++; for (String su : users[dist - 1]) { Map<String, Double> tns = trust_data.get(su); if (tns == null) continue; for (String tu : tns.keySet()) { // Skip if user is already processed (from earlier distance levels) if (trustScores.containsKey(tu)) continue; double directTrust = tns.get(tu); double trust_value = directTrust * (double)(horizon - dist + 1) / horizon; trustScores.put(tu, trust_value); } } } trustScores.remove(sourceUser); return trustScores;
Note: I added a check to skip users already in trustScores since your Step 1 ensures each user is only added to one users[dist] list—this prevents unnecessary reprocessing.
内容的提问来源于stack exchange,提问作者Samar

