Плотный вектор
Плотные векторы - это числовые представления данных, широко используемые в машинном обучении и анализе данных. Они состоят из массивов вещественных чисел, в которых большинство или все элементы ненулевые. По сравнению с разреженными векторами, плотные векторы содержат больше информации на одном и том же уровне размерности, поскольку каждое измерение содержит значимые значения. Такое представление может эффективно отражать сложные закономерности и взаимосвязи, облегчая анализ и обработку данных в высокоразмерных пространствах. Плотные векторы обычно имеют фиксированное число измерений, от нескольких десятков до нескольких сотен или даже тысяч, в зависимости от конкретного применения и требований.
Плотные векторы в основном используются в сценариях, требующих понимания семантики данных, таких как семантический поиск и рекомендательные системы. В семантическом поиске плотные векторы помогают уловить глубинные связи между запросами и документами, повышая релевантность результатов поиска. В рекомендательных системах они помогают выявить сходство между пользователями и предметами, предлагая более персонализированные предложения.
Обзор
Плотные векторы обычно представляются в виде массивов чисел с плавающей точкой фиксированной длины, например [0.2, 0.7, 0.1, 0.8, 0.3, ..., 0.5]
. Размерность таких векторов обычно варьируется от сотен до тысяч, например 128, 256, 768 или 1024. Каждая размерность отражает специфические семантические особенности объекта, что позволяет использовать его в различных сценариях путем вычисления сходства.
Плотные векторы в двумерном пространстве
На рисунке выше показано представление плотных векторов в двумерном пространстве. Хотя плотные векторы в реальных приложениях часто имеют гораздо большую размерность, эта двумерная иллюстрация эффективно передает несколько ключевых концепций.
Многомерное представление: Каждая точка представляет собой концептуальный объект (например, Milvus, векторную базу данных, поисковую систему и т. д.), положение которого определяется значениями его размерностей.
Семантические отношения: Расстояния между точками отражают семантическое сходство между концептами. Более близкие точки указывают на концепции, которые более семантически связаны.
Эффект кластеризации: Связанные понятия (такие как Milvus, векторная база данных и поисковая система) располагаются близко друг к другу в пространстве, образуя семантический кластер.
Ниже приведен пример реального плотного вектора, представляющего текст "Milvus is an efficient vector database"
.
[
-0.013052909,
0.020387933,
-0.007869,
-0.11111383,
-0.030188112,
-0.0053388323,
0.0010654867,
0.072027855,
// ... more dimensions
]
Плотные векторы могут быть сгенерированы с помощью различных моделей встраивания, таких как CNN-модели (например, ResNet, VGG) для изображений и языковые модели (например, BERT, Word2Vec) для текста. Эти модели преобразуют исходные данные в точки в высокоразмерном пространстве, отражая семантические особенности данных. Кроме того, Milvus предлагает удобные методы, помогающие пользователям генерировать и обрабатывать плотные векторы, как подробно описано в разделе Embeddings.
После того как данные векторизованы, их можно хранить в Milvus для управления и поиска векторов. На схеме ниже показан основной процесс.
Использование плотных векторов в Milvus
Помимо плотных векторов, Milvus также поддерживает разреженные векторы и двоичные векторы. Разреженные векторы подходят для точного сопоставления по определенным терминам, например, для поиска по ключевым словам и сопоставления терминов, а двоичные векторы обычно используются для эффективной работы с бинаризованными данными, например, для сопоставления шаблонов изображений и некоторых приложений хэширования. Дополнительные сведения см. в разделах "Двоичный вектор" и "Разреженный вектор".
Использование плотных векторов в Milvus
Добавьте векторное поле
Чтобы использовать плотные векторы в Milvus, сначала определите векторное поле для хранения плотных векторов при создании коллекции. Этот процесс включает в себя.
Установка
datatype
на поддерживаемый тип данных плотного вектора. Поддерживаемые типы данных плотных векторов см. в разделе Типы данных.Указание размеров плотного вектора с помощью параметра
dim
.
В примере ниже мы добавляем векторное поле с именем dense_vector
для хранения плотных векторов. Тип данных поля - FLOAT_VECTOR
, размерность - 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: 128,
});
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
]
}"
Поддерживаемые типы данных для плотных векторных полей:
Тип | Описание |
---|---|
FLOAT_VECTOR | Хранит 32-битные числа с плавающей точкой, обычно используемые для представления вещественных чисел в научных вычислениях и машинном обучении. Идеально подходит для сценариев, требующих высокой точности, например для различения похожих векторов. |
FLOAT16_VECTOR | Хранит 16-битные числа с плавающей точкой половинной точности, используемые для глубокого обучения и вычислений на GPU. Экономит место в памяти в сценариях, где точность не так важна, например, на этапе запоминания с низкой точностью в рекомендательных системах. |
BFLOAT16_VECTOR | Хранит 16-битные числа Brain Floating Point (bfloat16), предлагая тот же диапазон экспоненты, что и Float32, но с пониженной точностью. Подходит для сценариев, в которых необходимо быстро обрабатывать большие объемы векторов, например, для крупномасштабного поиска изображений. |
Установка индексных параметров для векторного поля
Чтобы ускорить семантический поиск, необходимо создать индекс для векторного поля. Индексирование может значительно повысить эффективность поиска по крупномасштабным векторным данным.
index_params = client.prepare_index_params()
index_params.add_index(
field_name="dense_vector",
index_name="dense_vector_index",
index_type="IVF_FLAT",
metric_type="IP",
params={"nlist": 128}
)
import io.milvus.v2.common.IndexParam;
import java.util.*;
List<IndexParam> indexes = new ArrayList<>();
Map<String,Object> extraParams = new HashMap<>();
extraParams.put("nlist",128);
indexes.add(IndexParam.builder()
.fieldName("dense_vector")
.indexType(IndexParam.IndexType.IVF_FLAT)
.metricType(IndexParam.MetricType.IP)
.extraParams(extraParams)
.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.IVF_FLAT,
params: {
nlist: 128
},
};
export indexParams='[
{
"fieldName": "dense_vector",
"metricType": "IP",
"indexName": "dense_vector_index",
"indexType": "IVF_FLAT",
"params":{"nlist": 128}
}
]'
В приведенном выше примере для поля dense_vector
создается индекс с именем dense_vector_index
с использованием типа индекса IVF_FLAT
. Значение metric_type
установлено в IP
, что указывает на то, что в качестве метрики расстояния будет использоваться внутреннее произведение.
Milvus поддерживает и другие типы индексов. Для получения более подробной информации обратитесь к разделу Плавающие векторные индексы. Кроме того, Milvus поддерживает другие типы метрик. Для получения дополнительной информации обратитесь к разделу "Метрические типы".
Создание коллекции
После того как настройки параметров плотного вектора и индекса завершены, можно создать коллекцию, содержащую плотные векторы. В примере ниже используется метод create_collection
для создания коллекции с именем my_dense_collection
.
client.create_collection(
collection_name="my_dense_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_dense_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_dense_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_dense_collection\",
\"schema\": $schema,
\"indexParams\": $indexParams
}"
Вставка данных
После создания коллекции используйте метод insert
для добавления данных, содержащих плотные векторы. Убедитесь, что размерность вставляемых плотных векторов соответствует значению dim
, заданному при добавлении поля плотных векторов.
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_dense_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_dense_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_dense_collection",
data: data,
});
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"data": [
{"dense_vector": [0.1, 0.2, 0.3, 0.4]},
{"dense_vector": [0.2, 0.3, 0.4, 0.5]}
],
"collectionName": "my_dense_collection"
}'
## {"code":0,"cost":0,"data":{"insertCount":2,"insertIds":["453577185629572531","453577185629572532"]}}
Выполнение поиска по сходству
Семантический поиск на основе плотных векторов - одна из основных функций Milvus, позволяющая быстро находить данные, наиболее похожие на вектор запроса, на основе расстояния между векторами. Чтобы выполнить поиск по сходству, подготовьте вектор запроса и параметры поиска, а затем вызовите метод search
.
search_params = {
"params": {"nprobe": 10}
}
query_vector = [0.1, 0.2, 0.3, 0.7]
res = client.search(
collection_name="my_dense_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_dense_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_dense_collection,
data: query_vector,
limit: 5,
output_fields: ['pk'],
params: {
nprobe: 10
}
});
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_dense_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"}]}
Дополнительные сведения о параметрах поиска сходства см. в разделе Базовый поиск ANN.