🚀 Coba Zilliz Cloud, Milvus yang sepenuhnya terkelola, secara gratis—rasakan performa 10x lebih cepat! Coba Sekarang>>

milvus-logo
LFAI
Beranda
  • Panduan Pengguna
  • Home
  • Docs
  • Panduan Pengguna

  • Bidang Skema & Data

  • Vektor Jarang

Vektor Jarang

Vektor jarang adalah metode representasi data yang penting dalam pencarian informasi dan pemrosesan bahasa alami. Meskipun vektor padat populer karena kemampuan pemahaman semantiknya yang sangat baik, vektor jarang sering kali memberikan hasil yang lebih akurat dalam hal aplikasi yang memerlukan pencocokan kata kunci atau frasa yang tepat.

Gambaran Umum

Vektor jarang adalah representasi khusus dari vektor dimensi tinggi di mana sebagian besar elemen bernilai nol, dan hanya beberapa dimensi yang memiliki nilai bukan nol. Karakteristik ini membuat vektor jarang sangat efektif dalam menangani data berskala besar, berdimensi tinggi, tetapi jarang. Aplikasi yang umum meliputi.

  • Analisis Teks: Merepresentasikan dokumen sebagai vektor kantong kata, di mana setiap dimensi berhubungan dengan sebuah kata, dan hanya kata-kata yang muncul dalam dokumen yang memiliki nilai bukan nol.

  • Sistem Rekomendasi: Matriks interaksi pengguna dan item, di mana setiap dimensi mewakili peringkat pengguna untuk item tertentu, dengan sebagian besar pengguna hanya berinteraksi dengan beberapa item.

  • Pemrosesan Gambar: Representasi fitur lokal, yang hanya berfokus pada titik-titik penting dalam gambar, menghasilkan vektor jarang berdimensi tinggi.

Seperti yang ditunjukkan pada diagram di bawah ini, vektor padat biasanya direpresentasikan sebagai larik kontinu di mana setiap posisi memiliki nilai (misalnya, [0.3, 0.8, 0.2, 0.3, 0.1]). Sebaliknya, vektor jarang hanya menyimpan elemen non-nol dan indeksnya, yang sering direpresentasikan sebagai pasangan kunci-nilai (misalnya, [{2: 0.2}, ..., {9997: 0.5}, {9999: 0.7}]). Representasi ini secara signifikan mengurangi ruang penyimpanan dan meningkatkan efisiensi komputasi, terutama ketika berurusan dengan data berdimensi sangat tinggi (misalnya, 10.000 dimensi).

Spare vector representation Representasi vektor jarang

Vektor jarang dapat dihasilkan dengan menggunakan berbagai metode, seperti TF-IDF (Term Frequency-Inverse Document Frequency) dan BM25 dalam pemrosesan teks. Selain itu, Milvus menawarkan metode yang mudah digunakan untuk membantu menghasilkan dan memproses vektor jarang. Untuk detailnya, lihat Penyematan.

Untuk data teks, Milvus juga menyediakan kemampuan pencarian teks lengkap, sehingga Anda dapat melakukan pencarian vektor secara langsung pada data teks mentah tanpa menggunakan model penyematan eksternal untuk menghasilkan vektor jarang. Untuk informasi lebih lanjut, lihat Pencarian Teks Lengkap.

Setelah vektorisasi, data dapat disimpan di Milvus untuk pengelolaan dan pengambilan vektor. Diagram di bawah ini mengilustrasikan proses dasarnya.

Use sparse vector in Milvus Menggunakan vektor jarang di Milvus

Selain vektor jarang, Milvus juga mendukung vektor padat dan vektor biner. Vektor padat ideal untuk menangkap hubungan semantik yang dalam, sementara vektor biner unggul dalam skenario seperti perbandingan kemiripan cepat dan deduplikasi konten. Untuk informasi lebih lanjut, lihat Vektor Padat dan Vektor Biner.

Menggunakan vektor jarang di Milvus

Milvus mendukung representasi vektor jarang dalam salah satu format berikut.

  • Matriks jarang (menggunakan kelas scipy.sparse )

    from scipy.sparse import csr_matrix
    
    # Create a sparse matrix
    row = [0, 0, 1, 2, 2, 2]
    col = [0, 2, 2, 0, 1, 2]
    data = [1, 2, 3, 4, 5, 6]
    sparse_matrix = csr_matrix((data, (row, col)), shape=(3, 3))
    
    # Represent sparse vector using the sparse matrix
    sparse_vector = sparse_matrix.getrow(0)
    
    
  • Daftar Kamus (diformat sebagai {dimension_index: value, ...})

    # Represent sparse vector using a dictionary
    sparse_vector = [{1: 0.5, 100: 0.3, 500: 0.8, 1024: 0.2, 5000: 0.6}]
    
    
    SortedMap<Long, Float> sparseVector = new TreeMap<>();
    sparseVector.put(1L, 0.5f);
    sparseVector.put(100L, 0.3f);
    sparseVector.put(500L, 0.8f);
    sparseVector.put(1024L, 0.2f);
    sparseVector.put(5000L, 0.6f);
    
    
  • Daftar Iterator Tuple (diformat sebagai [(dimension_index, value)])

    # Represent sparse vector using a list of tuples
    sparse_vector = [[(1, 0.5), (100, 0.3), (500, 0.8), (1024, 0.2), (5000, 0.6)]]
    
    

Menambahkan bidang vektor

Untuk menggunakan vektor jarang di Milvus, tentukan sebuah bidang untuk menyimpan vektor jarang saat membuat koleksi. Proses ini meliputi.

  1. Mengatur datatype ke tipe data vektor jarang yang didukung, SPARSE_FLOAT_VECTOR.

  2. Tidak perlu menentukan dimensi.

from pymilvus import MilvusClient, DataType

client = MilvusClient(uri="http://localhost:19530")

client.drop_collection(collection_name="my_sparse_collection")

schema = client.create_schema(
    auto_id=True,
    enable_dynamic_fields=True,
)

schema.add_field(field_name="pk", datatype=DataType.VARCHAR, is_primary=True, max_length=100)
schema.add_field(field_name="sparse_vector", datatype=DataType.SPARSE_FLOAT_VECTOR)

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;

import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .build());
        
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.setEnableDynamicField(true);
schema.addField(AddFieldReq.builder()
        .fieldName("pk")
        .dataType(DataType.VarChar)
        .isPrimaryKey(true)
        .autoID(true)
        .maxLength(100)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("sparse_vector")
        .dataType(DataType.SparseFloatVector)
        .build());

import { DataType } from "@zilliz/milvus2-sdk-node";

const schema = [
  {
    name: "metadata",
    data_type: DataType.JSON,
  },
  {
    name: "pk",
    data_type: DataType.Int64,
    is_primary_key: true,
  },
  {
    name: "sparse_vector",
    data_type: DataType.SparseFloatVector,
  }
];


export primaryField='{
    "fieldName": "pk",
    "dataType": "VarChar",
    "isPrimary": true,
    "elementTypeParams": {
        "max_length": 100
    }
}'

export vectorField='{
    "fieldName": "sparse_vector",
    "dataType": "SparseFloatVector"
}'

export schema="{
    \"autoID\": true,
    \"fields\": [
        $primaryField,
        $vectorField
    ]
}"

Pada contoh ini, bidang vektor bernama sparse_vector ditambahkan untuk menyimpan vektor jarang. Tipe data dari field ini adalah SPARSE_FLOAT_VECTOR.

Mengatur parameter indeks untuk bidang vektor

Proses pembuatan indeks untuk vektor jarang mirip dengan proses pembuatan indeks untuk vektor padat, tetapi dengan perbedaan pada tipe indeks yang ditentukan (index_type), metrik jarak (metric_type), dan parameter indeks (params).

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="sparse_vector",
    index_name="sparse_inverted_index",
    index_type="SPARSE_INVERTED_INDEX",
    metric_type="IP",
    params={"inverted_index_algo": "DAAT_MAXSCORE"},
)

import io.milvus.v2.common.IndexParam;
import java.util.*;

List<IndexParam> indexes = new ArrayList<>();
Map<String,Object> extraParams = new HashMap<>();
extraParams.put("inverted_index_algo": "DAAT_MAXSCORE");
indexes.add(IndexParam.builder()
        .fieldName("sparse_vector")
        .indexName("sparse_inverted_index")
        .indexType(IndexParam.IndexType.SPARSE_INVERTED_INDEX)
        .metricType(IndexParam.MetricType.IP)
        .extraParams(extraParams)
        .build());

const indexParams = await client.createIndex({
    index_name: 'sparse_inverted_index',
    field_name: 'sparse_vector',
    metric_type: MetricType.IP,
    index_type: IndexType.SPARSE_INVERTED_INDEX,
    params: {
      inverted_index_algo: 'DAAT_MAXSCORE',
    },
});

export indexParams='[
        {
            "fieldName": "sparse_vector",
            "metricType": "IP",
            "indexName": "sparse_inverted_index",
            "indexType": "SPARSE_INVERTED_INDEX",
            "params":{"inverted_index_algo": "DAAT_MAXSCORE"}
        }
    ]'

Dalam contoh di atas:

  • index_type: Jenis indeks yang akan dibuat untuk bidang vektor jarang. Nilai yang valid:

    • SPARSE_INVERTED_INDEX: Indeks terbalik tujuan umum untuk vektor jarang.

    Mulai Milvus 2.5.4 dan seterusnya, SPARSE_WAND sudah tidak digunakan lagi. Sebagai gantinya, disarankan untuk menggunakan "inverted_index_algo": "DAAT_WAND" untuk kesetaraan dengan tetap menjaga kompatibilitas.

  • metric_type: Metrik yang digunakan untuk menghitung kemiripan antara vektor jarang. Nilai yang valid:

    • IP (Inner Product): Mengukur kemiripan dengan menggunakan dot product.

    • BM25: Biasanya digunakan untuk pencarian teks lengkap, dengan fokus pada kemiripan tekstual.

      Untuk detail lebih lanjut, lihat Jenis Metrik dan Pencarian Teks Lengkap.

  • params.inverted_index_algo: Algoritme yang digunakan untuk membangun dan menanyakan indeks. Nilai yang valid:

    • "DAAT_MAXSCORE" (default): Pemrosesan kueri Dokumen per Dokumen (DAAT) yang dioptimalkan menggunakan algoritme MaxScore. MaxScore memberikan kinerja yang lebih baik untuk nilai k yang tinggi atau kueri dengan banyak istilah dengan melewatkan istilah dan dokumen yang kemungkinan besar memiliki dampak minimal. Hal ini dicapai dengan mempartisi istilah ke dalam kelompok penting dan tidak penting berdasarkan nilai dampak maksimumnya, dengan fokus pada istilah yang dapat berkontribusi pada hasil k teratas.

    • "DAAT_WAND": Pemrosesan kueri DAAT yang dioptimalkan menggunakan algoritme WAND. WAND mengevaluasi lebih sedikit dokumen yang terkena dampak dengan memanfaatkan nilai dampak maksimum untuk melewatkan dokumen yang tidak kompetitif, tetapi memiliki overhead per hit yang lebih tinggi. Hal ini membuat WAND lebih efisien untuk kueri dengan nilai k kecil atau kueri pendek, di mana melewatkan lebih memungkinkan.

    • "TAAT_NAIVE": Pemrosesan kueri dasar Term-at-a-Time (TAAT). Meskipun lebih lambat dibandingkan dengan DAAT_MAXSCORE dan DAAT_WAND, TAAT_NAIVE menawarkan keuntungan yang unik. Tidak seperti algoritme DAAT, yang menggunakan skor dampak maksimum yang di-cache yang tetap statis terlepas dari perubahan pada parameter koleksi global (avgdl), TAAT_NAIVE secara dinamis beradaptasi dengan perubahan tersebut.

Membuat koleksi

Setelah pengaturan vektor jarang dan indeks selesai, Anda dapat membuat koleksi yang berisi vektor jarang. Contoh di bawah ini menggunakan metode create_collection untuk membuat koleksi bernama my_sparse_collection.

client.create_collection(
    collection_name="my_sparse_collection",
    schema=schema,
    index_params=index_params
)

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .build());
        
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
        .collectionName("my_sparse_collection")
        .collectionSchema(schema)
        .indexParams(indexes)
        .build();
client.createCollection(requestCreate);

import { MilvusClient } from "@zilliz/milvus2-sdk-node";

const client = new MilvusClient({
    address: 'http://localhost:19530'
});

await client.createCollection({
    collection_name: 'my_sparse_collection',
    schema: schema,
    index_params: indexParams
});

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
    \"collectionName\": \"my_sparse_collection\",
    \"schema\": $schema,
    \"indexParams\": $indexParams
}"

Menyisipkan data

Setelah membuat koleksi, masukkan data yang berisi vektor jarang.

sparse_vectors = [
    {"sparse_vector": {1: 0.5, 100: 0.3, 500: 0.8}},
    {"sparse_vector": {10: 0.1, 200: 0.7, 1000: 0.9}},
]

client.insert(
    collection_name="my_sparse_collection",
    data=sparse_vectors
)

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp;

List<JsonObject> rows = new ArrayList<>();
Gson gson = new Gson();
{
    JsonObject row = new JsonObject();
    SortedMap<Long, Float> sparse = new TreeMap<>();
    sparse.put(1L, 0.5f);
    sparse.put(100L, 0.3f);
    sparse.put(500L, 0.8f);
    row.add("sparse_vector", gson.toJsonTree(sparse));
    rows.add(row);
}
{
    JsonObject row = new JsonObject();
    SortedMap<Long, Float> sparse = new TreeMap<>();
    sparse.put(10L, 0.1f);
    sparse.put(200L, 0.7f);
    sparse.put(1000L, 0.9f);
    row.add("sparse_vector", gson.toJsonTree(sparse));
    rows.add(row);
}

InsertResp insertR = client.insert(InsertReq.builder()
        .collectionName("my_sparse_collection")
        .data(rows)
        .build());

const data = [
  { sparse_vector: { "1": 0.5, "100": 0.3, "500": 0.8 } },
  { sparse_vector: { "10": 0.1, "200": 0.7, "1000": 0.9 } },
];
client.insert({
  collection_name: "my_sparse_collection",
  data: data,
});


curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "data": [
        {"sparse_vector": {"1": 0.5, "100": 0.3, "500": 0.8}},
        {"sparse_vector": {"10": 0.1, "200": 0.7, "1000": 0.9}}        
    ],
    "collectionName": "my_sparse_collection"
}'

## {"code":0,"cost":0,"data":{"insertCount":2,"insertIds":["453577185629572534","453577185629572535"]}}

Untuk melakukan pencarian kemiripan menggunakan vektor jarang, siapkan vektor kueri dan parameter pencarian.

# Prepare search parameters
search_params = {
    "params": {"drop_ratio_search": 0.2},  # Additional optional search parameters
}

# Prepare the query vector
query_vector = [{1: 0.2, 50: 0.4, 1000: 0.7}]

Dalam contoh ini, drop_ratio_search adalah parameter opsional khusus untuk vektor jarang, yang memungkinkan penyesuaian nilai kecil dalam vektor kueri selama pencarian. Misalnya, dengan {"drop_ratio_search": 0.2}, 20% nilai terkecil dalam vektor kueri akan diabaikan selama pencarian.

Kemudian, jalankan pencarian kemiripan menggunakan metode search.

res = client.search(
    collection_name="my_sparse_collection",
    data=query_vector,
    limit=3,
    output_fields=["pk"],
    search_params=search_params,
)

print(res)

# Output
# data: ["[{'id': '453718927992172266', 'distance': 0.6299999952316284, 'entity': {'pk': '453718927992172266'}}, {'id': '453718927992172265', 'distance': 0.10000000149011612, 'entity': {'pk': '453718927992172265'}}]"]

import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.SparseFloatVec;
import io.milvus.v2.service.vector.response.SearchResp;

Map<String,Object> searchParams = new HashMap<>();
searchParams.put("drop_ratio_search", 0.2);

SortedMap<Long, Float> sparse = new TreeMap<>();
sparse.put(10L, 0.1f);
sparse.put(200L, 0.7f);
sparse.put(1000L, 0.9f);

SparseFloatVec queryVector = new SparseFloatVec(sparse);

SearchResp searchR = client.search(SearchReq.builder()
        .collectionName("my_sparse_collection")
        .data(Collections.singletonList(queryVector))
        .annsField("sparse_vector")
        .searchParams(searchParams)
        .topK(3)
        .outputFields(Collections.singletonList("pk"))
        .build());
        
System.out.println(searchR.getSearchResults());

// Output
//
// [[SearchResp.SearchResult(entity={pk=453444327741536759}, score=1.31, id=453444327741536759), SearchResp.SearchResult(entity={pk=453444327741536756}, score=1.31, id=453444327741536756), SearchResp.SearchResult(entity={pk=453444327741536753}, score=1.31, id=453444327741536753)]]

client.search({
    collection_name: 'my_sparse_collection',
    data: {1: 0.2, 50: 0.4, 1000: 0.7},
    limit: 3,
    output_fields: ['pk'],
    params: {
        drop_ratio_search: 0.2
    }
});

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "my_sparse_collection",
    "data": [
        {"1": 0.2, "50": 0.4, "1000": 0.7}
    ],
    "annsField": "sparse_vector",
    "limit": 3,
    "searchParams":{
        "params":{"drop_ratio_search": 0.2}
    },
    "outputFields": ["pk"]
}'

## {"code":0,"cost":0,"data":[{"distance":0.63,"id":"453577185629572535","pk":"453577185629572535"},{"distance":0.1,"id":"453577185629572534","pk":"453577185629572534"}]}

Untuk informasi lebih lanjut tentang parameter pencarian kemiripan, lihat Pencarian ANN Dasar.

Batasan

Ketika menggunakan vektor jarang di Milvus, pertimbangkan batasan-batasan berikut:

  • Saat ini, hanya metrik jarak IP dan BM25 (untuk pencarian teks lengkap) yang didukung untuk vektor jarang. Dimensi vektor jarang yang tinggi membuat L2 dan jarak kosinus tidak praktis.

  • Untuk bidang vektor jarang, hanya tipe indeks SPARSE_INVERTED_INDEX yang didukung.

  • Tipe data yang didukung untuk vektor jarang:

    • Bagian dimensi harus berupa bilangan bulat 32-bit yang tidak ditandatangani;
    • Bagian nilai dapat berupa angka floating-point 32-bit non-negatif.
  • Vektor jarang harus memenuhi persyaratan berikut untuk penyisipan dan pencarian:

    • Setidaknya satu nilai dalam vektor bukan nol;
    • Indeks vektor tidak bernilai negatif.

PERTANYAAN UMUM

  • Dapatkah dimensi penyisipan jarang berupa nilai diskrit dalam ruang uint32?

    Ya, dengan satu pengecualian. Dimensi sematan jarang dapat berupa nilai apa pun dalam kisaran [0, maximum of uint32). Ini berarti Anda tidak dapat menggunakan nilai maksimum uint32.

  • Apakah pencarian pada ruas yang sedang tumbuh dilakukan melalui indeks atau dengan brute force?

    Pencarian pada segmen yang sedang tumbuh dilakukan melalui indeks dengan tipe yang sama dengan indeks segmen yang disegel. Untuk segmen baru yang sedang tumbuh sebelum indeks dibangun, pencarian brute force digunakan.

  • Apakah mungkin untuk memiliki vektor yang jarang dan padat dalam satu koleksi?

    Ya, dengan dukungan beberapa jenis vektor, Anda dapat membuat koleksi dengan kolom vektor jarang dan padat dan melakukan pencarian hibrida di dalamnya.

Coba Milvus yang Dikelola secara Gratis

Zilliz Cloud bebas masalah, didukung oleh Milvus dan 10x lebih cepat.

Mulai
Umpan balik

Apakah halaman ini bermanfaat?