Spaces:
Sleeping
Sleeping
Upload backend/hue_portal/core/query_expansion.py with huggingface_hub
Browse files
backend/hue_portal/core/query_expansion.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Query expansion with Vietnamese synonyms for improved search recall.
|
| 3 |
+
"""
|
| 4 |
+
from typing import List, Set
|
| 5 |
+
|
| 6 |
+
# Vietnamese synonyms dictionary for legal domain
|
| 7 |
+
VIETNAMESE_SYNONYMS = {
|
| 8 |
+
# Discipline/punishment terms
|
| 9 |
+
"kỷ luật": ["xử lý", "xử phạt", "vi phạm", "trừng phạt", "kỷ luật đảng viên"],
|
| 10 |
+
"xử lý": ["kỷ luật", "xử phạt", "trừng phạt"],
|
| 11 |
+
"vi phạm": ["sai phạm", "lỗi", "khuyết điểm"],
|
| 12 |
+
|
| 13 |
+
# Document types
|
| 14 |
+
"quyết định": ["qd", "nghị quyết", "văn bản", "quyết nghị"],
|
| 15 |
+
"thông tư": ["tt", "văn bản hướng dẫn"],
|
| 16 |
+
"nghị định": ["nđ", "nd", "văn bản pháp luật"],
|
| 17 |
+
"điều lệnh": ["quy định", "quy chế", "nội quy"],
|
| 18 |
+
|
| 19 |
+
# Organizational terms
|
| 20 |
+
"đảng viên": ["cán bộ đảng", "đảng viên đảng bộ", "đảng viên chi bộ"],
|
| 21 |
+
"cán bộ": ["công chức", "viên chức", "cán bộ công an"],
|
| 22 |
+
"công an": ["cand", "lực lượng công an", "công an nhân dân"],
|
| 23 |
+
|
| 24 |
+
# Disciplinary forms
|
| 25 |
+
"khiển trách": ["kỷ luật khiển trách", "hình thức khiển trách"],
|
| 26 |
+
"cảnh cáo": ["kỷ luật cảnh cáo", "hình thức cảnh cáo"],
|
| 27 |
+
"cách chức": ["kỷ luật cách chức", "miễn nhiệm"],
|
| 28 |
+
"khai trừ": ["khai trừ đảng", "kỷ luật khai trừ"],
|
| 29 |
+
|
| 30 |
+
# Procedures
|
| 31 |
+
"thủ tục": ["quy trình", "trình tự", "các bước"],
|
| 32 |
+
"hồ sơ": ["giấy tờ", "tài liệu", "chứng từ"],
|
| 33 |
+
"điều kiện": ["yêu cầu", "tiêu chuẩn", "quy định"],
|
| 34 |
+
|
| 35 |
+
# Common verbs
|
| 36 |
+
"quy định": ["qui định", "nêu rõ", "chỉ rõ", "ghi rõ"],
|
| 37 |
+
"áp dụng": ["thực hiện", "thi hành", "triển khai"],
|
| 38 |
+
"ban hành": ["công bố", "phát hành", "ra đời"],
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
# Reverse mapping for faster lookup
|
| 42 |
+
_REVERSE_SYNONYMS = {}
|
| 43 |
+
for key, synonyms in VIETNAMESE_SYNONYMS.items():
|
| 44 |
+
for syn in synonyms:
|
| 45 |
+
if syn not in _REVERSE_SYNONYMS:
|
| 46 |
+
_REVERSE_SYNONYMS[syn] = []
|
| 47 |
+
_REVERSE_SYNONYMS[syn].append(key)
|
| 48 |
+
# Add other synonyms
|
| 49 |
+
_REVERSE_SYNONYMS[syn].extend([s for s in synonyms if s != syn])
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def expand_query(query: str, max_expansions: int = 3) -> List[str]:
|
| 53 |
+
"""
|
| 54 |
+
Expand query with Vietnamese synonyms.
|
| 55 |
+
|
| 56 |
+
Args:
|
| 57 |
+
query: Original query string.
|
| 58 |
+
max_expansions: Maximum number of synonym expansions per term.
|
| 59 |
+
|
| 60 |
+
Returns:
|
| 61 |
+
List of expanded query strings (including original).
|
| 62 |
+
"""
|
| 63 |
+
if not query:
|
| 64 |
+
return [query]
|
| 65 |
+
|
| 66 |
+
query_lower = query.lower()
|
| 67 |
+
expanded_queries = [query] # Always include original
|
| 68 |
+
|
| 69 |
+
# Find matching terms
|
| 70 |
+
matched_terms = set()
|
| 71 |
+
for term in VIETNAMESE_SYNONYMS.keys():
|
| 72 |
+
if term in query_lower:
|
| 73 |
+
matched_terms.add(term)
|
| 74 |
+
|
| 75 |
+
# Also check reverse mapping
|
| 76 |
+
for term in _REVERSE_SYNONYMS.keys():
|
| 77 |
+
if term in query_lower:
|
| 78 |
+
matched_terms.add(term)
|
| 79 |
+
|
| 80 |
+
# Generate expanded queries
|
| 81 |
+
for term in matched_terms:
|
| 82 |
+
# Get synonyms
|
| 83 |
+
synonyms = VIETNAMESE_SYNONYMS.get(term, [])
|
| 84 |
+
if not synonyms and term in _REVERSE_SYNONYMS:
|
| 85 |
+
synonyms = _REVERSE_SYNONYMS[term]
|
| 86 |
+
|
| 87 |
+
# Create expanded queries (limit to max_expansions)
|
| 88 |
+
for syn in synonyms[:max_expansions]:
|
| 89 |
+
expanded = query_lower.replace(term, syn)
|
| 90 |
+
if expanded != query_lower and expanded not in expanded_queries:
|
| 91 |
+
expanded_queries.append(expanded)
|
| 92 |
+
|
| 93 |
+
return expanded_queries
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def get_synonyms(term: str) -> Set[str]:
|
| 97 |
+
"""
|
| 98 |
+
Get all synonyms for a term.
|
| 99 |
+
|
| 100 |
+
Args:
|
| 101 |
+
term: Term to find synonyms for.
|
| 102 |
+
|
| 103 |
+
Returns:
|
| 104 |
+
Set of synonyms (including the term itself).
|
| 105 |
+
"""
|
| 106 |
+
term_lower = term.lower()
|
| 107 |
+
synonyms = {term_lower}
|
| 108 |
+
|
| 109 |
+
# Check direct mapping
|
| 110 |
+
if term_lower in VIETNAMESE_SYNONYMS:
|
| 111 |
+
synonyms.update(VIETNAMESE_SYNONYMS[term_lower])
|
| 112 |
+
|
| 113 |
+
# Check reverse mapping
|
| 114 |
+
if term_lower in _REVERSE_SYNONYMS:
|
| 115 |
+
synonyms.update(_REVERSE_SYNONYMS[term_lower])
|
| 116 |
+
|
| 117 |
+
return synonyms
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def expand_keywords(keywords: List[str]) -> List[str]:
|
| 121 |
+
"""
|
| 122 |
+
Expand a list of keywords with synonyms.
|
| 123 |
+
|
| 124 |
+
Args:
|
| 125 |
+
keywords: List of keyword strings.
|
| 126 |
+
|
| 127 |
+
Returns:
|
| 128 |
+
Expanded list of keywords (including originals).
|
| 129 |
+
"""
|
| 130 |
+
expanded = set(keywords) # Keep originals
|
| 131 |
+
|
| 132 |
+
for keyword in keywords:
|
| 133 |
+
synonyms = get_synonyms(keyword)
|
| 134 |
+
expanded.update(synonyms)
|
| 135 |
+
|
| 136 |
+
return list(expanded)
|
| 137 |
+
|