Vettore denso

I vettori densi sono rappresentazioni numeriche dei dati ampiamente utilizzate nell'apprendimento automatico e nell'analisi dei dati. Sono costituiti da array di numeri reali, in cui la maggior parte o tutti gli elementi sono diversi da zero. Rispetto ai vettori sparsi, i vettori densi contengono più informazioni a parità di dimensionalità, poiché ogni dimensione contiene valori significativi. Questa rappresentazione è in grado di cogliere efficacemente modelli e relazioni complesse, rendendo i dati più facili da analizzare ed elaborare in spazi ad alta dimensionalità. I vettori densi hanno in genere un numero fisso di dimensioni, che varia da poche decine a diverse centinaia o addirittura migliaia, a seconda dell’applicazione specifica e dei requisiti.

I vettori densi vengono utilizzati principalmente in contesti che richiedono la comprensione della semantica dei dati, come la ricerca semantica e i sistemi di raccomandazione. Nella ricerca semantica, i vettori densi aiutano a cogliere le connessioni sottostanti tra query e documenti, migliorando la pertinenza dei risultati di ricerca. Nei sistemi di raccomandazione, aiutano a identificare le somiglianze tra utenti e elementi, offrendo suggerimenti più personalizzati.

Panoramica

I vettori densi sono tipicamente rappresentati come array di numeri in virgola mobile di lunghezza fissa, come ad esempio [0.2, 0.7, 0.1, 0.8, 0.3, ..., 0.5]. La dimensionalità di questi vettori varia solitamente da centinaia a migliaia, come 128, 256, 768 o 1024. Ogni dimensione cattura caratteristiche semantiche specifiche di un oggetto, rendendolo applicabile a vari scenari attraverso calcoli di similarità.

Dense Vector Vettore denso

L’immagine sopra illustra la rappresentazione dei vettori densi in uno spazio bidimensionale. Sebbene nei casi d’uso reali i vettori densi abbiano spesso dimensioni molto più elevate, questa illustrazione bidimensionale trasmette efficacemente diversi concetti chiave:

  • Rappresentazione multidimensionale: ogni punto rappresenta un oggetto concettuale (come Milvus, un database vettoriale, un sistema di recupero, ecc.), la cui posizione è determinata dai valori delle sue dimensioni.

  • Relazioni semantiche: le distanze tra i punti riflettono la somiglianza semantica tra i concetti. I punti più vicini indicano concetti che sono più correlati dal punto di vista semantico.

  • Effetto di raggruppamento: i concetti correlati (come Milvus, database vettoriale e sistema di recupero) sono posizionati vicini tra loro nello spazio, formando un cluster semantico.

Di seguito è riportato un esempio di un vettore denso reale che rappresenta il testo « "Milvus is an efficient vector database" »:

[
    -0.013052909,
    0.020387933,
    -0.007869,
    -0.11111383,
    -0.030188112,
    -0.0053388323,
    0.0010654867,
    0.072027855,
    // ... more dimensions
]

I vettori densi possono essere generati utilizzando vari modelli di embedding, come i modelli CNN (ad esempio ResNet, VGG) per le immagini e i modelli linguistici (come BERT, Word2Vec) per il testo. Questi modelli trasformano i dati grezzi in punti in uno spazio ad alta dimensionalità, catturando le caratteristiche semantiche dei dati. Inoltre, Milvus offre metodi pratici per aiutare gli utenti a generare ed elaborare vettori densi, come descritto in dettaglio nella sezione Embedding.

Una volta vettorializzati, i dati possono essere archiviati in Milvus per la gestione e il recupero dei vettori. Il diagramma sottostante illustra il processo di base.

Use Dense Vector Utilizzo dei vettori densi

Oltre ai vettori densi, Milvus supporta anche vettori sparsi e vettori binari. I vettori sparsi sono adatti per corrispondenze precise basate su termini specifici, come la ricerca per parole chiave e la corrispondenza di termini, mentre i vettori binari sono comunemente utilizzati per gestire in modo efficiente dati binarizzati, come il riconoscimento di pattern nelle immagini e alcune applicazioni di hashing. Per ulteriori informazioni, consultare Vettori binari e Vettori sparsi.

Utilizzo dei vettori densi

Aggiungere un campo vettoriale

Per utilizzare i vettori densi in Milvus, definire innanzitutto un campo vettoriale per la memorizzazione dei vettori densi durante la creazione di una collezione. Questa procedura prevede:

  1. Impostare ` datatype ` su un tipo di dati vettoriale denso supportato. Per i tipi di dati vettoriali densi supportati, consultare Tipi di dati.

  2. Specificare le dimensioni del vettore denso utilizzando il parametro dim.

Nell’esempio riportato di seguito, aggiungiamo un campo vettoriale denominato dense_vector per memorizzare vettori densi. Il tipo di dati del campo è FLOAT_VECTOR, con una dimensione pari a 4.

from pymilvus import MilvusClient, DataType

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

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="dense_vector", datatype=DataType.FLOAT_VECTOR, dim=4)
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("dense_vector")
        .dataType(DataType.FloatVector)
        .dimension(4)
        .build());
import { DataType } from "@zilliz/milvus2-sdk-node";

schema.push({
  name: "dense_vector",
  data_type: DataType.FloatVector,
  dim: 4,
});

import (
    "context"
    "fmt"

    "github.com/milvus-io/milvus/client/v2/column"
    "github.com/milvus-io/milvus/client/v2/entity"
    "github.com/milvus-io/milvus/client/v2/index"
    "github.com/milvus-io/milvus/client/v2/milvusclient"
)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

milvusAddr := "localhost:19530"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: milvusAddr,
})
if err != nil {
    fmt.Println(err.Error())
    // handle error
}
defer client.Close(ctx)

schema := entity.NewSchema()
schema.WithField(entity.NewField().
    WithName("pk").
    WithDataType(entity.FieldTypeVarChar).
    WithIsPrimaryKey(true).
    WithIsAutoID(true).
    WithMaxLength(100),
).WithField(entity.NewField().
    WithName("dense_vector").
    WithDataType(entity.FieldTypeFloatVector).
    WithDim(4),
)
export primaryField='{
    "fieldName": "pk",
    "dataType": "VarChar",
    "isPrimary": true,
    "elementTypeParams": {
        "max_length": 100
    }
}'

export vectorField='{
    "fieldName": "dense_vector",
    "dataType": "FloatVector",
    "elementTypeParams": {
        "dim": 4
    }
}'

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

Tipi di dati supportati per i campi vettoriali densi:

Tipo di dati

Descrizione

FLOAT_VECTOR

Memorizza numeri in virgola mobile a 32 bit, comunemente utilizzati per rappresentare i numeri reali nei calcoli scientifici e nell’apprendimento automatico. Ideale per scenari che richiedono un’elevata precisione, come la distinzione di vettori simili.

FLOAT16_VECTOR

Memorizza numeri in virgola mobile a mezza precisione a 16 bit, utilizzati per il deep learning e i calcoli su GPU. Consente di risparmiare spazio di archiviazione in scenari in cui la precisione è meno critica, come nella fase di richiamo a bassa precisione dei sistemi di raccomandazione.

BFLOAT16_VECTOR

Memorizza numeri in virgola mobile Brain (bfloat16) a 16 bit, offrendo lo stesso intervallo di esponenti di Float32 ma con precisione ridotta. Adatto a scenari che richiedono l’elaborazione rapida di grandi volumi di vettori, come il recupero di immagini su larga scala.

INT8_VECTOR

Memorizza vettori i cui singoli elementi in ciascuna dimensione sono interi a 8 bit (int8), con ciascun elemento compreso tra –128 e 127. Progettato per modelli di deep learning quantizzati (ad es. ResNet, EfficientNet), INT8_VECTOR riduce le dimensioni del modello e accelera l’inferenza con una perdita minima di precisione.
Nota: questo tipo di vettore è supportato solo per gli indici HNSW.

Impostazione dei parametri dell’indice per il campo vettoriale

Per accelerare le ricerche semantiche, è necessario creare un indice per il campo vettoriale. L’indicizzazione può migliorare significativamente l’efficienza di recupero dei dati vettoriali su larga scala.

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="dense_vector",
    index_name="dense_vector_index",
    index_type="AUTOINDEX",
    metric_type="IP"
)
import io.milvus.v2.common.IndexParam;
import java.util.*;

List<IndexParam> indexes = new ArrayList<>();

indexes.add(IndexParam.builder()
        .fieldName("dense_vector")
        .indexType(IndexParam.IndexType.AUTOINDEX)
        .metricType(IndexParam.MetricType.IP)
        .build());
import { MetricType, IndexType } from "@zilliz/milvus2-sdk-node";

const indexParams = {
    index_name: 'dense_vector_index',
    field_name: 'dense_vector',
    metric_type: MetricType.IP,
    index_type: IndexType.AUTOINDEX
};
idx := index.NewAutoIndex(index.MetricType(entity.IP))
indexOption := milvusclient.NewCreateIndexOption("my_collection", "dense_vector", idx)
export indexParams='[
        {
            "fieldName": "dense_vector",
            "metricType": "IP",
            "indexName": "dense_vector_index",
            "indexType": "AUTOINDEX"
        }
    ]'

Nell’esempio sopra riportato, viene creato un indice denominato ` dense_vector_index ` per il campo ` dense_vector ` utilizzando il tipo di indice ` AUTOINDEX `. Il parametro ` metric_type ` è impostato su ` IP`, indicando che verrà utilizzato il prodotto interno come metrica di distanza.

Milvus offre vari tipi di indice per migliorare l’esperienza di ricerca vettoriale. AUTOINDEX è un tipo di indice speciale progettato per facilitare l’apprendimento della ricerca vettoriale. Sono disponibili numerosi tipi di indice tra cui scegliere. Per ulteriori dettagli, consultare la sezione Spiegazione degli indici.

Milvus supporta altri tipi di metriche. Per ulteriori informazioni, consultare la sezione Tipi di metriche.

Creazione di una collezione

Una volta completate le impostazioni relative ai vettori densi e ai parametri dell’indice, è possibile creare una collezione contenente vettori densi. L’esempio riportato di seguito utilizza il metodo ` create_collection ` per creare una collezione denominata ` my_collection`.

client.create_collection(
    collection_name="my_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_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_collection',
    schema: schema,
    index_params: indexParams
});

err = client.CreateCollection(ctx,
    milvusclient.NewCreateCollectionOption("my_collection", schema).
        WithIndexOptions(indexOption))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d "{
    \"collectionName\": \"my_collection\",
    \"schema\": $schema,
    \"indexParams\": $indexParams
}"

Inserimento dei dati

Dopo aver creato la collezione, utilizzare il metodo ` insert ` per aggiungere dati contenenti vettori densi. Assicurarsi che la dimensionalità dei vettori densi inseriti corrisponda al valore di ` dim ` definito durante l’aggiunta del campo vettore denso.

data = [
    {"dense_vector": [0.1, 0.2, 0.3, 0.7]},
    {"dense_vector": [0.2, 0.3, 0.4, 0.8]},
]

client.insert(
    collection_name="my_collection",
    data=data
)
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();
rows.add(gson.fromJson("{\"dense_vector\": [0.1, 0.2, 0.3, 0.4]}", JsonObject.class));
rows.add(gson.fromJson("{\"dense_vector\": [0.2, 0.3, 0.4, 0.5]}", JsonObject.class));

InsertResp insertR = client.insert(InsertReq.builder()
        .collectionName("my_collection")
        .data(rows)
        .build());
const data = [
  { dense_vector: [0.1, 0.2, 0.3, 0.7] },
  { dense_vector: [0.2, 0.3, 0.4, 0.8] },
];

client.insert({
  collection_name: "my_collection",
  data: data,
});
_, err = client.Insert(ctx, milvusclient.NewColumnBasedInsertOption("my_collection").
    WithFloatVectorColumn("dense_vector", 4, [][]float32{
        {0.1, 0.2, 0.3, 0.7},
        {0.2, 0.3, 0.4, 0.8},
    }),
)
if err != nil {
    fmt.Println(err.Error())
    // handle err
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "data": [
        {"dense_vector": [0.1, 0.2, 0.3, 0.4]},
        {"dense_vector": [0.2, 0.3, 0.4, 0.5]}        
    ],
    "collectionName": "my_collection"
}'

## {"code":0,"cost":0,"data":{"insertCount":2,"insertIds":["453577185629572531","453577185629572532"]}}

La ricerca semantica basata su vettori densi è una delle funzionalità principali di Milvus e consente di individuare rapidamente i dati più simili a un vettore di query in base alla distanza tra i vettori. Per eseguire una ricerca per somiglianza, preparare il vettore di query e i parametri di ricerca, quindi richiamare il metodo ` search `.

search_params = {
    "params": {"nprobe": 10}
}

query_vector = [0.1, 0.2, 0.3, 0.7]

res = client.search(
    collection_name="my_collection",
    data=[query_vector],
    anns_field="dense_vector",
    search_params=search_params,
    limit=5,
    output_fields=["pk"]
)

print(res)

# Output
# data: ["[{'id': '453718927992172271', 'distance': 0.7599999904632568, 'entity': {'pk': '453718927992172271'}}, {'id': '453718927992172270', 'distance': 0.6299999952316284, 'entity': {'pk': '453718927992172270'}}]"]
import io.milvus.v2.service.vector.request.data.FloatVec;

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

FloatVec queryVector = new FloatVec(new float[]{0.1f, 0.3f, 0.3f, 0.4f});

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

// Output
//
// [[SearchResp.SearchResult(entity={pk=453444327741536779}, score=0.65, id=453444327741536779), SearchResp.SearchResult(entity={pk=453444327741536778}, score=0.65, id=453444327741536778)]]
query_vector = [0.1, 0.2, 0.3, 0.7];

client.search({
    collection_name: 'my_collection',
    data: query_vector,
    limit: 5,
    output_fields: ['pk'],
    params: {
        nprobe: 10
    }
});
queryVector := []float32{0.1, 0.2, 0.3, 0.7}

annParam := index.NewCustomAnnParam()
annParam.WithExtraParam("nprobe", 10)
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
    "my_collection", // collectionName
    5,                     // limit
    []entity.Vector{entity.FloatVector(queryVector)},
).WithANNSField("dense_vector").
    WithOutputFields("pk").
    WithAnnParam(annParam))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}

for _, resultSet := range resultSets {
    fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
    fmt.Println("Scores: ", resultSet.Scores)
    fmt.Println("Pks: ", resultSet.GetColumn("pk").FieldData().GetScalars())
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "my_collection",
    "data": [
        [0.1, 0.2, 0.3, 0.7]
    ],
    "annsField": "dense_vector",
    "limit": 5,
    "searchParams":{
        "params":{"nprobe":10}
    },
    "outputFields": ["pk"]
}'

## {"code":0,"cost":0,"data":[{"distance":0.55,"id":"453577185629572532","pk":"453577185629572532"},{"distance":0.42,"id":"453577185629572531","pk":"453577185629572531"}]}

Per ulteriori informazioni sui parametri della ricerca per somiglianza, consultare Ricerca ANN di base.

Tradotto daDeepL

Prova Milvus gestito gratuitamente

Zilliz Cloud è senza problemi, basato su Milvus e 10 volte più veloce.

Inizia
Feedback

Questa pagina è stata utile?