금융 및 커머스 도메인의 추천 시스템은 두 가지 핵심 과제를 동시에 해결해야 합니다.
- 명시적 조건의 절대적 준수 (Hard Filter): 타겟 마케팅 시 지역, 나이 등의 조건은 1%의 오차도 허용되지 않습니다.
- 고객 성향의 의미론적 파악 (Semantic Search): "외식을 좋아하는"과 같은 추상적 성향은 단순 수치나 키워드만으로 잡아내기 어렵습니다.
본 프로젝트는 전통적인 키워드 검색(BM25)과 최신 AI 문맥 검색(Dense Vector)이 가진 각각의 치명적 한계를 분석하고, SQL 하드 필터링과 RRF(Reciprocal Rank Fusion) 알고리즘을 결합하여 이 문제를 우아하게 해결하는 하이브리드 검색 파이프라인을 설계 및 검증합니다.
실무 검색 엔진(Elasticsearch 등)의 Bool Query 로직을 Python으로 구현하여 3단계 파이프라인을 구축했습니다.
- Hard Filter (SQL): 타겟 조건(서울, 30대)에 맞지 않는 데이터는 1차적으로 100% 차단하여 시스템 부하 감소 및 오답률 0% 달성.
- Dual Scoring (BM25 + Dense): 필터를 통과한 후보군을 대상으로 키워드 매칭(BM25)과 문맥 유사도(SentenceTransformer)를 각각 병렬 채점.
- Rank Fusion (RRF): 스케일이 다른 두 점수를 무시하고, 오직 '순위(Rank)'만을 역수 합산하여 최적의 교집합(진짜 VIP) 도출.
- 실험 쿼리:
외식 소비가 많은 고객 - 하드 조건:
서울 거주, 30대 - Ground Truth (정답셋): 하드 조건을 만족하면서 실제 요식업 지출이 상위 10%인 고객 (61명)
| 평가 항목 | Dense 단독 (+SQL) | BM25 단독 (+SQL) | Score Fusion (단순가중합) | Rank Fusion (RRF) |
|---|---|---|---|---|
| Accuracy (조건 일치) | 100.0% | 100.0% | 100.0% | 100.0% |
| Recall@10 (정답 검출률) | 0.0164 | 0.0000 | 0.0164 | 0.1148 (약 7배 향상) |
| Hit@10 | 1 | 0 | 1 | 1 |
| Latency (총 수행 시간) | - | - | 16.69 ms | 4.93 ms (가장 빠름) |
- 연산 효율성: SQL 필터링을 통해 초기 모수 10,000건 중 94.4%의 불필요한 연산을 0.00ms 만에 제거하여 안정적인 응답 속도 확보.
동일한 '서울 30대' 통과자를 대상으로 정렬(Ranking) 대결을 펼친 결과입니다.
- ❌ Dense 단독: 360만 원 / 1만 원 / 9만 원 (지출액이 낮아도 문맥만 비슷하면 상위 랭크)
- ❌ BM25 단독: 0원 / 0원 / 0원 (지출 내역이 아예 없는 깡통 데이터가 1위 장악)
- ✅ RRF 하이브리드: 360만 원 / 90만 원 / 300만 원 (두 엔진의 교집합으로 실제 고과금 VIP 완벽 추출)
검색 결과의 치명적인 오류들을 디버깅하고 원인을 공학적으로 규명했습니다.
- 원인: 단순 텍스트 검색은 "요식업 지출 없음"이라는 부정문에서 '요식업' 키워드만 기계적으로 매칭합니다. 또한, 지출 내역이 적어 문장이 짧은 고객일수록 단어 밀도가 높게 계산(Length Normalization)되어 가산점을 받는 BM25 알고리즘의 맹점을 확인했습니다.
- 해결: 수치 데이터는 절대 텍스트 검색에 맡기지 않고, 구조화된 데이터 필터링(SQL)과 상호 보완되도록 파이프라인을 재설계했습니다.
- 원인: 점수 스케일이 다른 두 엔진을 5:5로 결합하기 위해 Min-Max 정규화를 수행했으나, 특정 엔진의 극단적인 점수 분포(Outlier)로 인해 나머지 점수가 0으로 왜곡되는 현상이 발생했습니다. (
bm25_norm= 0.0 수렴) - 해결: 정규화의 함정을 피하기 위해 점수 스케일과 완전히 독립적인 RRF(순위 기반 융합) 를 도입하여 특정 모델에 랭킹이 지배당하는 현상(Model Bias)을 원천 차단했습니다.
# 가상환경 생성 및 활성화 (Windows 기준)
python -m venv venv
.\venv\Scripts\activate
# 의존성 패키지 설치
pip install -r requirments.txt
"정렬도 구조다 (Ranking is Structural)" 단순히 최신 AI(Dense)를 도입하거나 가중치를 튜닝하는 것만으로는 훌륭한 검색 시스템을 만들 수 없습니다. AI의 유연함, 전통적 키워드 검색의 명확함, 그리고 비즈니스 룰을 강제하는 SQL의 견고함이 RRF라는 구조적 틀 안에서 결합될 때 가장 신뢰할 수 있는 시스템이 완성됨을 실증 데이터로 증명했습니다.