bat-6 commited on
Commit
692f58b
·
1 Parent(s): 44f90cf
src/similarity_model/__pycache__/semantic_search.cpython-313.pyc CHANGED
Binary files a/src/similarity_model/__pycache__/semantic_search.cpython-313.pyc and b/src/similarity_model/__pycache__/semantic_search.cpython-313.pyc differ
 
src/similarity_model/semantic_search.py CHANGED
@@ -1,5 +1,3 @@
1
- # src/semantic_search.py
2
-
3
  import re
4
  import ast
5
  import logging
@@ -15,25 +13,17 @@ from Data.database.sql_connector import (
15
  load_preprocessed_projects
16
  )
17
 
18
- # =====================================================
19
- # Logging
20
- # =====================================================
21
  logging.basicConfig(
22
  level=logging.INFO,
23
  format="%(asctime)s | %(levelname)s | %(message)s"
24
  )
25
  logger = logging.getLogger(__name__)
26
 
27
- # =====================================================
28
- # Config
29
- # =====================================================
30
  DEFAULT_MODEL = "all-MiniLM-L6-v2"
31
 
32
  TITLE_COL = "project_title"
33
  TECH_COL = "technologies"
34
 
35
- # Resolve paths relative to the project root (3 levels up from this file:
36
- # src/similarity_model/semantic_search.py -> src/similarity_model -> src -> project root)
37
  _PROJECT_ROOT = Path(__file__).resolve().parents[2]
38
 
39
  INDEX_PATH = _PROJECT_ROOT / "models" / "faiss_index.bin"
@@ -43,9 +33,6 @@ EMBED_PATH = _PROJECT_ROOT / "models" / "project_embeddings.npy"
43
  TOP_K = 20
44
  MIN_SCORE = 0.35
45
 
46
- # =====================================================
47
- # Text Helpers
48
- # =====================================================
49
  def normalize_text(text: str) -> str:
50
  """
51
  Normalize user query to match preprocessing style.
@@ -61,23 +48,17 @@ def normalize_text(text: str) -> str:
61
 
62
  return text
63
 
64
-
65
  def tokenize(text: str) -> set:
66
  """
67
  Tokenize normalized text.
68
  """
69
  return set(normalize_text(text).split())
70
 
71
-
72
- # =====================================================
73
- # Cached Loaders
74
- # =====================================================
75
  @lru_cache(maxsize=1)
76
  def load_model():
77
  logger.info(f"Loading model: {DEFAULT_MODEL}")
78
  return SentenceTransformer(DEFAULT_MODEL)
79
 
80
-
81
  @lru_cache(maxsize=1)
82
  def load_faiss_index():
83
  if not INDEX_PATH.exists():
@@ -86,7 +67,6 @@ def load_faiss_index():
86
  logger.info("Loading FAISS index...")
87
  return faiss.read_index(str(INDEX_PATH))
88
 
89
-
90
  @lru_cache(maxsize=1)
91
  def load_metadata():
92
 
@@ -98,7 +78,6 @@ def load_metadata():
98
 
99
  return df.reset_index(drop=True)
100
 
101
-
102
  @lru_cache(maxsize=1)
103
  def load_embeddings():
104
  if not EMBED_PATH.exists():
@@ -107,10 +86,6 @@ def load_embeddings():
107
  logger.info("Loading embeddings...")
108
  return np.load(str(EMBED_PATH))
109
 
110
-
111
- # =====================================================
112
- # Core Result Builder
113
- # =====================================================
114
  def build_results(
115
  df: pd.DataFrame,
116
  ids,
@@ -133,8 +108,7 @@ def build_results(
133
  final_score = float(score)
134
 
135
  # ---------------------------------------------
136
- # Keyword Boosting
137
- # ---------------------------------------------
138
  if query_words:
139
 
140
  title_words = tokenize(row[TITLE_COL])
@@ -149,8 +123,7 @@ def build_results(
149
  if overlap > 0:
150
  final_score += 0.02 * overlap
151
 
152
- # cap score
153
- final_score = min(final_score, 1.0)
154
 
155
  if final_score < min_score:
156
  continue
@@ -174,10 +147,6 @@ def build_results(
174
  .reset_index(drop=True)
175
  )
176
 
177
-
178
- # =====================================================
179
- # Search by Free Text
180
- # =====================================================
181
  def search_by_text(
182
  query_text: str,
183
  k: int = TOP_K,
@@ -206,10 +175,6 @@ def search_by_text(
206
  min_score=min_score
207
  )
208
 
209
-
210
- # =====================================================
211
- # Search Similar to Existing Project
212
- # =====================================================
213
  def search_by_project_id(
214
  project_id: int,
215
  k: int = TOP_K,
@@ -270,10 +235,6 @@ def search_by_project_id(
270
 
271
  return pd.DataFrame(rows)
272
 
273
-
274
- # =====================================================
275
- # Compare Two Ideas
276
- # =====================================================
277
  def compare_two_ideas(
278
  text_a: str,
279
  text_b: str
@@ -293,33 +254,3 @@ def compare_two_ideas(
293
  score = float(np.dot(vecs[0], vecs[1]))
294
 
295
  return round(score, 4)
296
-
297
-
298
- # =====================================================
299
- # Example Run
300
- # =====================================================
301
- if __name__ == "__main__":
302
-
303
- print("\n=== Search by Text ===")
304
- print(
305
- search_by_text(
306
- "mobile app for expense tracking using flutter",
307
- k=5
308
- )
309
- )
310
-
311
- print("\n=== Similar Projects ===")
312
- print(
313
- search_by_project_id(
314
- project_id=0,
315
- k=5
316
- )
317
- )
318
-
319
- print("\n=== Compare Two Ideas ===")
320
- print(
321
- compare_two_ideas(
322
- "AI Medical Chatbot",
323
- "Healthcare Assistant with AI"
324
- )
325
- )
 
 
 
1
  import re
2
  import ast
3
  import logging
 
13
  load_preprocessed_projects
14
  )
15
 
 
 
 
16
  logging.basicConfig(
17
  level=logging.INFO,
18
  format="%(asctime)s | %(levelname)s | %(message)s"
19
  )
20
  logger = logging.getLogger(__name__)
21
 
 
 
 
22
  DEFAULT_MODEL = "all-MiniLM-L6-v2"
23
 
24
  TITLE_COL = "project_title"
25
  TECH_COL = "technologies"
26
 
 
 
27
  _PROJECT_ROOT = Path(__file__).resolve().parents[2]
28
 
29
  INDEX_PATH = _PROJECT_ROOT / "models" / "faiss_index.bin"
 
33
  TOP_K = 20
34
  MIN_SCORE = 0.35
35
 
 
 
 
36
  def normalize_text(text: str) -> str:
37
  """
38
  Normalize user query to match preprocessing style.
 
48
 
49
  return text
50
 
 
51
  def tokenize(text: str) -> set:
52
  """
53
  Tokenize normalized text.
54
  """
55
  return set(normalize_text(text).split())
56
 
 
 
 
 
57
  @lru_cache(maxsize=1)
58
  def load_model():
59
  logger.info(f"Loading model: {DEFAULT_MODEL}")
60
  return SentenceTransformer(DEFAULT_MODEL)
61
 
 
62
  @lru_cache(maxsize=1)
63
  def load_faiss_index():
64
  if not INDEX_PATH.exists():
 
67
  logger.info("Loading FAISS index...")
68
  return faiss.read_index(str(INDEX_PATH))
69
 
 
70
  @lru_cache(maxsize=1)
71
  def load_metadata():
72
 
 
78
 
79
  return df.reset_index(drop=True)
80
 
 
81
  @lru_cache(maxsize=1)
82
  def load_embeddings():
83
  if not EMBED_PATH.exists():
 
86
  logger.info("Loading embeddings...")
87
  return np.load(str(EMBED_PATH))
88
 
 
 
 
 
89
  def build_results(
90
  df: pd.DataFrame,
91
  ids,
 
108
  final_score = float(score)
109
 
110
  # ---------------------------------------------
111
+ # ---------------------------------------------
 
112
  if query_words:
113
 
114
  title_words = tokenize(row[TITLE_COL])
 
123
  if overlap > 0:
124
  final_score += 0.02 * overlap
125
 
126
+ final_score = min(final_score, 1.0)
 
127
 
128
  if final_score < min_score:
129
  continue
 
147
  .reset_index(drop=True)
148
  )
149
 
 
 
 
 
150
  def search_by_text(
151
  query_text: str,
152
  k: int = TOP_K,
 
175
  min_score=min_score
176
  )
177
 
 
 
 
 
178
  def search_by_project_id(
179
  project_id: int,
180
  k: int = TOP_K,
 
235
 
236
  return pd.DataFrame(rows)
237
 
 
 
 
 
238
  def compare_two_ideas(
239
  text_a: str,
240
  text_b: str
 
254
  score = float(np.dot(vecs[0], vecs[1]))
255
 
256
  return round(score, 4)