nandi/gleanpublic⑂ Fork 0
⑂ 59d6bbb
Commits
⬇ Clone ▾
git clone https://git.rickub.com/nandi/glean.git
git clone ssh://git@rickub.com/nandi/glean.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Increase people recommendation diversityUnverified

Julien Robert committed 2026-04-29T13:29:13+02:00 Browse files
59d6bbb parent: be4aec4
modified internal/cluster/scoring.go +22 -3
@@ -68,13 +68,32 @@ func (e *Engine) GetFeedRecommendations(ctx context.Context, userDID string, lim
6868 }
6969
7070 // GetPeopleRecommendations returns similar users based on subscription overlap,
71-// like co-occurrence, tag overlap, and follow relationships. Scores are min-max
72-// normalized on the Jaccard field.
71+// like co-occurrence, tag overlap, and follow relationships. Up to half the
72+// limit come from the user's network (followed) and half from outside. When
73+// outside-network candidates are scarce, in-network fills the remaining slots.
7374 func (e *Engine) GetPeopleRecommendations(ctx context.Context, userDID string, limit int) ([]*PersonRecommendation, error) {
74- recs, err := e.ComputePeopleRecommendationsOnDemand(ctx, userDID, limit)
75+ recs, err := e.ComputePeopleRecommendationsOnDemand(ctx, userDID, limit*2)
7576 if err != nil {
7677 return nil, err
7778 }
79+
80+ half := max(limit/2, 1)
81+
82+ var inNet, outNet []*PersonRecommendation
83+ for _, r := range recs {
84+ if r.IsFollowed {
85+ inNet = append(inNet, r)
86+ } else {
87+ outNet = append(outNet, r)
88+ }
89+ }
90+
91+ outTake := min(half, len(outNet))
92+ inTake := min(limit-outTake, len(inNet))
93+ recs = recs[:0]
94+ recs = append(recs, inNet[:inTake]...)
95+ recs = append(recs, outNet[:outTake]...)
96+
7897 normalizePersonScores(recs)
7998 return recs, nil
8099 }
@@ -68,13 +68,32 @@ func (e *Engine) GetFeedRecommendations(ctx context.Context, userDID string, lim
68 }68 }
69 69
70 // GetPeopleRecommendations returns similar users based on subscription overlap,70 // GetPeopleRecommendations returns similar users based on subscription overlap,
71-// like co-occurrence, tag overlap, and follow relationships. Scores are min-max71+// like co-occurrence, tag overlap, and follow relationships. Up to half the
72-// normalized on the Jaccard field.72+// limit come from the user's network (followed) and half from outside. When
73+// outside-network candidates are scarce, in-network fills the remaining slots.
73 func (e *Engine) GetPeopleRecommendations(ctx context.Context, userDID string, limit int) ([]*PersonRecommendation, error) {74 func (e *Engine) GetPeopleRecommendations(ctx context.Context, userDID string, limit int) ([]*PersonRecommendation, error) {
74- recs, err := e.ComputePeopleRecommendationsOnDemand(ctx, userDID, limit)75+ recs, err := e.ComputePeopleRecommendationsOnDemand(ctx, userDID, limit*2)
75 if err != nil {76 if err != nil {
76 return nil, err77 return nil, err
77 }78 }
79+
80+ half := max(limit/2, 1)
81+
82+ var inNet, outNet []*PersonRecommendation
83+ for _, r := range recs {
84+ if r.IsFollowed {
85+ inNet = append(inNet, r)
86+ } else {
87+ outNet = append(outNet, r)
88+ }
89+ }
90+
91+ outTake := min(half, len(outNet))
92+ inTake := min(limit-outTake, len(inNet))
93+ recs = recs[:0]
94+ recs = append(recs, inNet[:inTake]...)
95+ recs = append(recs, outNet[:outTake]...)
96+
78 normalizePersonScores(recs)97 normalizePersonScores(recs)
79 return recs, nil98 return recs, nil
80 }99 }