벡터 필드를 사용한 텍스트 유사도 검색

이 게시물에서는 텍스트 임베딩과 Elasticsearch의 새로운 dense_vector 유형을 사용하여 유사성 검색을 지원하는 방법을 살펴봅니다.

벡터 검색부터 강력한 REST API까지, Elasticsearch는 개발자에게 가장 폭넓은 검색 도구 키트를 제공합니다. GitHub의 샘플 노트북을 살펴보고 새로운 기능을 시험해 보세요. 무료 체험판을 시작하거나 지금 바로 Elasticsearch를 로컬에서 실행할 수도 있습니다.

레시피 검색 엔진으로 시작한 Elasticsearch는 처음부터 빠르고 강력한 전체 텍스트 검색을 제공하도록 설계되었습니다. 이러한 뿌리를 고려할 때, 텍스트 검색을 개선하는 것은 벡터를 활용한 지속적인 작업의 중요한 동기가 되었습니다. Elasticsearch 7.0에서는 고차원 벡터를 위한 실험적인 필드 유형을 도입했으며, 이제 7.3 릴리즈에서는 이러한 벡터를 문서 채점에 사용할 수 있도록 지원합니다.

이 게시물은 텍스트 유사도 검색이라는 특정 기술에 중점을 두고 있습니다. 이 유형의 검색에서는 사용자가 짧은 자유 텍스트 쿼리를 입력하면 쿼리와의 유사성에 따라 문서 순위가 매겨집니다. 텍스트 유사성은 다양한 사용 사례에서 유용하게 사용될 수 있습니다:

  • 질문-답변: 자주 묻는 질문 모음이 주어지면 사용자가 입력한 질문과 유사한 질문을 찾습니다.
  • 논문 검색: 연구 논문 모음에서 사용자의 검색어와 밀접한 관련이 있는 제목의 기사를 반환합니다.
  • 이미지 검색: 캡션이 있는 이미지 데이터 세트에서 사용자의 설명과 유사한 캡션이 있는 이미지를 찾습니다.

유사성 검색에 대한 간단한 접근 방식은 문서가 쿼리와 얼마나 많은 단어를 공유하는지에 따라 순위를 매기는 것입니다. 그러나 공통 단어가 거의 없더라도 문서가 쿼리와 유사할 수 있으며, 보다 강력한 유사성 개념은 구문 및 의미론적 내용도 고려합니다.

자연어 처리(NLP) 커뮤니티에서는 단어와 문장을 숫자 벡터로 인코딩하는 텍스트 임베딩이라는 기술을 개발했습니다. 이러한 벡터 표현은 텍스트의 언어적 내용을 캡처하도록 설계되었으며 쿼리와 문서 간의 유사성을 평가하는 데 사용할 수 있습니다.

이 게시물에서는 텍스트 임베딩과 Elasticsearch의 dense_vector 유형을 사용하여 유사도 검색을 지원하는 방법을 살펴봅니다. 먼저 임베딩 기술에 대한 개요를 살펴본 다음, Elasticsearch를 사용한 간단한 유사성 검색 프로토타입을 단계별로 살펴보겠습니다.

참고: 검색에서 텍스트 임베딩을 사용하는 것은 복잡하고 진화하는 영역입니다. 이 블로그는 특정 아키텍처나 구현에 대한 권장 사항이 아닙니다. 벡터 검색의 강력한 기능으로 검색 환경을 개선하는 방법을 알아보려면 여기에서 시작하세요.

텍스트 임베딩이란 무엇인가요?

다양한 유형의 텍스트 임베딩과 기존 검색 방식과 비교하여 자세히 살펴보겠습니다.

단어 임베딩

단어 임베딩 모델은 단어를 밀도가 높은 숫자 벡터로 표현합니다. 이러한 벡터는 단어의 의미적 속성을 포착하는 것을 목표로 하며, 벡터가 서로 가까운 단어는 의미적 의미 측면에서 유사해야 합니다. 좋은 임베딩에서는 벡터 공간의 방향이 단어 의미의 다양한 측면에 연결됩니다. 예를 들어, "캐나다" 의 벡터는 한 방향으로는 "프랑스" 에 가깝고 다른 방향으로는 "토론토" 에 가까울 수 있습니다.

NLP 및 검색 커뮤니티에서는 꽤 오랫동안 단어의 벡터 표현에 관심을 가져왔습니다. 지난 몇 년 동안 신경망을 사용하여 많은 전통적인 작업을 재검토하면서 단어 임베딩에 대한 관심이 다시 높아졌습니다. 단어 임베딩 알고리즘이 성공적으로 개발되었는데, 워드2vec과 GloVe가 대표적입니다. 이러한 접근 방식은 대규모 텍스트 컬렉션을 활용하고 각 단어가 나타나는 문맥을 검토하여 벡터 표현을 결정합니다:

  • word2vec 스킵그램 모델은 신경망을 훈련시켜 문장에서 단어 주변의 문맥 단어를 예측합니다. 네트워크의 내부 가중치는 임베딩이라는 단어를 부여합니다.
  • GloVe에서 단어의 유사성은 다른 문맥 단어와 얼마나 자주 나타나는지에 따라 달라집니다. 이 알고리즘은 단어 동시 발생 횟수에 대한 간단한 선형 모델을 학습합니다.

많은 연구 그룹에서 Wikipedia나 Common Crawl과 같은 대규모 텍스트 말뭉치에 대해 사전 학습된 모델을 배포하고 있으므로 다운로드하여 다운스트림 작업에 편리하게 연결할 수 있습니다. 사전 학습된 버전을 직접 사용하는 경우도 있지만, 특정 대상 데이터 세트와 작업에 맞게 모델을 조정하는 것이 도움이 될 수 있습니다. 이는 종종 사전 학습된 모델에 '미세 조정' 단계를 실행하여 수행합니다.

단어 임베딩은 매우 강력하고 효과적인 것으로 입증되었으며, 이제 기계 번역 및 감정 분류와 같은 NLP 작업에서 개별 토큰 대신 임베딩을 사용하는 것이 일반적인 관행이 되었습니다.

문장 임베딩

최근에는 연구자들이 단어뿐만 아니라 긴 텍스트 섹션을 표현하는 임베딩 기술에 집중하기 시작했습니다. 현재 대부분의 접근 방식은 복잡한 신경망 아키텍처를 기반으로 하며, 의미 정보를 포착하는 데 도움을 주기 위해 학습 중에 레이블이 지정된 데이터를 통합하기도 합니다.

학습이 완료된 모델은 문장을 가져와 문맥에 따라 각 단어에 대한 벡터와 전체 문장에 대한 벡터를 생성할 수 있습니다. 단어 임베딩과 마찬가지로 많은 모델의 사전 학습된 버전이 제공되므로 사용자는 값비싼 학습 과정을 생략할 수 있습니다. 학습 과정은 매우 리소스 집약적일 수 있지만, 모델을 호출하는 것은 훨씬 더 가볍습니다. 문장 임베딩 모델은 일반적으로 실시간 애플리케이션의 일부로 사용할 수 있을 만큼 빠릅니다.

몇 가지 일반적인 문장 임베딩 기술로는 InferSent, 범용 문장 인코더, ELMo, BERT 등이 있습니다. 단어 및 문장 임베딩을 개선하는 것은 활발한 연구 분야이며, 강력한 모델이 추가로 도입될 가능성이 높습니다.

기존 검색 방식과 비교

기존 정보 검색에서 텍스트를 숫자 벡터로 표현하는 일반적인 방법은 어휘의 각 단어에 하나의 차원을 할당하는 것입니다. 그런 다음 텍스트의 벡터는 어휘의 각 용어가 나타나는 횟수를 기반으로 합니다. 이러한 텍스트 표현 방식은 문장 구조와 관계없이 단순히 단어 발생 횟수만 계산하기 때문에 흔히 "단어 가방," 이라고도 합니다.

텍스트 임베딩은 몇 가지 중요한 점에서 기존의 벡터 표현과 다릅니다:

  • 인코딩된 벡터는 밀도가 높고 비교적 낮은 차원으로, 보통 100~1,000차원에 걸쳐 있습니다. 이와 대조적으로 단어의 가방 벡터는 희소하며 50,000개 이상의 차원으로 구성될 수 있습니다. 임베딩 알고리즘은 의미론적 의미를 모델링하기 위해 텍스트를 저차원 공간으로 인코딩합니다. 이상적으로 동의어 단어와 구문은 새 벡터 공간에서 비슷한 표현으로 끝납니다.
  • 문장 임베딩은 벡터 표현을 결정할 때 단어의 순서를 고려할 수 있습니다. 예를 들어" 의 "튠이라는 문구는 "의" 과는 매우 다른 벡터로 매핑될 수 있습니다.
  • 실제로 문장 임베딩은 텍스트의 큰 섹션에 잘 적용되지 않는 경우가 많습니다. 일반적으로 짧은 단락보다 긴 텍스트를 나타내는 데는 사용되지 않습니다.

질문과 답변이 많이 모였다고 가정해 보겠습니다. 사용자가 질문을 하면 컬렉션에서 가장 유사한 질문을 검색하여 답변을 찾을 수 있도록 도와줍니다.

텍스트 임베딩을 사용하여 유사한 질문을 검색할 수 있도록 할 수 있습니다:

  • 인덱싱하는 동안 각 질문은 문장 임베딩 모델을 통해 실행되어 숫자 벡터를 생성합니다.
  • 사용자가 쿼리를 입력하면 동일한 문장 임베딩 모델을 통해 실행되어 벡터를 생성합니다. 응답의 순위를 매기기 위해 각 질문과 쿼리 벡터 간의 벡터 유사도를 계산합니다. 임베딩 벡터를 비교할 때는 코사인 유사도를 사용하는 것이 일반적입니다.

이 리포지토리는 Elasticsearch에서 이를 어떻게 수행할 수 있는지에 대한 간단한 예를 보여줍니다. 기본 스크립트는 StackOverflow 데이터 세트에서 최대 20,000개의 질문을 색인한 다음 사용자가 데이터 세트에 대해 자유 텍스트 쿼리를 입력할 수 있도록 합니다.

곧 스크립트의 각 부분을 자세히 살펴보겠지만 먼저 몇 가지 결과 예시를 살펴보겠습니다. 많은 경우, 이 방법은 쿼리와 색인된 질문 간에 단어가 많이 겹치지 않는 경우에도 유사성을 포착할 수 있습니다:

  • "파일 압축하기" 반환 "폴더 압축/압축 풀기 & 파일"
  • "" 반환 문자열이 IP인지 호스트 이름인지 어떻게 알 수 있나요? ""
  • "바이트를 복수로 변환" 반환 "파이썬에서 바이트를 부동 소수점 숫자로 변환하기"

구현 세부 정보

스크립트는 TensorFlow에서 임베딩 모델을 다운로드하고 생성하는 것으로 시작됩니다. Google의 범용 문장 인코더를 선택했지만 다른 많은 임베딩 방법을 사용할 수 있습니다. 스크립트는 추가 교육이나 미세 조정 없이 임베딩 모델을 그대로 사용합니다.

다음으로, 질문 제목, 태그, 그리고 벡터로 인코딩된 질문 제목에 대한 매핑을 포함하는 Elasticsearch 인덱스를 생성합니다:

dense_vector에 대한 매핑에서 벡터에 포함될 차원 수를 지정해야 합니다. title_vector 필드를 색인할 때 Elasticsearch는 매핑에 지정된 것과 동일한 수의 차원을 가지고 있는지 확인합니다.

문서를 색인화하기 위해 임베딩 모델을 통해 질문 제목을 실행하여 숫자 배열을 얻습니다. 이 배열은 title_vector 필드에 있는 문서에 추가됩니다.

사용자가 쿼리를 입력하면 먼저 동일한 임베딩 모델을 통해 텍스트가 실행되고 쿼리 벡터 매개변수에 저장됩니다. 7.3 버전부터 Elasticsearch는 기본 스크립팅 언어로 cosineSimilarity 함수를 제공합니다. 따라서 사용자 쿼리와의 유사성을 기준으로 질문의 순위를 매기기 위해 스크립트_스코어 쿼리를 사용합니다:

모든 새 쿼리에서 스크립트()를 다시 컴파일하지 않도록쿼리 벡터를 스크립트 매개변수로 전달해야 합니다. Elasticsearch는 음수 점수를 허용하지 않으므로 코사인 유사도에 음수 점수를 추가해야 합니다.

| 참고: 이 블로그 게시물은 원래 Elasticsearch 7.3에서 사용할 수 있었던 벡터 함수에 대해 다른 구문을 사용했지만 7.6에서 더 이상 사용되지 않습니다.
|

중요한 제한 사항

script_score 쿼리는 제한적인 쿼리를 래핑하고 반환하는 문서의 점수를 수정하도록 설계되었습니다. 하지만 인덱스의 모든 문서에 대해 스크립트가 실행된다는 의미의 match_all 쿼리를 제공했습니다. 벡터는 문서 채점에는 사용할 수 있지만 초기 검색 단계에서는 사용할 수 없다는 것이 현재 Elasticsearch의 벡터 유사성의 제한 사항입니다. 벡터 유사성을 기반으로 한 검색 지원은 현재 진행 중인 중요한 작업 영역입니다.

모든 문서를 스캔하는 것을 피하고 빠른 성능을 유지하려면 match_all 쿼리를 보다 선택적인 쿼리로 대체할 수 있습니다. 검색에 사용할 수 있는 올바른 쿼리는 특정 사용 사례에 따라 달라질 수 있습니다.

위에서 몇 가지 고무적인 사례를 살펴봤지만, 결과가 노이즈가 많고 직관적이지 않을 수도 있다는 점에 유의해야 합니다. 예를 들어, "파일을 압축하는 경우" " 부분 .csproj에도 높은 점수를 부여합니다. 파일" 및 ".pyc를 피하는 방법 파일은". 그리고 메서드가 놀라운 결과를 반환하는 경우, 각 벡터 구성 요소의 의미가 불분명하고 해석 가능한 개념과 일치하지 않는 경우가 많아 문제를 디버그하는 방법이 항상 명확하지 않습니다. 단어 중복에 기반한 기존의 채점 기법을 사용하면 "이 문서가 높은 순위를 차지한 이유는 무엇인가요? 라는 질문에 답하기가 더 쉬워지는 경우가 많습니다."

앞서 언급했듯이 이 프로토타입은 임베딩 모델을 벡터 필드와 함께 사용할 수 있는 방법을 보여주는 예시일 뿐, 실제 제작에 사용할 수 있는 솔루션은 아닙니다. 새로운 검색 전략을 개발할 때는 자체 데이터에서 접근 방식이 어떻게 수행되는지 테스트하고 일치 검색어와 같은 강력한 기준과 비교하는 것이 중요합니다. 대상 데이터 세트에 대한 임베딩 모델을 미세 조정하거나 단어 수준 쿼리 확장 등 임베딩을 통합하는 다양한 방법을 시도하는 등 확실한 결과를 얻기 전에 전략을 크게 변경해야 할 수도 있습니다.

결론

임베딩 기술은 텍스트의 언어적 콘텐츠를 캡처할 수 있는 강력한 방법을 제공합니다. 임베딩을 색인하고 벡터 거리를 기반으로 점수를 매김으로써 단어 수준의 중첩을 넘어서는 유사성 개념을 사용하여 문서를 비교할 수 있습니다.

벡터 필드 유형을 기반으로 하는 더 많은 기능을 소개할 수 있기를 기대합니다. 검색에 벡터를 사용하는 것은 미묘한 차이가 있고 발전 중인 영역입니다. 언제나 그렇듯이 Github과 토론 포럼에서 여러분의 사용 사례와 경험을 듣고 싶습니다!

자주 묻는 질문

텍스트 유사도 검색이란 무엇인가요?

텍스트 유사도 검색은 사용자가 짧은 자유 텍스트 쿼리를 입력하면 쿼리와의 유사도에 따라 문서 순위가 매겨지는 검색 유형입니다. 질문 답변, 문서 검색, 이미지 검색 등 다양한 사용 사례에서 유용하게 사용할 수 있습니다.

관련 콘텐츠

최첨단 검색 환경을 구축할 준비가 되셨나요?

충분히 고급화된 검색은 한 사람의 노력만으로는 달성할 수 없습니다. Elasticsearch는 여러분과 마찬가지로 검색에 대한 열정을 가진 데이터 과학자, ML 운영팀, 엔지니어 등 많은 사람들이 지원합니다. 서로 연결하고 협력하여 원하는 결과를 얻을 수 있는 마법 같은 검색 환경을 구축해 보세요.

직접 사용해 보세요