K-최근접 이웃을 찾아 Spanner에서 벡터 유사성 검색 수행

이 페이지에서는 코사인 거리, 유클리드 거리, 내적 벡터 함수를 사용하여 K-최근접 이웃을 찾아 Spanner에서 벡터 유사성 검색을 수행하는 방법을 설명합니다. 이 페이지를 읽기 전에 다음 개념을 이해해야 합니다.

  • 유클리드 거리: 두 벡터 간의 최단 거리를 측정합니다.
  • 코사인 거리: 두 벡터 간의 각도 코사인을 측정합니다.
  • 내적: 각도에 해당 벡터 크기의 곱을 곱하여 코사인을 계산합니다. 데이터 세트의 모든 벡터 임베딩이 정규화된 경우 DOT_PRODUCT()를 거리 함수로 사용할 수 있습니다.
  • K-최근접 이웃(KNN): 분류 또는 회귀 문제를 해결하는 데 사용되는 지도 머신러닝 알고리즘입니다.

유사성 검색이나 검색 증강 생성과 같은 사용 사례에 벡터 거리 함수를 사용하여 K-최근접 이웃(KNN) 벡터 검색을 수행할 수 있습니다. Spanner는 벡터 임베딩에서 작동하는 COSINE_DISTANCE(), EUCLIDEAN_DISTANCE(), DOT_PRODUCT() 함수를 지원하므로 입력 임베딩의 KNN을 찾을 수 있습니다.

예를 들어 운영 Spanner 데이터를 벡터 임베딩으로 생성 및 저장한 후 이러한 벡터 임베딩을 쿼리에서 입력 매개변수로 제공하여 N차원 공간에서 가장 가까운 벡터를 찾아 의미론적으로 유사하거나 관련된 항목을 검색할 수 있습니다.

세 거리 함수 모두 array<> 유형인 vector1vector2 인수를 사용하며 동일한 차원으로 구성되고 길이가 같아야 합니다. 이러한 함수에 대한 자세한 내용은 다음을 참조하세요.

예시

다음 예시에서는 KNN 검색, 파티셔닝된 데이터에 대한 KNN 검색, KNN과 함께 보조 색인 사용 방법을 보여줍니다.

예시에서는 모두 EUCLIDEAN_DISTANCE()를 사용합니다. COSINE_DISTANCE()도 사용할 수 있습니다. 또한 데이터 세트의 모든 벡터 임베딩이 정규화된 경우 DOT_PRODUCT()를 거리 함수로 사용할 수 있습니다.

DocContents 바이트 열에서 미리 계산된 텍스트 임베딩의 열(DocEmbedding)이 있는 Documents 테이블을 가정해보세요.

GoogleSQL

CREATE TABLE Documents (
UserId       INT64 NOT NULL,
DocId        INT64 NOT NULL,
Author       STRING(1024),
DocContents  BYTES,
DocEmbedding ARRAY<FLOAT32>
) PRIMARY KEY (UserId, DocId);

PostgreSQL

CREATE TABLE Documents (
UserId       bigint NOT NULL,
DocId        bigint NOT NULL,
Author       varchar(1024),
DocContents  bytea,
DocEmbedding float4[],
PRIMARY KEY  (UserId, DocId)
);

'프로 야구가 아닌 야구'의 입력 임베딩이 [0.3, 0.3, 0.7, 0.7] 배열이라고 가정하면 다음 쿼리를 사용하여 가장 가깝게 일치하는 상위 5개 문서를 찾을 수 있습니다.

GoogleSQL

SELECT DocId, DocEmbedding FROM Documents
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
ARRAY<FLOAT32>[0.3, 0.3, 0.7, 0.8])
LIMIT 5;

PostgreSQL

SELECT DocId, DocEmbedding FROM Documents
ORDER BY spanner.euclidean_distance(DocEmbedding,
'{0.3, 0.3, 0.7, 0.8}'::float4[])
LIMIT 5;

이 예시의 예상 결과는 다음과 같습니다.

Documents
+---------------------------+-----------------+
| DocId                     | DocEmbedding    |
+---------------------------+-----------------+
| 24                        | [8, ...]        |
+---------------------------+-----------------+
| 25                        | [6, ...]        |
+---------------------------+-----------------+
| 26                        | [3.2, ...]      |
+---------------------------+-----------------+
| 27                        | [38, ...]       |
+---------------------------+-----------------+
| 14229                     | [1.6, ...]      |
+---------------------------+-----------------+

예시 2: 파티션을 나눈 데이터에 대한 KNN 검색

벡터 검색을 데이터 하위 집합으로 제한하도록 조건을 WHERE 절에 추가하여 앞선 예시의 쿼리를 수정할 수 있습니다. 이를 위한 한 가지 일반적인 애플리케이션은 특정 UserId에 속하는 행과 같이 파티션을 나눈 데이터를 검색하는 것입니다.

GoogleSQL

SELECT UserId, DocId, DocEmbedding FROM Documents
WHERE UserId=18
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
ARRAY<FLOAT32>[0.3, 0.3, 0.7, 0.8])
LIMIT 5;

PostgreSQL

SELECT UserId, DocId, DocEmbedding FROM Documents
WHERE UserId=18
ORDER BY spanner.euclidean_distance(DocEmbedding,
'{0.3, 0.3, 0.7, 0.8}'::float4[])
LIMIT 5;

이 예시의 예상 결과는 다음과 같습니다.

Documents
+-----------+-----------------+-----------------+
| UserId    | DocId           | DocEmbedding    |
+-----------+-----------------+-----------------+
| 18        | 234             | [12, ...]       |
+-----------+-----------------+-----------------+
| 18        | 12              | [1.6, ...]      |
+-----------+-----------------+-----------------+
| 18        | 321             | [22, ...]       |
+-----------+-----------------+-----------------+
| 18        | 432             | [3, ...]        |
+-----------+-----------------+-----------------+

예시 3: 보조 색인 범위에 대한 KNN 검색

사용하는 WHERE 절 필터가 테이블의 기본 키에 포함되지 않은 경우 보조 색인을 만들어 색인 전용 스캔으로 작업을 가속화할 수 있습니다.

GoogleSQL

CREATE INDEX DocsByAuthor
ON Documents(Author)
STORING (DocEmbedding);

SELECT Author, DocId, DocEmbedding FROM Documents
WHERE Author="Mark Twain"
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
   <embeddings for "book about the time traveling American">)
LIMIT 5;

PostgreSQL

CREATE INDEX DocsByAuthor
ON Documents(Author)
INCLUDE (DocEmbedding);

SELECT Author, DocId, DocEmbedding FROM Documents
WHERE Author="Mark Twain"
ORDER BY spanner.euclidean_distance(DocEmbedding,
   <embeddings for "that book about the time traveling American">)
LIMIT 5;

이 예시의 예상 결과는 다음과 같습니다.

Documents
+------------+-----------------+-----------------+
| Author     | DocId           | DocEmbedding    |
+------------+-----------------+-----------------+
| Mark Twain | 234             | [12, ...]       |
+------------+-----------------+-----------------+
| Mark Twain | 12              | [1.6, ...]      |
+------------+-----------------+-----------------+
| Mark Twain | 321             | [22, ...]       |
+------------+-----------------+-----------------+
| Mark Twain | 432             | [3, ...]        |
+------------+-----------------+-----------------+
| Mark Twain | 375             | [9, ...]        |
+------------+-----------------+-----------------+

다음 단계