bat-6 commited on
Commit
caa78f1
·
1 Parent(s): 48c0bec

feat: implement hybrid similarity and originality scoring logic for project ranking

Browse files
models/metadata.backup.parquet ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:33a3d8e57a016cf66922cbd0c013090f6d11f59712c45dac488dfad056f330ab
3
+ size 775966
models/metadata.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:fa65da476454398a5d7b124e338e0e4bc2c8015258b73e09fa28cad448f9a420
3
- size 773665
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6765e155f8c73dc97d9f9d681291a1bba2a9d6c59c6712dd51a96e0cccce8058
3
+ size 786476
src/similarity_model/__pycache__/hybrid_ranker.cpython-313.pyc CHANGED
Binary files a/src/similarity_model/__pycache__/hybrid_ranker.cpython-313.pyc and b/src/similarity_model/__pycache__/hybrid_ranker.cpython-313.pyc differ
 
src/similarity_model/hybrid_ranker.py CHANGED
@@ -40,17 +40,25 @@ def get_dynamic_weights(
40
  """
41
  Adaptive weights depending on feature richness.
42
  Returns (semantic_w, feature_w, coverage_w) — always sum to 1.0
 
 
 
 
43
  """
44
 
45
-
 
 
 
 
46
  if feature_count >= 5 and coverage >= 0.60:
47
  return 0.40, 0.45, 0.15
48
 
49
-
50
  if feature_count <= 2:
51
  return 0.70, 0.20, 0.10
52
 
53
-
54
  return 0.55, 0.35, 0.10
55
 
56
  def compute_hybrid_score(
@@ -109,16 +117,22 @@ def compute_originality(
109
  ) -> float:
110
  """
111
  Originality Score (0-100).
112
- Base score is (1 - hybrid_score) * 100.
113
- Bonus of up to +10 points when the query has many features
114
- that are unique vs the candidate (genuine differentiation signal).
 
 
 
 
115
  """
116
  hybrid_score = clamp(hybrid_score)
117
 
118
  originality = 100.0 * (1.0 - hybrid_score)
119
 
120
- # Uniqueness bonus: reward projects whose features don't overlap
121
- if total_query_features > 0:
 
 
122
  uniqueness_ratio = unique_query_features / total_query_features
123
  originality = min(100.0, originality + (uniqueness_ratio * 10.0))
124
 
 
40
  """
41
  Adaptive weights depending on feature richness.
42
  Returns (semantic_w, feature_w, coverage_w) — always sum to 1.0
43
+
44
+ NOTE: When coverage==0 (DB project has no stored features),
45
+ always fall back to the high-semantic-weight path so that
46
+ a rich multi-feature query is not penalised vs a sparse one.
47
  """
48
 
49
+ # No feature evidence at all — rely on semantic regardless of query richness
50
+ if coverage == 0:
51
+ return 0.70, 0.20, 0.10
52
+
53
+ # Rich features + high overlap → trust features heavily
54
  if feature_count >= 5 and coverage >= 0.60:
55
  return 0.40, 0.45, 0.15
56
 
57
+ # Sparse query features
58
  if feature_count <= 2:
59
  return 0.70, 0.20, 0.10
60
 
61
+ # Balanced
62
  return 0.55, 0.35, 0.10
63
 
64
  def compute_hybrid_score(
 
117
  ) -> float:
118
  """
119
  Originality Score (0-100).
120
+ Base: (1 - hybrid_score) * 100.
121
+
122
+ Uniqueness bonus (+up to 10 pts) is only applied when the DB project
123
+ actually has stored features (total_query_features > 0 AND there were
124
+ real feature matches to compare against). While DB features are empty,
125
+ unique_query_features == total_query_features always, making the bonus
126
+ a constant +10 noise term — so we skip it until the parquet is rebuilt.
127
  """
128
  hybrid_score = clamp(hybrid_score)
129
 
130
  originality = 100.0 * (1.0 - hybrid_score)
131
 
132
+ # Only apply uniqueness bonus when feature comparison was meaningful
133
+ # (i.e. the candidate had stored features, so coverage > 0)
134
+ # Guarded by unique < total to avoid the always-1.0 ratio when DB is empty
135
+ if total_query_features > 0 and unique_query_features < total_query_features:
136
  uniqueness_ratio = unique_query_features / total_query_features
137
  originality = min(100.0, originality + (uniqueness_ratio * 10.0))
138