<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Valentin Crettaz - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Valentin Crettaz - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/kr/search-labs/author/valentin-crettaz</link>
    </image>
    <link>https://www.elastic.co/kr/search-labs/author/valentin-crettaz</link>
    <atom:link href="https://www.elastic.co/kr/search-labs/rss/author/valentin-crettaz.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[kr]]></language>
    <lastBuildDate>Wed, 23 Sep 2026 01:48:39 GMT</lastBuildDate>
  <item>
    <title><![CDATA[벡터 검색에 대한 간단한 소개]]></title>
    <description><![CDATA[이 글은 시맨틱 검색이라고도 하는 벡터 검색의 복잡성과 Elasticsearch에서 어떻게 구현되는지에 대해 자세히 설명하는 3편의 시리즈 중 첫 번째 글입니다.]]></description>
    <content:encoded><![CDATA[<p>이 글은 시맨틱 검색이라고도 하는 벡터 검색의 복잡성과 Elasticsearch에서 어떻게 구현되는지에 대해 자세히 설명하는 3편의 시리즈 중 첫 번째 글입니다.</p><p>이 첫 번째 파트에서는 벡터 임베딩의 기본 사항과 벡터 검색의 내부 작동 방식에 대한 일반적인 소개에 중점을 둡니다.</p><p>첫 번째 글에서 배운 모든 지식으로 무장하고 <a href="https://www.elastic.co/search-labs/blog/vector-search-set-up-elasticsearch">두 번째</a> 글에서는 Elasticsearch에서 벡터 검색을 설정하는 방법에 대해 자세히 안내합니다.</p><p><a href="https://www.elastic.co/search-labs/blog/hybrid-search-elasticsearch">세 번째 파트</a>에서는 앞선 두 파트에서 배운 내용을 활용하고, 그 지식을 바탕으로 Elasticsearch에서 강력한 하이브리드 검색 쿼리를 작성하는 방법에 대해 자세히 알아보겠습니다.</p><p>이 글의 본론으로 들어가기 전에 시간을 거슬러 올라가 시맨틱 검색의 핵심 개념인 벡터의 역사에 대해 살펴봅시다.</p><h2>벡터는 새로운 것이 아닙니다.</h2><p>2022년 11월 ChatGPT가 등장한 이후 "벡터 검색"에 대해 듣거나 읽지 않고는 단 하루도 지나가지 않는다는 사실에 모두가 동의할 것입니다. 어디에나 있고 너무 널리 퍼져 있어 이제 막 나온 새로운 첨단 기술이라는 인상을 받기도 하지만, 사실 이 기술은 60년 이상 전부터 사용되어 온 기술입니다! 이 주제에 대한 연구는 1960년대 중반에 시작되었으며, 1978년 코넬 대학교의 정보 검색 전문가인 제라드 살튼과 그의 동료들이 최초의 연구 논문을 발표했습니다. 고밀도 및 희소 벡터 모델에 대한 Salton의 연구는 현대 벡터 검색 기술의 근간을 이루고 있습니다.</p><p>지난 20년 동안 그의 연구를 기반으로 한 다양한 <a href="https://db-engines.com/en/ranking/vector+dbms/all">벡터 DBMS가</a> 개발되어 시장에 출시되었습니다. 여기에는 2019년에 <a href="https://issues.apache.org/jira/browse/LUCENE-9004">벡터 검색 작업을</a> 시작한 Apache Lucene 프로젝트 기반의 Elasticsearch가 포함됩니다.</p><p>벡터는 이제 어디에나 있고 널리 퍼져 있으므로 벡터를 활용하기 전에 먼저 벡터의 기본 이론과 내부 작동 원리를 잘 이해하는 것이 중요합니다. 자세히 알아보기 전에 어휘 검색과 벡터 검색의 차이점을 간단히 살펴봄으로써 두 검색이 어떻게 다르고 어떻게 서로를 보완할 수 있는지 더 잘 이해할 수 있도록 하겠습니다.</p><h2>벡터 검색과 어휘 검색 비교</h2><p>벡터 검색을 소개하는 쉬운 방법은 익숙한 기존의 어휘 검색과 비교하는 것입니다. 일반적으로 시맨틱 검색이라고도 하는 벡터 검색과 어휘 검색은 작동 방식이 매우 다릅니다. 어휘 검색은 우리 모두가 Elasticsearch에서 수년 동안 사용해온 검색입니다. 간단히 요약하자면, 색인되고 쿼리되는 내용의 실제 의미를 이해하려고 노력하는 것이 아니라, 사용자가 쿼리에 입력하는 단어의 리터럴 또는 그 변형(어간, 동의어 등)을 TF-IDF와 같은 유사성 알고리즘을 사용하여 이전에 데이터베이스에 색인된 모든 리터럴과 <strong>어휘적으로</strong> 일치시키기 위해 많은 노력을 기울이는 것입니다.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfbb8e150865a5ec8/6a17e0c725daab50f408a16e/a4f3eba19599e5330e9b0d29ecdbbeac211cdab0-1600x583.png" alt="어휘 검색 예제" /><p>보시다시피 왼쪽 상단에 있는 세 개의 문서는 토큰화되어 분석되고 있습니다. 그런 다음 결과 용어가 역 인덱스에 색인되어 분석된 용어를 해당 용어가 포함된 문서 ID에 간단히 매핑합니다. 모든 용어는 한 번만 표시되며 어떤 문서에서도 공유되지 않는다는 점에 유의하세요. "멋진 독일어 선생님"을 검색하면 세 문서 모두 다른 점수로 일치하지만, 그 중 어느 것도 쿼리의 진정한 의미를 파악하지 못합니다.</p><p>아래 그림 2에서 볼 수 있듯이 다의어 또는 동음이의어, 즉 철자는 같지만 <strong>다른 의미</strong> (오른쪽, 손바닥, 방망이, 평균 등)를 가진 단어를 다룰 때는 더욱 까다로워집니다. 세 가지 의미를 가질 수 있는 '오른쪽'이라는 단어를 예로 들어 어떤 일이 일어나는지 살펴봅시다.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltea0cc829ff2c8029/6a17e0c92f4a5c8107fa8811/ebb9cc1be03475bbf68269a8dcea5f08bcda0b64-1594x754.png" alt="어휘 검색으로 동음이의어 검색하기" /><p><em>"나는 옳지 않다"를</em> 검색하면 첫 번째 반환된 결과와 정반대의 의미를 가진 문서가 반환됩니다. 완전히 동일한 용어를 검색하지만 순서를 달리하여 다른 의미를 생성하는 경우(예: <em>"우회전</em> "과 <em>"우회전</em> ") 완전히 동일한 결과가 표시됩니다(예: 세 번째 문서 "우회전"). 물론 쿼리가 지나치게 단순화되어 있고 구문 검색과 같은 고급 쿼리를 사용하지는 않지만, 이는 어휘 검색이 색인된 내용과 검색된 내용의 진정한 의미를 이해하지 못한다는 것을 보여주는 예시입니다. 명확하지 않더라도 걱정하지 마세요. 세 번째 글에서 이 예시를 다시 살펴보고 벡터 검색이 이 경우에 어떻게 도움이 되는지 알아보겠습니다.</p><p><strong>구조화된</strong> 데이터를 색인하는 방법(매핑, 텍스트 분석, 수집 파이프라인 등)과 쿼리를 작성하는 방법(영리하게 만들어진 DSL 쿼리, 쿼리 용어 분석 등)을 제어할 수 있다면 어휘 검색 엔진으로 놀라운 일을 할 수 있다는 것은 의심의 여지가 없습니다! 어휘 검색 기능에 관한 Elasticsearch의 실적은 정말 놀랍습니다. 지난 몇 년 동안 어휘 검색 분야를 대중화하고 개선한 성과는 정말 놀랍습니다.</p><p>그러나 자유 텍스트 질문을 해야 하는 사용자에게 <a href="https://www.elastic.co/what-is/unstructured-data"><strong>비정형</strong></a><a href="https://www.elastic.co/what-is/unstructured-data"> 데이터</a> (이미지, 동영상, 오디오, 원시 텍스트 등)에 대한 쿼리 지원을 제공해야 하는 경우 어휘 검색만으로는 부족합니다. 또한 곧 살펴보겠지만 쿼리가 텍스트가 아닌 이미지일 수도 있습니다. 이러한 상황에서 어휘 검색이 부적절한 주된 이유는 비정형 데이터는 정형 데이터와 동일한 방식으로 색인화하거나 쿼리할 수 없기 때문입니다. 비정형 데이터를 다룰 때는 <strong>의미론이</strong> 중요한 역할을 합니다. 시맨틱이란 무엇을 의미하나요? 아주 간단하게 말하자면, 의미입니다!</p><p>이미지 검색 엔진(예: Google 이미지 검색 또는 렌즈)의 간단한 예를 들어 보겠습니다. 이미지를 끌어다 놓으면 Google 시맨틱 검색 엔진이 쿼리한 이미지와 가장 유사한 이미지를 찾아서 반환합니다. 아래 그림 3에서 왼쪽에는 독일 셰퍼드 사진이 있고 오른쪽에는 검색된 모든 유사한 사진이 표시되며, 첫 번째 결과는 제공된 사진과 동일한 사진(즉, 가장 유사한 사진)입니다.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3e0a0fb3c300537a/6a17e0cbe8fbce69d13a185d/c0dff24d4379141abd1038c9c4b5577fd2dca802-1600x657.png" alt="시맨틱 검색 예제: 사진 검색하기" /><p>사람에게는 간단하고 논리적으로 들리지만 컴퓨터에게는 완전히 다른 이야기입니다. 이것이 바로 벡터 검색이 가능하게 하고 달성하는 데 도움이 되는 것입니다. 최근 전 세계가 목격했듯이 벡터 검색의 잠재력은 엄청납니다. 이제 후드를 열고 그 아래에 무엇이 숨어 있는지 알아봅시다.</p><h2>벡터 임베딩</h2><p>앞서 살펴본 것처럼 어휘 검색 엔진을 사용하면 텍스트와 같은 구조화된 데이터를 용어의 실제 의미와 관계없이 검색 시 일치할 수 있는 용어로 쉽게 토큰화할 수 있습니다. 그러나 비정형 데이터는 이미지, 동영상, 오디오 등 다양한 형태로 존재할 수 있으며, 동일한 토큰화 프로세스에 전혀 적합하지 않습니다. 또한 시맨틱 검색의 전체 목적은 데이터가 나타내는 의미에 따라 검색할 수 있도록 데이터를 색인하는 것입니다. 이를 어떻게 달성할 수 있을까요? 그 답은 두 단어에 있습니다: 바로 <strong>머신 러닝입니다</strong>! 더 정확하게는 딥러닝!</p><p><strong>딥러닝은</strong> 데이터의 진정한 의미를 점진적으로 추출할 수 있는 여러 처리 계층으로 구성된 인공 신경망 기반 모델에 의존하는 머신러닝의 특정 영역입니다. 이러한 신경망 모델이 작동하는 방식은 인간의 뇌에서 많은 영감을 받았습니다. 아래 그림 4는 입력 및 출력 계층과 여러 개의 숨겨진 계층이 있는 신경망의 모습을 보여줍니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8ca5fd8f0e61d939/6a17e0cd7f6f152a67c09a53/aeea3bab3c29e1c591a9c9082f2e73e7d3990ef1-1600x1116.png" alt="벡터 검색의 신경망 레이어" /><p>신경망의 진정한 위업은 하나의 비정형 데이터를 일련의 부동 소수점 값으로 변환할 수 있다는 점인데, 이를 임베딩 <strong>벡터</strong> 또는 간단히 <strong>임베딩이라고</strong> 합니다. 인간은 벡터를 2차원 또는 3차원 공간에서 시각화하면 벡터가 무엇인지 꽤 잘 이해할 수 있습니다. 벡터의 각 구성 요소는 2D x-y 평면 또는 3D x-y-z 공간의 좌표를 나타냅니다.</p><p>그러나 신경망 모델이 작동하는 임베딩 벡터는 수백 또는 수천 개의 차원을 가질 수 있으며 단순히 다차원 공간의 한 점을 나타낼 수 있습니다. 각 벡터 차원은 비정형 데이터의 <strong>특징</strong> 또는 특성을 나타냅니다. 이미지를 2048차원의 임베딩 벡터로 변환하는 딥러닝 모델을 통해 이를 설명해 보겠습니다. 이 모델은 그림 3에서 사용한 독일 셰퍼드 그림을 아래 표에 표시된 임베딩 벡터로 변환합니다. 여기서는 첫 번째와 마지막 세 요소만 표시하지만 테이블에는 2,042개의 열/차원이 더 있습니다.</p><p></p><p>is_red</p><p>is_dog</p><p>blue_sky</p><p>…</p><p>no_gras</p><p>게르만 셰퍼드</p><p>is_tree</p><p>독일 셰퍼드 임베딩</p><p>0.0121</p><p>0.9572</p><p>0.8735</p><p>…</p><p>0.1198</p><p>0.9712</p><p>0.0512</p><p>각 열은 모델의 차원이며 기본 신경망이 모델링하고자 하는 기능 또는 특성을 나타냅니다. 모델에 주어진 각 입력은 해당 입력이 2048개의 각 차원과 얼마나 유사한지에 따라 특성화됩니다. 따라서 임베딩 벡터의 각 요소 값은 해당 입력과 특정 차원의 <strong>유사성을</strong> 나타냅니다. 이 예시에서는 모델이 개와 독일 셰퍼드 사이의 높은 유사성과 푸른 하늘의 존재를 감지한 것을 볼 수 있습니다.</p><p>용어의 일치 여부만 알 수 있는 어휘 검색과 달리, 벡터 검색을 사용하면 비정형 데이터 조각이 모델이 지원하는 각 차원과 얼마나 <em>유사한지</em> 훨씬 더 잘 파악할 수 있습니다. 이처럼 임베딩 벡터는 비정형 데이터를 환상적으로 의미적으로 표현하는 역할을 합니다.</p><h2>비법 소스</h2><p>이제 비정형 데이터가 딥러닝 신경망에 의해 여러 차원에 걸쳐 데이터의 유사성을 포착하는 임베딩 벡터로 잘게 쪼개지는 방법을 알았으니, 이러한 벡터의 매칭이 어떻게 작동하는지 이해해야 합니다. 그 답은 매우 간단합니다. 서로 <strong>가까운</strong> 벡터를 임베딩하면 <strong>의미적으로 유사한</strong> 데이터 조각을 나타냅니다. 따라서 벡터 데이터베이스를 쿼리할 때 먼저 모든 비정형 데이터 색인에 사용된 것과 동일한 모델을 사용하여 검색 입력(이미지, 텍스트 등)을 임베딩 벡터로 변환하고, 최종 목표는 해당 쿼리 벡터와 <strong>가장 가까운 이웃 벡터를</strong> 찾는 것입니다. 따라서 쿼리 벡터와 데이터베이스에 색인된 모든 기존 벡터 사이의 '거리' 또는 '유사성'을 측정하는 방법만 알아내면 됩니다.</p><h3>거리 및 유사성</h3><p>다행히도 두 벡터 사이의 거리를 측정하는 것은 벡터 산술 덕분에 쉽게 해결할 수 있는 문제입니다. 이제 Elasticsearch와 같은 최신 벡터 검색 데이터베이스에서 지원하는 가장 널리 사용되는 거리 및 유사도 함수에 대해 살펴보겠습니다. 경고, 수학이 앞서갑니다!</p><h4>L1 거리</h4><p>맨해튼 거리라고도 하는 두 벡터 x와 y의 L1 거리는 모든 요소의 쌍별 절대 차이를 합산하여 측정합니다. 당연히 거리 d가 작을수록 두 벡터는 더 가까워집니다. 아래에서 볼 수 있듯이 공식은 매우 간단합니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2df2e9bc20883491/6a17e0ce033c8d006a6bb0bf/2b17bcedfbedde61117a3e7970af55bc62318c6c-312x102.png" alt="벡터 검색의 L1 거리 공식" /><p>시각적으로 L1 거리는 아래 그림 5와 같이 설명할 수 있습니다:</p><p></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb90a33e6b1cbe00b/6a17e0d0414c64eb76945096/52075441892151536ed216081817a8e852566daa-474x464.png" alt="두 벡터 사이의 L1 거리 시각화하기" /><p>x = (1, 2), y = (4, 3)과 같은 두 벡터 x와 y를 예로 들면 두 벡터의 L1 거리는 | 1 - 4 | + | 2 - 3 | = 4가 됩니다.</p><h4>L2 거리</h4><p>유클리드 거리라고도 하는 두 벡터 x와 y의 L2 거리는 먼저 모든 요소의 쌍별 차이의 제곱을 합한 다음 그 결과의 제곱근을 구하여 측정합니다. 기본적으로 두 점 사이의 최단 경로(빗변이라고도 함)입니다. L1과 마찬가지로, 거리 d가 작을수록 두 벡터는 더 가까워집니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltae9b63fb593ae225/6a17e0d1af47b68379cddea8/b7675aa41f4f381e954c21dacd23a51a2dde6780-384x112.png" alt="벡터 검색의 L2 거리" /><p>L2 거리는 아래 그림 6에 나와 있습니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt32d913b46e07e79d/6a17e0d27f6f1582f7c09a57/bac99d08d6cf8a3a387a8acdc2e8f67357dad235-448x456.png" alt="두 벡터 사이의 L2 거리 시각화하기" /><p>L1 거리에서 사용한 것과 동일한 두 개의 샘플 벡터 x와 y를 재사용하면 이제 L2 거리를  계산할 수 있습니다. 10의 제곱근을 구하면 3.16이 됩니다.</p><p></p><h4>린프 거리</h4><p>체비셰프 또는 체스판 거리라고도 하는 두 벡터 x와 y의 Linf(무한대의 경우) 거리는 간단히 두 요소 사이의 최장 거리 또는 축/차원 중 하나를 따라 측정한 최장 거리로 정의됩니다. 공식은 매우 간단하며 아래와 같습니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt863411e15de16fa3/6a17e0d4505ac30939ad8a48/179ea6c6520a59acd97638313a2fb1b105e2ffed-436x82.png" alt="벡터 검색의 린프 거리 공식" /><p>린프 거리의 표현은 아래 그림 7에 나와 있습니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt863ee7b51fd5fc15/6a17e0d56864a4772db686af/b75540d793cdc0645244d77dc36da9d5734ccbac-548x560.png" alt="두 벡터 사이의 선형 거리" /><p>다시, 동일한 두 개의 샘플 벡터 x와 y를 사용하여 최대 ( | 1 - 4 | , | 2 - 3 | ) = 최대 (3, 1) = 3으로 L 무한대 거리를 계산할 수 있습니다.</p><h4>코사인 유사도</h4><p>L1, L2, Linf와 달리 코사인 유사도는 두 벡터 x와 y 사이의 거리를 측정하는 것이 아니라 상대 각도, 즉 둘이 거의 같은 방향을 가리키고 있는지 여부를 측정합니다. 유사도 s가 높을수록 두 벡터가 "더 가깝다"는 의미입니다. 공식은 다시 매우 간단하며 아래와 같습니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt61d55341a6457ab7/6a17e0d7e9ea872b4ea9c4e2/931b6b90f0ee83e63a66496d06d6b4cef3affddd-304x72.png" alt="벡터 검색의 코사인 유사도 공식" /><p>두 벡터 간의 코사인 유사성을 표현하는 방법은 아래 그림 8에 나와 있습니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt50eb6399510b5380/6a17e0d83e9e45302cba139a/52092e8b5d366178e50a35f8c954ee8eaca76965-582x586.png" alt="두 벡터 간의 코사인 유사도" /><p>또한 코사인 값은 항상 [-1, 1] 간격에 있으므로 아래 그림 9와 같이 -1은 반대 유사성(즉, 두 벡터 사이의 180° 각도), 0은 무관한 유사성(즉, 90° 각도), 1은 동일성(즉, 0° 각도)을 의미합니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt785e195c75a5089e/6a17e0da1d1b8355bc93e398/fd2690a845b89b69ff202bd04192893638538aec-1600x456.png" alt="벡터 검색의 코사인 유사도 스펙트럼" /><p>
다시 한 번 동일한 샘플 벡터 x와 y를 재사용하고 위의 공식을 사용하여 코사인 유사도를 계산해 보겠습니다. 먼저 두 벡터의 내적을  계산할 수 있습니다. 그런 다음 두 벡터의 길이(크기라고도 함)를 곱합니다:  + (4^2 + 3^2)^{1/2} = 11.18034. 마지막으로 도트 곱을 곱한 길이 10 / 11.18034 = 0.894427(즉, 26° 각도)로 나누면 1에 매우 가깝기 때문에 두 벡터는 매우 유사하다고 볼 수 있습니다.</p><h4>도트 제품 유사성</h4><p>코사인 유사도의 한 가지 단점은 두 벡터 사이의 각도만 고려하고 크기(즉, 길이)는 고려하지 않기 때문에 두 벡터가 대략 같은 방향을 가리키지만 한쪽이 다른 쪽보다 훨씬 길어도 둘 다 비슷한 것으로 간주된다는 점입니다. 스칼라 또는 내적 곱이라고도 하는 도트 곱 유사성은 벡터의 각도와 크기를 모두 고려하여 훨씬 더 정확한 유사성 지표를 제공함으로써 이를 개선합니다.</p><p>도트 제품 유사성을 계산하는 데는 두 가지 동등한 공식이 사용됩니다. 첫 번째는 앞서 코사인 유사도의 분자에서 살펴본 것과 동일합니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7f1c3369f8628457/6a17e0db1d1b832a1893e39c/52e2723926ab27cd96b688e805fae15f607073c8-482x104.png" alt="벡터 검색의 도트 곱 유사도 공식" /><p>두 번째 공식은 두 벡터의 길이에 두 벡터 사이의 각도의 코사인을 곱하기만 하면 됩니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt136dd2a749c2398a/6a17e0dc6df73108a80a0e1f/dc9b11fc67dd748d9f1f29b735f4726138cb7d39-452x70.png" alt="벡터 검색에서 단순화된 도트 곱 유사도 공식" /><p>도트 제품 유사성은 아래 그림 10에 시각화되어 있습니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb2c095e1c1948752/6a17e0dd6df731e30b0a0e23/1bda38cf82a1e1037f44b6e9657602c9efe1c0a6-558x574.png" alt="두 벡터 간의 도트 곱 유사성" /><p>마지막으로 샘플 x 및 y 벡터를 가져와 앞서 코사인 유사도 때와 마찬가지로 첫 번째 공식을 사용하여 (1 ) + (2 ) = 10으로 도트 곱 유사도를 계산합니다.</p><p>두 번째 공식을 사용하여 두 벡터의 길이를 곱합니다:  + (4^2 + 3^2)^{1/2} = 11.18034에 두 벡터 사이의 26° 각도의 코사인을 곱하면 11.18034 (26°) = 10을 구할 수 있습니다.</p><p>한 가지 주목할 점은 모든 벡터가 먼저 <strong>정규화되면</strong> (즉, 길이가 1이면) 도트 곱 유사도는 코사인 유사도(|x| |y| = 1이므로), 즉 두 벡터 사이의 각도의 코사인과 정확히 동일해진다는 점입니다. 나중에 살펴보겠지만, 벡터를 정규화하는 것은 벡터의 크기를 무의미하게 만들어 유사성이 단순히 각도에 초점을 맞추기 위해 채택하는 좋은 관행입니다. 또한 수십억 개의 벡터를 처리할 때 큰 문제가 될 수 있는 인덱싱 및 쿼리 시 거리 계산의 속도를 높여줍니다.</p><h3>빠른 요약</h3><p>지금까지 많은 정보를 살펴보았으니 잠시 멈춰서 현재 상황을 간단히 정리해 보겠습니다. 우리는 배웠습니다...</p><ul><li><p>...시맨틱 검색은 비정형 데이터를 다차원 임베딩 벡터로 변환하는 데 탁월한 딥러닝 신경망 모델을 기반으로 합니다.</p></li><li><p>...모델의 각 차원은 비정형 데이터의 기능 또는 특성을 나타냅니다.</p></li><li><p>...임베딩 벡터는 주어진 비정형 데이터 조각이 각 차원과 얼마나 유사한지를 나타내는 유사도 값의 시퀀스(각 차원에 대해 하나씩)입니다.</p></li><li><p>... 두 벡터가 "더 가깝게"(즉, 가장 가까운 이웃) 있을수록 의미적으로 유사한 개념을 더 많이 나타냅니다.</p></li><li><p>...거리 함수(L1, L2, Linf)를 사용하면 두 벡터가 얼마나 가까운지 측정할 수 있습니다.</p></li><li><p>...유사도 함수(코사인과 도트 곱)를 사용하면 두 벡터가 얼마나 같은 방향으로 향하고 있는지 측정할 수 있습니다.</p></li></ul><p></p><p>이제 마지막으로 살펴봐야 할 부분은 벡터 검색 엔진 자체입니다. 쿼리가 들어오면 먼저 쿼리를 벡터화한 다음 벡터 검색 엔진이 해당 쿼리 벡터에 가장 가까운 이웃 벡터를 찾습니다. 쿼리 벡터와 데이터베이스의 모든 벡터 사이의 거리 또는 유사성을 측정하는 무차별 대입 방식은 작은 데이터 세트에서는 효과가 있지만 벡터의 수가 증가하면 금방 부족해집니다. 다르게 말하면 수백만, 수십억, 심지어 수조 개의 벡터를 색인하고 합리적인 시간 내에 쿼리 벡터의 가장 가까운 이웃을 찾을 수 있는 방법은 무엇일까요? 따라서 정밀도를 크게 떨어뜨리지 않으면서 최대한 빠르게 가장 가까운 이웃을 찾아낼 수 있도록 최적의 벡터 인덱싱 방법을 찾아내야 합니다.</p><h3>벡터 검색 알고리즘 및 기법</h3><p>수년 동안 많은 연구팀이 매우 영리한 벡터 검색 알고리즘을 개발하기 위해 많은 노력을 기울여 왔습니다. 여기에서는 주요 기능에 대해 간략하게 소개하겠습니다. 사용 사례에 따라 어떤 것이 다른 것보다 더 적합한 경우도 있습니다.</p><h4>선형 검색</h4><p>앞서 데이터베이스에 존재하는 모든 벡터와 쿼리 벡터를 비교하는 무차별 대입 방식을 언급하면서 선형 검색 또는 플랫 인덱싱에 대해 간략하게 살펴봤습니다. 작은 데이터 세트에서는 잘 작동할 수 있지만, 벡터와 차원 수가 증가하면 성능이 급격히 저하됩니다(복잡도 O(n))).</p><p>다행히도 임베딩 벡터 사이의 거리를 미리 계산하고 클러스터, 트리, 해시 또는 그래프를 사용하여 유사한 벡터를 서로 가깝게 유지하는 방식으로 저장하고 구성하는 <strong>근사 최인접 이웃</strong> (ANN)이라는 보다 효율적인 접근 방식이 있습니다. 이러한 접근 방식은 일반적으로 100%% 정확도를 보장하지 않기 때문에 '근사치'라고 합니다. 궁극적인 목표는 유사한 벡터를 포함할 가능성이 가장 높은 영역에만 집중하기 위해 <strong>검색 범위를</strong> 최대한 빨리, 그리고 최대한 많이 줄이거나 <strong>벡터의 차원을 줄이는</strong> 것입니다.</p><h4>K-차원 트리</h4><p>K 차원 트리 또는 KD 트리는 이진 검색 트리를 일반화한 것으로, K 차원 공간에 포인트를 저장하고 벡터가 색인되는 작은 왼쪽과 오른쪽 트리로 검색 공간을 계속 이등분하여 작동합니다. 검색 시 알고리즘은 가장 가까운 이웃(그림 11의 녹색 점)을 찾기 위해 쿼리 벡터(그림 11의 빨간색 점) 주변의 트리 가지 몇 개를 방문하기만 하면 됩니다. k개 이상의 이웃이 요청되면 알고리즘이 더 많은 이웃을 찾을 때까지 노란색 영역이 확장됩니다.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt55e01707cd9fca57/6a17e0dfbe60866a90004653/e21af2d613112279089b6fa2166359233b10019d-829x860.png" alt="벡터 검색의 KD 트리 알고리즘" /><p>KD 트리 알고리즘의 가장 큰 장점은 일부 국소화된 트리 가지에만 빠르게 집중할 수 있어 대부분의 벡터를 고려 대상에서 제외할 수 있다는 점입니다. 그러나 이 알고리즘은 차원 수가 증가할수록 저차원 공간보다 더 많은 브랜치를 방문해야 하므로 효율성이 떨어집니다.</p><h4>반전된 파일 색인</h4><p>거꾸로 파일 인덱스(IVF) 방식은 서로 가까운 벡터를 공유 중심점에 할당하는 <strong>공간 분할</strong> 알고리즘이기도 합니다. 2D 공간에서는 그림 12와 같이 보로노이 다이어그램으로 이를 가장 잘 시각화할 수 있습니다:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7b7e4fe6deff5ef3/6a17e0e17b54f940eb8b381c/33ddaaa818ab2f2a5fc87982c82c2a34cb849e33-640x640.png" alt="2D 공간에서 반전된 파일 인덱스의 보로노이 표현 " /><p>위의 2D 공간은 20개의 클러스터로 분할되어 있으며, 각 클러스터의 중심은 검은색 점으로 표시되어 있음을 알 수 있습니다. 공간의 모든 임베딩 벡터는 중심이 가장 가까운 클러스터에 할당됩니다. 검색 시 알고리즘은 먼저 쿼리 벡터에 가장 가까운 중심을 찾아 집중해야 할 클러스터를 파악한 다음, 해당 영역과 필요한 경우 주변 영역까지 제로화하여 가장 가까운 이웃을 찾을 수 있습니다.</p><p>이 알고리즘은 고차원 공간에서 사용할 때 KD 트리와 동일한 문제를 겪습니다. 이를 차원의 저주라고 하며, 공간의 부피가 너무 커져서 모든 데이터가 희박해 보이고 더 정확한 결과를 얻기 위해 필요한 데이터의 양이 기하급수적으로 늘어날 때 발생합니다. 데이터가 희소하면 이러한 공간 분할 알고리즘이 데이터를 클러스터로 구성하기가 더 어려워집니다. 다행히도 아래에 자세히 설명된 것처럼 이 문제를 완화하는 다른 알고리즘과 기술이 있습니다.</p><h4>양자화</h4><p>양자화는 임베딩 벡터의 정밀도를 낮춤으로써 데이터베이스의 전체 크기를 줄일 수 있는 <strong>압축 기반</strong>접근 방식입니다. 이는 부동 소수점 벡터 값을 정수 값으로 변환하는 <strong>스칼라 양자화(SQ)를</strong> 사용하여 달성할 수 있습니다. 이렇게 하면 데이터베이스의 크기가 8배까지 줄어들 뿐만 아니라 메모리 사용량도 감소하고 검색 시 벡터 간의 거리 계산 속도도 빨라집니다.</p><p>또 다른 기법은 <strong>제품 양자화(PQ)</strong> 로, 먼저 공간을 저차원 하위 공간으로 나눈 다음 클러스터링 알고리즘(K-평균과 유사)을 사용하여 서로 가까운 벡터를 각 하위 공간에 그룹화합니다.</p><p>양자화는 차원 수가 줄어드는 <strong>차원 축소</strong>, 즉 벡터가 단순히 짧아지는 차원 축소와는 다릅니다.</p><h4>계층적 탐색 가능한 작은 세계(HNSW)</h4><p>이름만 보고 복잡해 보이더라도 걱정하지 마세요, 실제로는 그렇지 않으니까요! 간단히 말해 계층적 탐색 가능한 작은 세계는 매우 인기 있고 효율적인 다층 그래프 기반 알고리즘입니다. 아파치 루씬을 비롯한 다양한 벡터 데이터베이스에서 사용됩니다. 아래 그림 13에서 HNSW의 개념적 표현을 볼 수 있습니다.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7f4f4a8e393c8d53/6a17e0e3e8fbcefa193a1861/189ef9a8bec476e379222c454644ba4c1f952085-1400x840.png" alt="계층적 탐색 가능한 작은 세계(HNSW)" /><p>최상위 레이어에서는 벡터들 사이에 가장 긴 연결 고리를 가진 극소수의 벡터, 즉 유사성이 가장 낮은 연결된 벡터의 그래프를 볼 수 있습니다. 더 낮은 레이어로 내려갈수록 더 많은 벡터를 발견할 수 있으며, 그래프는 점점 더 밀도가 높아져 서로 가까운 벡터가 많아집니다. 가장 낮은 레이어에서 모든 벡터를 찾을 수 있으며, 가장 유사한 벡터가 서로 가장 가까운 곳에 위치합니다.</p><p>검색 시 알고리즘은 임의의 진입점의 최상위 레이어에서 시작하여 쿼리 벡터에 가장 가까운 벡터(회색 점으로 표시됨)를 찾습니다. 그런 다음 한 레이어 아래로 이동하여 가장 낮은 레이어에 도달하여 쿼리 벡터와 가장 가까운 이웃을 찾을 때까지 위 레이어에 남긴 동일한 벡터에서 시작하여 동일한 과정을 한 레이어씩 차례로 반복합니다.</p><h4>지역 민감 해싱(LSH)</h4><p>지금까지 소개한 다른 모든 접근 방식과 같은 맥락에서, 위치 정보에 민감한 해싱은 검색 속도를 높이기 위해 검색 공간을 대폭 줄이려고 합니다. 이 기술을 사용하면 임베딩 벡터가 유사성 정보를 보존하면서 해시값으로 변환되므로 검색 공간은 궁극적으로 탐색해야 하는 그래프나 트리 대신 조회할 수 있는 간단한 해시 테이블이 됩니다. 해시 기반 방법의 가장 큰 장점은 임의의 (큰) 수의 차원을 포함하는 벡터를 고정 크기 해시에 매핑할 수 있어 정밀도를 크게 떨어뜨리지 않으면서 검색 시간을 크게 단축할 수 있다는 것입니다.</p><p>일반적으로 데이터를 해싱하는 방법, 특히 벡터를 임베딩하는 방법에는 여러 가지가 있지만 이 글에서는 각 방법에 대해 자세히 다루지는 않겠습니다. 기존의 해시 방식은 일반적으로 매우 비슷해 보이는 데이터에 대해 매우 다른 해시를 생성합니다. 임베딩 벡터는 실수 값으로 구성되므로 벡터 산술에서 서로 매우 가까운 것으로 간주되는 두 개의 샘플 실수 값(예: 0.73 및 0.74)을 가져와 몇 가지 일반적인 해싱 함수를 통해 실행해 보겠습니다. 아래 결과를 보면 일반적인 해싱 함수는 입력 간의 유사성을 유지하지 못한다는 것을 알 수 있습니다.</p><p>해싱 기능</p><p>0.73</p><p>0.74</p><p>MD5</p><p>1342129d04cd2924dd06cead4cf0a3ca</p><p>0aec1b15371bd979cfa66b0a50ebecc5</p><p>SHA1</p><p>49d2c3e0e44bff838e1db571a121be5ea874e8d9</p><p>a534e76482ade9d9fe4bff3035a7f31f2f363d77</p><p>SHA256</p><p>99d03fc3771fe6848d675339fc49eeb1cb8d99a12e6358173336b99a2ec530ea</p><p>5ecbc825ba5c16856edfdaf0abc5c6c41d0d8a9c508e34188239521dc7645663</p><p>기존의 해싱 방식은 유사한 데이터 조각 간의 <em>해싱 충돌을 최소화하려고</em> 하지만, 지역 민감 해싱의 주요 목표는 정반대로, 즉 <em>해싱 충돌을 최대화하여</em> 유사한 데이터가 높은 확률로 같은 버킷에 속하도록 하는 것입니다. 이렇게 하면 다차원 공간에서 서로 가까이 있는 벡터를 임베딩하면 동일한 버킷에 속하는 고정된 크기의 값으로 해시됩니다. LSH는 해시된 벡터가 근접성을 유지할 수 있도록 해주기 때문에 데이터 클러스터링과 가장 가까운 이웃 검색에 매우 유용한 기술입니다.</p><p>모든 무거운 작업은 해시를 계산해야 하는 인덱싱 시점에 이루어지며, 검색 시에는 가장 가까운 임베딩 벡터가 포함된 버킷을 조회하기 위해 쿼리 벡터만 해시하면 됩니다. 후보 버킷이 발견되면 일반적으로 쿼리 벡터에 가장 가까운 이웃 벡터를 식별하기 위해 두 번째 라운드가 진행됩니다.</p><h2>결론을 내리겠습니다.</h2><p>벡터 검색을 소개하기 위해 이 글에서 꽤 많은 내용을 다루어야 했습니다. 어휘 검색과 벡터 검색의 차이점을 비교한 후, 딥러닝 신경망 모델이 어떻게 비정형 데이터의 의미를 파악하고 그 의미를 고차원 임베딩 벡터(모델의 각 차원에 따라 데이터의 유사성을 나타내는 부동 소수점 숫자 시퀀스)로 변환하는지에 대해 알아봤습니다. 벡터 검색과 어휘 검색은 경쟁하는 것이 아니라 상호 보완적인 정보 검색 기술이라는 점도 주목할 필요가 있습니다(이 시리즈의 3부에서 하이브리드 검색에 대해 자세히 살펴보겠습니다).</p><p>그 후, 벡터 검색의 기본 구성 요소인 거리(및 유사도) 함수를 도입하여 두 벡터의 근접성을 측정하고 벡터가 나타내는 개념의 유사성을 평가할 수 있게 했습니다.</p><p>마지막으로 트리, 그래프, 클러스터 또는 해시를 기반으로 하는 가장 인기 있는 벡터 검색 알고리즘과 기법의 다양한 종류를 살펴보았는데, 선형 무차별 대입 검색처럼 전체 공간을 둘러볼 필요 없이 다차원 공간의 특정 영역을 빠르게 좁혀 가장 가까운 이웃을 찾는 것이 목표입니다.</p><p>읽고 있는 내용이 마음에 드신다면 이 시리즈의 다른 부분도 꼭 확인해 보세요:</p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/vector-search-set-up-elasticsearch">2부: Elasticsearch에서 벡터 검색을 설정하는 방법</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/hybrid-search-elasticsearch">3부: Elasticsearch를 사용한 하이브리드 검색</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/introduction-to-vector-search</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/introduction-to-vector-search</guid>
    <category><![CDATA[벡터 데이터베이스]]></category>
    <dc:creator><![CDATA[Valentin Crettaz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt70da374b8dc0c490/6a17e0e46864a473aab686b3/63eea8ea95b49e7241e539f65bf5aa3bb8823fff-1200x628.png" length="0" type="image/png"/>
    <pubDate>Thu, 06 Feb 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[벡터 유사도 측정 및 점수]]></title>
    <description><![CDATA[L1 &amp; L2 거리, 코사인 유사도, 도트 곱 유사도, 최대 내적 곱 유사도 등 Elasticsearch의 벡터 유사도 측정값과 점수를 살펴보세요.]]></description>
    <content:encoded><![CDATA[<p>자유 텍스트 검색이 필요하지만 Ctrl+F/Cmd+F로는 더 이상 검색이 되지 않을 때, 일반적으로 어휘 검색 엔진을 사용하는 것이 논리적으로 가장 좋은 선택입니다. 어휘 검색 엔진은 검색할 텍스트를 분석하고 검색 시 일치하는 용어로 토큰화하는 데는 탁월하지만, 색인 및 검색되는 텍스트의 진정한 의미를 이해하고 파악하는 데는 일반적으로 부족합니다.</p><p>바로 이 부분에서 벡터 검색 엔진이 빛을 발합니다. 동일한 텍스트를 색인화하여 그 텍스트가 나타내는 의미와 유사하거나 연관된 의미를 가진 다른 개념과의 관계를 기반으로 검색할 수 있습니다.</p><p>이 블로그에서는 벡터가 텍스트의 의미를 전달하는 데 얼마나 훌륭한 수학적 개념인지에 대해 간략하게 살펴보겠습니다. 그런 다음 이웃 벡터 검색, 즉 유사한 의미를 갖는 벡터를 검색할 때 Elasticsearch에서 지원하는 다양한 유사도 기술과 점수를 매기는 방법에 대해 자세히 알아보겠습니다.</p><h2>벡터 임베딩이란 무엇인가요?</h2><p>이 글에서는 벡터 임베딩의 복잡성에 대해 자세히 다루지 않습니다. 이 주제를 더 자세히 살펴보고 싶거나 계속하기 전에 입문서가 필요한 경우 <a href="https://www.elastic.co/kr/what-is/vector-embedding">다음 가이드를</a> 확인하는 것이 좋습니다.</p><p>간단히 말해, 벡터 임베딩은 머신 러닝 프로세스를 통해 얻어집니다(예 딥러닝 신경망)을 사용하여 모든 종류의 비정형 입력 데이터(예: 원시 텍스트, 이미지, 동영상, 사운드 등)를 그 의미와 관계를 전달하는 수치 데이터로 변환합니다. "비정형 데이터의 종류에 따라 각 유형의 데이터를" 이해하도록 학습된 다양한 종류의 머신 러닝 모델이 필요합니다.</p><p>각 벡터는 다차원 공간에서 특정 데이터의 위치를 점으로 표시하며, 해당 위치는 모델이 데이터를 특성화하는 데 사용하는 특징 집합을 나타냅니다. 차원 수는 머신 러닝 모델에 따라 다르지만 일반적으로 수백 개에서 수천 개까지 다양합니다. 예를 들어 <a href="https://platform.openai.com/docs/guides/embeddings">OpenAI 임베딩 모델은</a> 1536개의 치수를 자랑하는 반면, <a href="https://docs.cohere.com/reference/embed">Cohere 임베딩 모델은</a> 382개에서 4096개의 치수를 지원합니다. 최신 릴리즈부터 Elasticsearch dense_vector 필드 유형은 최대 4096개의 차원을 지원합니다.</p><p>벡터 임베딩의 진정한 장점은 비슷한 의미를 공유하는 데이터 포인트가 공간에서 서로 가깝게 배치된다는 것입니다. 또 다른 흥미로운 측면은 벡터 임베딩이 데이터 요소 간의 관계를 포착하는 데 도움이 된다는 점입니다.</p><h2>벡터는 어떻게 비교하나요?</h2><p>비정형 데이터가 머신러닝 모델에 의해 여러 차원에 걸쳐 데이터의 유사성을 포착하는 벡터 임베딩으로 잘게 쪼개진다는 것을 알았으니, 이제 이러한 벡터의 매칭이 어떻게 작동하는지 이해해야 합니다. 그 답은 매우 간단합니다.</p><p>서로 <strong>가까운</strong> 벡터 임베딩은 <strong>의미적으로 유사한</strong> 데이터 조각을 나타냅니다. 따라서 벡터 데이터베이스를 쿼리할 때 먼저 모든 비정형 데이터 색인에 사용된 것과 동일한 머신 러닝 모델을 사용하여 검색 입력(이미지, 텍스트 등)을 벡터 임베딩으로 변환하고, 최종 목표는 해당 쿼리 벡터에 <strong>가장 가까운 이웃 벡터를</strong> 찾는 것입니다. 따라서 쿼리 벡터와 데이터베이스에 색인된 모든 기존 벡터 사이의 "거리" 또는 "유사성" 을 측정하는 방법만 알아내면 됩니다.</p><h2>거리, 유사도 및 점수</h2><p>다행히도 두 벡터 사이의 거리 또는 유사성을 측정하는 것은 벡터 산술 덕분에 쉽게 해결할 수 있는 문제입니다. 이제 Elasticsearch에서 지원하는 가장 인기 있는 거리 및 유사도 함수에 대해 살펴보겠습니다. 경고, 수학이 앞서갑니다!</p><p>자세히 알아보기 전에 득점에 대해 간단히 살펴보겠습니다. 실제로 Lucene은 양수 점수만 허용합니다. 곧 소개할 모든 거리 및 유사도 함수는 두 벡터가 얼마나 가깝거나 유사한지를 측정할 수 있지만, 이러한 원시 수치는 음수가 될 수 있으므로 점수로 사용하기에는 적합하지 않습니다. 따라서 최종 점수는 거리 또는 유사도 값에서 양수가 되고 점수가 클수록 더 높은 순위(즉, 더 가까운 벡터)에 해당하는 방식으로 도출되어야 합니다.</p><h3>L1 거리</h3><p>맨해튼 거리라고도 하는 두 벡터  및  의 L1 거리는 모든 요소의 쌍별 절대 차이를 합산하여 측정합니다. , 거리가 작을수록 두 벡터는 더 가까워집니다. L1 거리 공식(1)은 아래에서 볼 수 있듯이 매우 간단합니다:</p><p>시각적으로 L1 거리는 아래 이미지(빨간색)와 같이 표시할 수 있습니다:</p><p>다음 두 벡터   산출됩니다.</p><p><strong>중요:</strong> L1 거리 함수는 <a href="https://www.elastic.co/kr/guide/en/elasticsearch/reference/current/query-dsl-script-score-query.html#vector-functions-l1"></a> <code>script_score</code> DSL 쿼리를 <a href="https://www.elastic.co/kr/guide/en/elasticsearch/reference/8.11/dense-vector.html#dense-vector-params">사용한 정확한 벡터 검색</a> (일명 무차별 검색)에만 지원되며 <a href="https://www.elastic.co/kr/guide/en/elasticsearch/reference/8.11/knn-search.html#approximate-knn"><code>knn</code></a><a href="https://www.elastic.co/kr/guide/en/elasticsearch/reference/8.11/knn-search.html#approximate-knn"> </a> 검색 <a href="https://www.elastic.co/kr/guide/en/elasticsearch/reference/current/query-dsl-knn-query.html"><code>knn</code></a><a href="https://www.elastic.co/kr/guide/en/elasticsearch/reference/current/query-dsl-knn-query.html"> 옵션 또는 DSL 쿼리를 사용한 대략적인 kNN 검색에는 지원되지</a> 않는다는 점에 유의할 필요가 있습니다.</p><h3>L2 거리</h3><p>유클리드 거리라고도 하는 두 벡터  및  의 L2 거리는 먼저 모든 요소의 쌍별 차이의 제곱을 합한 다음 그 결과의 제곱근을 구하여 측정합니다. 기본적으로 두 지점 사이의 최단 경로입니다. L1과 마찬가지로 , 의 거리가 작을수록 두 벡터는 더 가까워집니다:</p><p>아래 이미지에서 L2 거리는 빨간색으로 표시되어 있습니다:</p><p> 거리에 사용한 것과 동일한 두 개의 샘플 벡터  및  을 재사용하면 이제  거리를  수 있습니다.</p><p>점수는 두 벡터 사이의 거리가 작을수록 더 가까울수록(즉, 더 유사할수록) 점수가 높습니다. 따라서 점수를 도출하려면 거리 측정값을 반전시켜 가장 작은 거리가 가장 높은 점수를 얻도록 해야 합니다. L2 거리를 사용할 때 점수가 계산되는 방식은 아래 공식 (3)과 같습니다:</p><p>이전 예제의 샘플 벡터를 다시 사용하면, 그 점수는  됩니다. 서로 매우 가까운 두 벡터의 점수는 1에 가까워지고, 서로 매우 먼 두 벡터의 점수는 0에 가까워지는 경향이 있습니다.</p><p>L1과 L2 거리 함수에 대해 마무리하면서, 이를 비교하기 위한 좋은 비유는 뉴욕 맨해튼에 있는 두 개의 건물 A와 B를 생각하면 됩니다. A에서 B로 가는 택시는 L1 경로(거리와 도로)를 따라 주행해야 하지만, 새는 L2 경로(직선)를 이용할 수 있습니다.</p><h3>코사인 유사도</h3><p>L1 및 L2와 달리 코사인 유사도는 두 벡터  와  사이의 거리를 측정하는 것이 아니라 상대 각도, 즉 둘이 거의 같은 방향을 가리키고 있는지 여부를 측정합니다. 유사도  가 높을수록 두 벡터 사이의 각도  작아지므로 "가까울수록" 더 가깝고 "비슷할수록" 전달되는 의미가 더 커집니다.</p><p>이를 설명하기 위해 야생에서 서로 다른 방향을 바라보고 있는 두 사람을 생각해 보겠습니다. 아래 그림에서 파란색의 사람은 벡터  로 표시된 방향을, 빨간색의 사람은 벡터  의 방향을 바라보고 있습니다. 시선이 같은 방향을 향할수록(즉, 벡터가 가까워질수록) 파란색과 빨간색 영역으로 상징되는 시야가 더 많이 겹칩니다. 시야가 얼마나 겹치는지를 코사인 유사도라고 합니다. 그러나 사람 B는 사람 A보다 더 멀리 보입니다(즉, 벡터  이 더 깁니다). 사람 B는 수평선 너머 멀리 있는 산을 바라보고 있을 수 있고, 사람 A는 가까운 나무를 바라보고 있을 수 있습니다. 코사인 유사도의 경우 각도에 관한 것이므로 아무런 역할을 하지 않습니다.</p><p>이제 코사인 유사도를 계산해 보겠습니다. 공식 (4)는 매우 간단한데, 분자는 두 벡터의 점 곱으로 구성되고 분모에는 크기(즉, 길이)의 곱이 포함됩니다:</p><p> 와  사이의 코사인 유사도는 아래 이미지에 두 값 사이의 각도(빨간색)를 측정한 값으로 표시되어 있습니다:</p><p>이 코사인 유사도 값이 구체적으로 무엇을 의미하는지 설명하기 위해 잠시 우회해 보겠습니다. 코사인 함수를 묘사한 아래 이미지에서 볼 수 있듯이 값은 항상  간격으로 진동합니다.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc0e4eb98ebb64cf3/6a17da287b54f983818b3783/e31145284b8c27d0bd9e3d2831f811388134fd83-1188x272.png" alt="코스 함수" /><p>두 벡터가 유사하다고 간주되려면 각도가 가능한 한 예각이어야 하며, 이상적으로는  각도에 가까워야 하며, 이는  완벽한 유사성으로 요약됩니다. 즉, 벡터가...</p><ol><li><p>...서로<strong>가까워지면</strong> 각도의 코사인이  가까워집니다(즉,  가까워짐).</p></li></ol><ol><li><p>..<strong>.관련이 없는</strong> 경우 각도의 코사인이  가까워집니다(즉,  가까워짐).</p></li></ol><ol><li><p>..<strong>.반대로</strong>, 각도의 코사인은  가까워집니다(즉,  가까워집니다).</p></li></ol><p>이제 두 벡터 간의 코사인 유사도를 계산하는 방법을 알았고 결과 값을 해석하는 방법을 알았으므로, 동일한 샘플 벡터  와  을 재사용하고 앞에서 본 공식 (4)를 사용하여 코사인 유사도를 계산할 수 있습니다.</p><p>  가까운  코사인 유사도를 얻었는데, 이는 두 벡터가 어느 <strong>정도 유사하다는</strong> 의미, 즉 완벽하게 유사하지는 않지만 완전히 무관한 것도 아니며 반대되는 의미도 아니라는 것을 의미합니다.</p><p>코사인 유사도 값에서 양수 점수를 도출하려면 다음 공식(5)을 사용하여  구간 내에서 진동하는 코사인 유사도 값을  구간의 점수로 변환해야 합니다:</p><p>따라서 샘플 벡터  및  의 점수는 다음과 같습니다: \ .</p><h3>도트 제품 유사성</h3><p>코사인 유사도의 한 가지 단점은 두 벡터 사이의 각도만 고려하고 크기는 고려하지 않는다는 것입니다. 즉, 두 벡터가 대략 같은 방향을 가리키지만 한 벡터가 다른 벡터보다 훨씬 길면 둘 다 비슷한 것으로 간주됩니다. 스칼라 또는 내적 곱 유사도라고도 하는 도트 곱 유사도는 벡터의 각도와 크기를 모두 고려하여 보다 정확한 유사도 메트릭을 제공함으로써 이를 개선합니다. 벡터의 크기를 무관하게 만들기 위해 도트 곱 유사성은 벡터를 먼저 정규화해야 하므로 궁극적으로 단위 길이 1의 벡터만 비교하게 됩니다.</p><p>이전과 동일한 두 사람으로 다시 설명해 보겠습니다. 이번에는 두 사람의 시야 범위(즉, 방의 반경)가 정확히 같도록 원형 방 한가운데에 두 사람을 배치해 보겠습니다. 코사인 유사도와 마찬가지로, 같은 방향을 향해 더 많이 돌수록(즉, 벡터가 가까워질수록) 시야가 더 많이 겹칩니다. 그러나 코사인 유사성과는 반대로 두 벡터의 길이가 같고 두 영역의 표면이 같기 때문에 두 사람이 같은 거리에 위치한 똑같은 그림을 보고 있다는 뜻입니다. 이 두 영역이 얼마나 잘 겹치는지는 도트 제품의 유사성을 나타냅니다.</p><p>도트 곱 유사도 공식을 소개하기 전에 벡터를 어떻게 정규화할 수 있는지 간단히 살펴보겠습니다. 매우 간단하며 두 가지 간단한 단계로 완료할 수 있습니다:</p><ol><li><p>벡터의 크기를 계산합니다.</p></li><li><p>각 구성 요소를 1에서 얻은 크기로 나눕니다.</p></li></ol><p>벡터  앞서 코사인 유사성을 검토할 때 보았던 것처럼 그 크기  를 계산할 수 있습니다(즉, ). 그런 다음 벡터의 각 구성 요소를 그 크기로 나누면 다음과 같은 정규화된 벡터  를 구할 수 있습니다:</p><p>두 번째 벡터   가 생성됩니다:</p><p>도트 곱 유사도 공식을 도출하기 위해 아래와 같이 공식 (4)를 사용하여 정규화된 벡터  와  간의 코사인 유사도를 계산할 수 있습니다:</p><p>이제 두 정규화된 벡터의 크기가 모두 , 도트 곱 유사도 공식(6)은 간단히 두 정규화된 벡터의 도트 곱이 됩니다:</p><p>아래 이미지에서 정규화된 벡터  와  을 보면 한 벡터를 다른 벡터에 투영한 도트 곱의 유사성을 빨간색으로 표시할 수 있습니다.</p><p>새로운 공식 (6)을 사용하면 정규화된 두 벡터의 도트 곱 유사도를 계산할 수 있으며, 당연히 코사인과 정확히 동일한 유사도 값을 산출할 수 있습니다:</p><p>도트 곱 유사성을 활용할 때 벡터에 플로트 값이 포함되어 있는지 바이트 값이 포함되어 있는지에 따라 점수가 다르게 계산됩니다. 전자의 경우 아래 공식 (7)을 사용하여 코사인 유사도와 동일한 방식으로 점수를 계산합니다:</p><p>그러나 벡터가 바이트 값으로 구성된 경우에는 아래 공식 (8)과 같이 점수가 약간 다르게 계산되며, 여기서  벡터의 차원 수입니다:</p><p>또한 정확한 점수를 산출하기 위한 한 가지 제약 조건은 쿼리 벡터를 포함한 모든 벡터의 길이가 같아야 하지만 반드시 1은 아니어야 한다는 것입니다.</p><h3>내부 제품 유사성 극대화</h3><p>릴리스 8.11부터 벡터를 정규화할 필요가 없다는 점에서 도트 곱 유사도보다 제약이 덜한 새로운 유사도 함수가 추가되었습니다. 그 주된 이유는 <a href="https://www.elastic.co/kr/search-labs/blog/lucene-bringing-maximum-inner-product-to-lucene">다음 글</a>에서 자세히 설명하지만, 간단히 요약하자면 특정 데이터 세트는 벡터를 정규화하는 데 적합하지 않으며(예: <a href="https://www.elastic.co/kr/search-labs/blog/elasticsearch-cohere-embeddings-support">Cohere 임베딩</a>), 그렇게 하면 연관성 문제가 발생할 수 있습니다.</p><p>최대 내적 곱 유사도를 계산하는 공식은 점 곱 1(6)과 정확히 동일합니다. 아래 공식 (9)와 같이 유사성이 양수인지 음수인지에 따라 수식이 달라지는 조각별 함수를 사용하여 최대 내적 곱 유사성을 스케일링하여 점수를 계산하는 방식이 변경됩니다:</p><p>이 조각 함수는  구간에서 음의 최대 내적 유사도 값을 모두 스케일링하고  구간에서 양의 값을 모두 스케일링하는 기능을 수행합니다.</p><h2>요약</h2><p>수학적으로 말하자면 꽤나 어려운 과정이었지만, 여기 몇 가지 유용한 팁이 있습니다.</p><p>어떤 유사도 함수를 사용할 수 있는지는 궁극적으로 벡터 임베딩의 정규화 여부에 따라 달라집니다. 벡터가 이미 정규화되어 있거나 데이터 세트가 벡터 정규화와 무관한 경우(즉, 관련성이 저하되지 않는 경우) 벡터를 정규화하고 도트 곱 유사성을 사용하면 각 벡터의 길이를 계산할 필요가 없으므로 코사인보다 훨씬 빠르게 계산할 수 있습니다. 수백만 개의 벡터를 비교할 때 이러한 계산은 상당히 많이 합산될 수 있습니다.</p><p>벡터가 정규화되지 않은 경우 두 가지 옵션이 있습니다:</p><ol><li><p>벡터를 정규화할 수 없는 경우 코사인 유사도를 사용합니다.</p></li><li><p>벡터의 크기가 의미를 지니고 있어 점수에 기여하도록 하려면 새로운 최대 내적 곱 유사성을 사용합니다(예: Cohere 임베딩).</p></li></ol><p>이 시점에서 벡터 임베딩 간의 거리 또는 유사성을 계산하고 점수를 도출하는 방법을 이해하면 이해가 쉬울 것입니다. 이 글이 도움이 되었기를 바랍니다.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/vector-similarity-measures-and-scoring</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/vector-similarity-measures-and-scoring</guid>
    <category><![CDATA[벡터 데이터베이스]]></category>
    <dc:creator><![CDATA[Valentin Crettaz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte5a3e9d39849d3ed/6a17da31a2929960a3d02b3f/4d9e89678798b9de68357b5cc06dbbd8b9c6e5e8-1440x823.webp" length="0" type="image/webp"/>
    <pubDate>Mon, 13 May 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>