Real-time Content-based Blog Recommendation System
이 글은 2015년 중앙대학교 빅데이터 경진대회에 출품했던 프로젝트를 다시 재구성한 것입니다. 학생 프로젝트로 진행했던 것이고, 해당 대회에서 금상을 받았습니다. 최신 트렌드를 반영하기보다는 서랍 속에 있던 발표 자료를 토대로 당시의 고민을 다시 정리해 보려 합니다. 이 글에서 소개하는 아이디어는 저와 함께한 프로젝트 팀원들의 것이니 무단으로 사용하지 않으셨으면 합니다. "현재"라고 언급되는 시점은 2015년 3분기임을 감안하고 읽어주시면 감사하겠습니다. 고작 몇 년 사이에 딥러닝이 세상을 지배하게 되어, 이런 방식의 아이디어는 더 이상 유효하지 않을 수도 있습니다.
문제 설정
블로그 글은 많은데, 이 글과 비슷한 주제의 글은 무엇일까?
수많은 블로그 글이 넘쳐나지만, 내가 읽는 글과 비슷한 주제의 다른 글을 찾기란 하늘의 별 따기보다 어렵습니다. 이는 대형 블로그 운영사들도 마찬가지인 듯합니다. 주제별 글을 볼 수 있는 코너가 있지만, 아직까지는 카테고리나 태그(Tag) 기반의 추천에 머물러 있는 것 같습니다.
네이버, 다음, 이글루스 등 주요 블로그 서비스들은 여전히 카테고리 기반의 분류를 사용하고 있습니다. 올블로그가 메타 블로그 추천수 기반으로 운영되는 것이 조금 특이한 정도입니다. 수년간의 노하우가 쌓인 블로그 플랫폼조차 빅데이터 분석 기반의 콘텐츠 추천을 적극적으로 시도하지 않는 것을 보면, 비슷한 주제의 글을 찾는 일이 얼마나 어려운지 짐작할 수 있습니다. 물론 백엔드 알고리즘으로는 이미 무언가를 시도하고 있을지도 모르겠지만요.
그래서 우리가 시도해 본 것은 "비슷한 주제의 블로그 글을 찾는 시스템 만들기"입니다.
문제 분석
우선 문제 분석부터 시작해야 합니다. 비슷한 주제를 컴퓨터가 이해할 수 있도록 어떻게 정의할지, 그리고 어떤 종류의 추천 시스템을 선택해야 할지 결정해야 합니다.
추천 시스템의 종류
추천 시스템을 만들려면 우선 어떤 방식들이 있는지 알아야겠죠. 추천 시스템은 크게 다음과 같이 분류할 수 있습니다.
- 콘텐츠 기반(Content-based): 아이템 자체의 특성을 활용하여 추천하는 방법
- 협업 필터링(Collaborative Filtering): 사용자의 행동 방식을 기반으로 아이템을 추천하는 방법
- 아이템 기반(Item-based): 아이템 사이의 유사도를 산출하여 추천
- 사용자 기반(User-based): 사용자와 사용자 사이의 유사도를 산출하여 추천
콘텐츠 기반 추천 시스템은 원리가 간단합니다. 콘텐츠의 특성을 이용해 유사한 콘텐츠를 찾아내는 것이죠. 이를 위해서는 콘텐츠의 특성을 정확히 파악해야 하고, '유사하다'는 것이 무엇인지 잘 정의해야 제대로 된 추천이 가능합니다. 비슷한 단어를 포함한 글을 추천하거나, 비슷한 색감을 가진 사진을 추천하는 것이 여기에 해당합니다.
반면 협업 필터링은 조금 더 복잡합니다. 사용자의 클릭 빈도와 같은 외부적인 요소를 가지고 유사성을 찾아냅니다.
아이템 기반은 특정 아이템과 함께 선택된 다른 아이템을 기억해 두었다가 추천하는 방식입니다. 쇼핑몰에서 흔히 보는 "이 상품을 본 고객이 함께 구매한 상품"이 좋은 예입니다. 마트의 스테이크 고기 매대 앞에 소스 매대가 있는 것과 비슷한 이치죠.
사용자 기반은 여기서 한 단계 더 나아갑니다. 단순히 아이템을 비교하는 것이 아니라 비슷한 선택을 한 사용자를 찾은 뒤, 그 사용자가 선택한 다른 아이템을 추천합니다. "20대 남성이 많이 고른 물품"과 같이 특정 그룹의 선택을 따르는 방식입니다.
협업 필터링은 훨씬 더 유연하고 사람의 사고에 가까운 추천을 할 수 있습니다. 하지만 사용자가 적거나 데이터를 충분히 모을 수 없는 환경에서는 추천이 불가능하다는 단점이 있습니다. 데이터를 최대한 많이 확보해야 하는데, 서비스 운영자가 아닌 입장에서는 쉽지 않은 일이죠.
우리는 구글이나 대형 블로그 플랫폼을 운영하고 있지 않으므로, 어떤 사용자가 어떤 글을 보았는지 알 수 없습니다. 따라서 아쉽지만 우리가 시도할 수 있는 유일한 방법인 콘텐츠 기반으로 진행하기로 했습니다.
비슷한 글이란 무엇일까?
콘텐츠 기반 분석으로 방향을 정했으니, 어떤 글을 '비슷한 글'로 정의할지 컴퓨터가 이해할 수 있도록 기준을 세워봅시다. 사람은 글을 읽으면 금방 알 수 있지만, 컴퓨터에게는 쉽지 않은 문제입니다.
TF-IDF
여러 고급 기법이 있겠지만, 복잡한 디테일은 잠시 제쳐두고 가장 기본적인 것부터 고려해 봅시다.
어떤 글이 비슷하다는 것은 "비슷한 구문이 등장"하거나 "비슷한 단어가 자주 등장"하는 것이라고 볼 수 있습니다. 특히 같은 구문이 길게 등장한다면 '인용'이거나 '표절'이겠죠. 둘 다 비슷한 주제를 다루고 있다는 강력한 증거가 됩니다. 하지만 비슷한 구문을 찾아내기란 쉽지 않습니다. 한국어 특성상 조사가 달라지거나 띄어쓰기가 틀리기 쉬운데, 컴퓨터가 이를 완벽하게 인식하기 어렵기 때문입니다.
그렇다면 비슷한 단어는 어떨까요? 단순히 단어가 등장하는 것만으로는 부족합니다. 우연히 같은 단어가 쓰일 수도 있으니까요. 하지만 핵심이 되는 중요한 단어가 비슷한 빈도로 등장한다면 어떨까요? 그렇다면 비슷한 주제의 글이라고 볼 수 있지 않을까요?
다행히 똑똑한 선학들이 중요한 단어를 찾는 수식을 이미 만들어 두었습니다. 바로 TF-IDF입니다.
- (Term Frequency): 특정 문서 내에서 단어 가 등장한 빈도입니다. 문서 내에서 자주 등장할수록 값이 커집니다.
- (Document Frequency): 전체 문서 중 단어 가 등장한 문서의 수입니다.
- (Inverse Document Frequency): 의 역수에 로그를 취한 값으로, 로 계산합니다. (여기서 은 전체 문서 수입니다.) 여러 문서에 흔하게 등장하는 단어일수록 값이 작아지며, 특정 문서에만 집중적으로 등장하는 단어일수록 값이 커집니다.
- : 이 두 값의 곱으로, 해당 문서에서 단어가 어느 정도로 중요한지를 나타내는 최종 지표가 됩니다.
TF-IDF는 한 문서에서 그 단어가 얼마나 중요한지를 나타내는 값입니다. 한 문서에서 자주 쓰일수록 수치가 높아지지만, 다른 문서에서도 흔하게 쓰이는 단어라면 수치가 낮아집니다. 즉, "물리학", "운영체제", "시분할 시스템" 같은 전문적인 단어는 점수가 높게 나오고, "나", "우리" 같이 어디에나 쓰이는 흔한 단어는 점수가 낮아집니다. 보통 단어의 분포는 로그 분포1를 보이기에 로그 함수를 이용해 정규화(Normalize)합니다. 결론적으로, 단어별 TF-IDF 값이 유사하다면 두 글은 비슷한 주제의 글이라고 판단할 수 있습니다.
유사도 측정
그렇다면 두 값이 '유사하다'는 것은 어떤 의미일까요? TF-IDF는 단어별로 값이 추출되기 때문에, 단순히 몇몇 단어의 값이 비슷하다고 해서 두 글이 유사하다고 단정 지을 수는 없습니다. 너무도 많은 변수가 있기 때문이죠. 다음과 같은 사례를 고려해 봅시다.
- A글 TF-IDF: 설탕(1.0), 냄비(0.3), 가열(0.1)
- B글 TF-IDF: 설탕(1.1), 솜사탕(0.5)
- C글 TF-IDF: 설탕(0.5), 냄비(0.1), 냉장고(0.1), 불(0.1), 그릇(0.1)
B와 C 중 A글과 더 비슷한 글은 무엇일까요? 수치만 보고는 쉽게 답하기 어렵습니다. 따라서 여러 개의 키-값(Key-Value) 쌍을 갖는 두 그룹 사이의 유사도를 수학적으로 정의해야 합니다. 수학적으로 정의만 된다면 계산은 컴퓨터에게 맡기면 되니까요.
빅데이터 처리에서는 흔히 두 가지 유사도가 사용됩니다. 바로 **자카드 유사도(Jaccard Similarity)**와 **코사인 유사도(Cosine Similarity)**입니다.
- Jaccard 유사도: 두 그룹에서 같은 키가 등장하기만 하면 유사도가 높다고 봅니다. 키의 값(Value)보다는 존재 여부가 중요한 경우에 사용합니다.
- Cosine 유사도: 벡터의 수학적 특성을 이용합니다. 각 키를 하나의 축으로 보고 값(Value)을 대응시켜 벡터를 그립니다. 두 벡터 사이의 코사인 값이 크면(각도가 작으면) 유사도가 높다고 판단합니다. 이는 내적을 통해 계산할 수 있습니다.
여기서는 단어의 등장 여부뿐만 아니라 중요도(값)도 매우 중요하므로, 코사인 유사도를 사용하기로 했습니다.
소정리
정리하자면, 비슷한 글이란 중요한 단어가 비슷한 빈도로 출현하는 글을 의미하며, 이는 TF-IDF로 수치화할 수 있습니다. 그리고 두 TF-IDF 벡터의 코사인 유사도를 구하면 비슷한 정도를 정량적으로 나타낼 수 있죠.
결국 처음에 가졌던 질문인 "이 글과 비슷한 주제의 다른 글은 무엇일까?"는 다음과 같이 수학적인 문제로 재정의됩니다.
특정한 A글과 TF-IDF의 코사인 유사도가 높은 문서를 찾는 문제
이제 문제를 컴퓨터가 풀 수 있는 형태로 만들었으니, 실제로 구현해 볼 차례입니다.
문제의 문제: 너무나 거대한 데이터
그런데 실제 구현을 고려해 보니 심각한 문제가 있었습니다. 우선 코사인 유사도를 계산하려면 각 TF-IDF 벡터를 서로 비교해야 합니다. 며칠간 크롤링으로 모은 블로그 글은 약 6,000만 건이었습니다. 즉, 6,000만 개의 벡터를 대조해야 한다는 뜻이죠. 게다가 TF-IDF 벡터의 차원(엘리먼트 개수)은 한국어 단어 수와 맞먹는데, 한국어 사전에 등록된 단어는 약 51만 개였습니다.
단순히 계산해 봐도 코사인 유사도를 구하기 위한 내적 연산 횟수는 6,000만 × 51만 = 약 30조 6,000억 번이 됩니다. 일반적인 연산 방법으로는 실시간 시스템은커녕, 분 단위의 처리조차 불가능해 보이는 수치였습니다2.
이토록 연산량이 많은 근본적인 원인은 데이터의 차원이 너무 높기 때문입니다. TF-IDF는 단어별로 값을 가지므로 51만 차원의 벡터가 되는데, 대부분의 단어는 특정 문서에 등장하지 않아 0값이겠지만 연산 시에는 이 높은 차원을 모두 고려해야 합니다. 결국 이 차원을 획기적으로 줄여야만 연산 횟수를 줄일 수 있습니다.
Local Sensitive Hashing (LSH)
차원을 줄이는 여러 방법이 있지만, 대규모 데이터 처리에서 자주 쓰이는 방식 중 하나가 LSH입니다. LSH는 일종의 해시 변형인데, 일반적인 해시와는 달리 '디퓨즈(Diffuse) 효과'가 없습니다.
일반적인 해시는 단 한 비트만 달라져도 결과값이 완전히 달라지지만, LSH는 입력값이 비슷하면 결과값도 비슷하게 나옵니다. 보안 측면에서는 쓸모가 없겠지만, 비슷한 것끼리 묶어야 하는 유사성 분석에서는 매우 유용합니다. 일종의 '차원 축소' 효과를 내는 것이죠. LSH를 만족하는 해시 함수에는 MinHash, Random Hyperplane Projection 등이 있으며, 유사도의 종류에 따라 적합한 함수를 선택해야 합니다.
우리는 코사인 유사도를 유지해야 하므로, 이에 적합한 Random Hyperplane Projection 방식을 사용하기로 했습니다.
랜덤 하이퍼플레인 (Random Hyperplane)의 기하학적 원리
문제를 해결하기 위해 먼저 블로그 글을 수학적인 **'벡터'**로 바라봅시다. 51만 개의 단어 사전을 고정된 순서로 나열했다고 가정하면, 어떤 블로그 글은 다음과 같은 거대한 벡터가 됩니다.
- 문서 벡터 (): (여기서 는 번째 단어의 TF-IDF 값)
이 공간에 임의의 방향을 가진 64개의 **초평면(Hyperplane)**을 설정하고, 문서 벡터()와 각 평면의 **법선 벡터()**를 **내적(Dot Product)**합니다.
수학적으로 이 내적 결과의 **부호(+/-)**는 문서 벡터가 평면을 기준으로 어느 쪽에 위치하는지를 알려줍니다3. 부호가 양수(+)면 법선 벡터와 같은 방향의 공간에, 음수(-)면 법선 벡터와 반대쪽 공간에 있다는 의미가 됩니다. 양수를 1, 음수를 0으로 표현하면 초평면 하나당 비트 하나로 위치를 특정할 수 있습니다. 결과적으로 64개의 초평면을 사용하면 전체 위치 정보를 단 64비트(bit)로 나타낼 수 있게 됩니다. 이 과정을 통해 51만 차원의 거대한 벡터는 단 하나의 64비트 정수로 압축됩니다.
여기서 연산 효율을 극대화해 주는 **희소 벡터(Sparse Vector)**의 특성이 나타납니다. 51만 차원의 벡터라고는 하지만, 실제 한 문서에 쓰인 단어는 고작 수백 개뿐입니다. 문서에 등장하지 않는 나머지 수십만 개의 단어는 가중치()가 0이므로 계산할 필요가 없습니다. 즉, 실제 내적 계산 시에는 51만 번의 곱셈을 할 필요 없이 문서에 실제로 존재하는 단어들에 대해서만 계산하면 됩니다.
구현의 난관: 64개 평면의 법선 벡터를 어떻게 저장할까?
하지만 구현상에 큰 문제가 하나 더 있습니다. 내적을 계산하려면 각 평면의 방향을 결정하는 **법선 벡터의 값()**들을 알고 있어야 합니다. 64개 평면 각각에 대해 51만 차원의 성분 값을 미리 생성해서 메모리에 보관하려면 수백 메가바이트(MB)가 필요하며, 이를 모든 분산 노드에 관리하는 것은 비효율적입니다.
테크닉: SHA-512를 이용한 법선 벡터의 실시간 생성 (On-the-fly)
여기서 **'법선 벡터를 저장하지 말고, 단어의 해시값을 법선 벡터의 성분으로 정의하자'**는 묘수가 등장합니다. 바로 SHA-512 해시 함수를 활용하는 것입니다.
- 법선 벡터 성분의 정의: 특정 단어()에 대한 번째 평면의 법선 벡터 성분()을
SHA512(단어)의 번째 바이트로 정의합니다. - 저장 필요 없음: 이제 법선 벡터를 기억해 둘 필요가 없습니다. 단어 하나를 해싱하면 그 단어가 64개 평면 각각에 대해 가져야 할 법선 벡터의 모든 성분 값을 즉석에서 알 수 있기 때문입니다.
| 단어 (k) | 해시 결과 (SHA-512) | 평면 1 법선벡터 성분 () | 평면 2 법선벡터 성분 () | ... |
|---|---|---|---|---|
| 사과 | [0x1A, 0xFF, 0x72, ...] |
0x1A (+26) |
0xFF (-1) |
... |
| 바나나 | [0x05, 0x2C, 0x8E, ...] |
0x05 (+5) |
0x2C (+44) |
... |
연산 과정:
- 문서 내의 단어를 하나씩 꺼냅니다.
- 단어를 해싱하여 해당 단어에 대응하는 64개 법선 벡터의 성분 값들을 얻습니다.
(단어의 TF-IDF × 법선벡터 성분)을 계산하여 64개의 점수판에 각각 누적합니다.- 모든 단어 처리 후, 점수판 부호에 따라 64비트 해시를 완성합니다.
이 방식을 통해 별도의 법선 벡터 데이터 없이도 단 한 번의 해싱만으로 64비트 LSH 해시를 생성할 수 있었고, 수천만 건의 데이터를 처리할 수 있는 압도적인 효율성을 확보했습니다.
해밍 거리(Hamming Distance): 유사도 측정
이제 51만 차원의 벡터가 단 64비트의 숫자로 압축되었습니다. 8비트 가중치를 활용해 정교하게 결정된 이 64개의 비트는 이제 실시간 추천의 핵심이 됩니다. 그렇다면 이 숫자들 사이의 유사도는 어떻게 측정할까요?
LSH의 특성상, 원래의 코사인 유사도가 높을수록 생성된 해시값의 비트들이 서로 일치할 확률이 높습니다. 여기서 바로 현대 CPU의 가장 강력한 무기인 64비트 XOR 연산이 등장합니다.
두 해시값 사이에서 서로 다른 비트의 개수를 **해밍 거리(Hamming Distance)**라고 합니다.
- 두 64비트 정수를
XOR연산합니다. (서로 다른 비트가 1이 됨) - 결과값에서 1인 비트의 개수(
POPCNT)를 세기만 하면 됩니다.
이 과정의 핵심은 CPU 사이클에 있습니다. 수십만 차원의 부동소수점(Floating-point) 벡터 내적 연산은 수천수만 번의 FPU/SIMD 명령어를 소모하며 메모리 대역폭을 잡아먹지만, 3 사이클**이면 충분한 단일 명령어입니다.XOR과 POPCNT는 현대 CPU에서 단 **1
연산 비용이 수만 배 이상 차이 나기 때문에, 일반적인 서버 한 대에서도 수천만 건의 데이터를 실시간으로 훑으며 유사한 글을 찾아내는 '마법'이 가능해지는 것입니다. 8비트로 정밀하게 빚어낸 64비트 해시 덕분에, 이 압도적인 사이클 효율성을 누리면서도 추천의 정확도를 유지할 수 있었습니다.
시스템 아키텍처
6,000만 건의 방대한 데이터를 처리하기 위해 설계했던 전체 시스템 구조와 파이프라인은 다음과 같습니다.
1. 데이터 수집 및 전처리 (Crawling & Preprocessing)
수천만 건의 데이터를 실시간으로 추천하기 위해서는 가장 먼저 양질의 데이터를 확보하고 이를 정형화하는 과정이 필요했습니다.
- 대규모 크롤링: 네이버, 다음 등 주요 블로그의 공개된 글들을 수집했습니다. 약 6,000만 건의 문서를 확보했으며, 데이터의 최신성을 유지하기 위해 RSS 피드와 사이트맵을 활용한 증분 수집 방식을 병행했습니다.
- 본문 정제: HTML 태그, 광고성 문구, 특수문자 등 분석에 방해가 되는 노이즈를 제거하고 순수 텍스트만을 추출했습니다. 또한 중복된 글(Scrap)을 필터링하여 추천의 품질을 높였습니다.
- 한국어 형태소 분석: 수집된 텍스트에서 의미 있는 키워드를 뽑아내기 위해 KoNLPy 패키지를 도입했습니다. 내부의 여러 형태소 분석 모듈 중 가장 속도가 빠른 Mecab을 사용하여 명사 위주의 키워드를 추출했고, 이를 바탕으로 문서별 단어 빈도를 계산했습니다.
2. 분산 배치 처리 파이프라인 (MapReduce Flow)
6,000만 건의 문서를 단일 서버에서 처리하는 것은 불가능했기에, Spark와 Hadoop을 활용한 MapReduce 모델을 설계하여 연산을 분산했습니다.
이 설계의 묘미는 전역 통계와 개별 연산의 분리에 있었습니다. 단어의 희소성을 나타내는 IDF 값은 전체 문서 수에 영향을 받으므로 엄밀히는 실시간 데이터 추가에 따라 계속 변해야 하지만, 6,000만 건이라는 거대한 모수에서는 그 변화폭이 미미합니다. 따라서 IDF는 1일 또는 1주 단위의 배치(Batch) 연산으로 업데이트하여 고정된 상수처럼 관리하고, 각 문서의 LSH 해시 생성은 이 캐싱된 통계치를 참조하여 완전 독립적으로 수행하도록 설계했습니다.
덕분에 새로운 문서가 추가될 때마다 기존 데이터를 다시 계산할 필요 없이 실시간으로 해시를 생성하여 덧붙이는(Append) 것이 가능했으며, 이는 시스템의 확장성을 확보하는 핵심적인 전략이 되었습니다.
- 단계 1: 단어 빈도 집계 (Word Count): 각 문서에서 등장하는 단어의 개수를 세어
(문서ID, 단어, TF)데이터를 생성합니다. - 단계 2: 전역 문서 빈도 계산 및 DF 정보 구축: 모든 문서를 훑어 특정 단어가 등장한 문서의 총합(
DF)을 구합니다. 이 정보는 Cluster내에서 전역 상태로 유지되어, 모든 분석 노드가 단어의 희소성(IDF)을 판단하는 통일된 기준점으로 참조하게 됩니다. - 단계 3: TF-IDF 및 LSH 생성: 개별 노드들은 Cluster로부터 필요한 IDF 값을 가져와(Side-join) 문서 벡터를 구성하고, SHA-512 기반 랜덤 하이퍼플레인 기법을 적용해 64비트 LSH 해시를 산출합니다.
- 단계 4: 해시 인덱싱: 생성된 64비트 해시를 분산 저장소에 인덱싱하여 추천 엔진이 바로 참조할 수 있게 합니다.
3. 도커(Docker) 기반 인프라 및 클러스터 구축
유연한 분산 처리를 위해 Docker 컨테이너 기술을 전면 도입하여 시스템의 유연성을 확보했습니다.
- 복잡한 환경의 패키징: TF-IDF와 형태소 분석에 사용되는 Python, Mecab, gcc, g++, glibs 등의 복잡한 라이브러리 의존성을 Docker 이미지 하나로 묶었습니다.
- 쉬운 클러스터 확장: 잘 만들어진 이미지 하나만 복사하면 즉각적으로 Node 개수를 늘릴 수 있어, 컴퓨터 대수만 확보된다면 손쉽게 대규모 클러스터를 구축할 수 있었습니다.
4. 실시간 추천 엔진 (Real-time Serving)
사용자가 글을 읽는 시점에 즉각적으로 추천 결과가 노출되어야 하므로, 서빙 레이어는 응답 속도와 자원 효율성에 극도로 초점을 맞췄습니다.
- 메모리 효율성의 극대화: 6,000만 건을 기존의 코사인 유사도 연산으로 처리하려면 약 113GB의 메모리 공간이 필요했습니다. 하지만 LSH를 통한 XOR 연산 방식을 도입함으로써 필요 메모리를 단 0.8GB로 줄일 수 있었고, 단일 머신에서도 전체 시스템을 구동할 수 있었습니다.
- 해밍 거리(Hamming Distance) 고속 검색: 사용자가 읽고 있는 글의 64비트 해시와 미리 인덱싱된 수천만 건의 해시들을 비교합니다. 앞서 설명한
XOR과POPCNT명령어(CPU Instruction)를 통해 캐시(Cache) 친화적으로 연산하여 밀리초(ms) 단위의 응답 속도를 확보했습니다.
결과 및 한계와 향후 과제
- 실시간 업데이트: 새로운 글이 올라올 때마다 즉시 인덱스에 반영하는 구조.
- 가중치 조절: 본문보다는 제목(Title)에 등장하는 키워드에 더 높은 가중치를 부여.
- 피드백 루프: 추천된 글을 사용자가 실제로 클릭했는지 정보를 수집하여 다시 협업 필터링 요소로 활용.
마무리하며
현재는 BERT나 GPT 같은 거대 언어 모델(LLM)과 임베딩 벡터를 활용한 벡터 데이터베이스(Vector DB)가 이 역할을 훨씬 더 정교하게 수행하고 있습니다. 하지만 LSH와 같은 알고리즘은 여전히 대규모 시스템에서 초고속 필터링이나 중복 제거 등을 위해 유용하게 사용되고 있습니다.
지금이라면 형태소 분석기 대신 소규모의 LLM 으로 품질을 높이는 시도를 해봤거나, 임베딩 벡터에 대한 인덱스 최적화에 아이디어를 접속 시켜 보았을것 같습니다.
10년 전 "빅데이터"라는 이름 아래 치열하게 고민했던 이 아이디어가 누군가에게는 기초적인 영감이 되길 바랍니다.