5
$\begingroup$

I think this question is one that many beginners run into and I could not find a decent generic guide for it.

My issue is the following. I want to evaluate similarity of vectors which have mixed data type features.

  1. Numerical values
  2. Text
  3. Ordinal
  4. GPS coordinates

I am thus looking for a set of tools which would allow me to mix different distances measures to be able to calculate my own combined distance. Levenshtein distance for the text, some geohashing distance for the coordinates and the classical ones for the ordinal (potentially OHE-ed) values.

I was looking into Milvus-type functionality for DB + SDK.

Does something like this exist in one single package ? If not, what would you recommend ?

$\endgroup$
1
  • 1
    $\begingroup$ What exactly is the challenge? There are multiple aspects to this topic: If you knew the mathematical definition of the metric and just want to find a nice way to implement it, scipy.cdist with some simple algebra can be good enough; If you don't know the definition and need to learn it from the data, Brian has provided some good starting point; If you have the implementation but need to optimize it for searching/retrieval, it's a big topic and I'd look for vector indexing DBs such as the one you suggested and tailor for your own use case. $\endgroup$ Commented Apr 17, 2023 at 21:19

2 Answers 2

0
+100
$\begingroup$

Handling similarity search on mixed data types vectors can be challenging, as different distance measures are required for different types of data. One approach is to transform your mixed data type vectors into a homogeneous feature space, where all features are of the same data type. You can convert text features into a numerical representation using methods like bag-of-words, TF-IDF, or word embeddings. You can also transform GPS coordinates into a numerical representation using methods like geohashing or projecting them onto a 2D plane. Once all features are of the same data type, you can use standard distance measures like Euclidean distance or cosine similarity.

For example,

  • Euclidean distance for numerical values.
  • Levenshtein distance or the Jaccard distance for text.
  • Haversine distance or the Vincenty distance for GPS coordinates.
  • Hamming distance for ordinal values

To combine different distance measures, you can use techniques like feature weighting or feature selection to assign different weights to the different features based on their importance. You can also use ensemble techniques like bagging or boosting to combine the results of different distance measures.

Specialized libraries

  1. Use a specialized tool designed for similarity search on mixed data types vectors, such as Milvus. Milvus is an open-source vector database that supports similarity search on vectors of various data types, including numerical values, text, and images. It uses various indexing techniques to enable fast and accurate similarity search on large-scale datasets. Milvus is a library specifically designed for similarity search, and it supports various distance measures, including Euclidean distance, Jaccard distance, and Hamming distance. Milvus also provides SDKs for several programming languages, including Python, Java, and C++, and it supports both CPU and GPU acceleration.

  2. Annoy (Approximate Nearest Neighbors Oh Yeah) is a C++ library with Python bindings to search for points in space that are close to a given query point. Annoy is similar to faiss in that it supports different distance metrics and can handle mixed data types. One advantage of Annoy is that it can be used from Python via the annoy-py wrapper, which makes it easier to integrate into your workflow.

    Summary of features:

    • Euclidean distance, Manhattan distance, cosine distance, Hamming distance, or Dot (Inner) Product distance
    • Cosine distance is equivalent to Euclidean distance of normalized vectors = sqrt(2-2*cos(u, v))
    • Works better if you don't have too many dimensions (like <100) but seems to perform surprisingly well even up to 1,000 dimensions
    • Small memory usage
    • Lets you share memory between multiple processes
    • Index creation is separate from lookup (in particular you can not add more items once the tree has been created)
  3. faiss, which is a library for efficient similarity search and clustering of dense vectors. Faiss comes with precompiled libraries for Anaconda in Python, see faiss-cpu and faiss-gpu. The library is mostly implemented in C++, the only dependency is a BLAS implementation. It supports different distance metrics such as L2, inner product, and Hamming distance, as well as custom distances. Faiss also allows you to mix different distance metrics to create your own combined distance. For instance, you can use a combination of L2 distance for numerical data, Levenshtein distance for text, and geohashing distance for GPS coordinates.

  4. In scikit-learn, you can use the pairwise_distances function to calculate distances between pairs of samples using a variety of metrics, including custom metrics.

$\endgroup$
7
  • 1
    $\begingroup$ Thks for this - could you point me in the right direction wrt FAISS - I looked into it but thought it only worked on float embeddings. "Faiss handles collections of vectors of a fixed dimensionality d, typically a few 10s to 100s. These collections can be stored in matrices. We assume row-major storage, ie. the j'th component of vector number i is stored in row i, column j of the matrix. Faiss uses only 32-bit floating point matrices." from github.com/facebookresearch/faiss/wiki/Getting-started $\endgroup$
    – Chapo
    Commented Apr 20, 2023 at 1:42
  • $\begingroup$ You are correct that FAISS only works with float vectors. FAISS is designed to work with high-dimensional vectors, and typically, float vectors are used to represent them. However, you can still use FAISS by transforming your mixed data type vectors into a float vectors. $\endgroup$ Commented Apr 22, 2023 at 12:35
  • $\begingroup$ How does one transform text data to float vectors so that a levenshtein distance can be used ? $\endgroup$
    – Chapo
    Commented Apr 24, 2023 at 7:10
  • $\begingroup$ I had to give the bounty so I chose the best amongst the provided answers but it's not really satisfactory. $\endgroup$
    – Chapo
    Commented Apr 24, 2023 at 7:14
  • 3
    $\begingroup$ Most of these libraries don't offer the kind of support for the mixed data types mentioned by the OP. Also, it's not necessary to list all the features of these packages. Seems irrelevant if they're implemented in C++ or offer GPU support etc. Please avoid this type of filler content. Keep it concise and relevant to the OP's question. Thank you. $\endgroup$
    – oW_
    Commented Apr 24, 2023 at 21:00
2
$\begingroup$

There are at least two different approaches:

  1. Create a single embedding space then use a distance metric for continuously measured vectors. The embedding space can be pretrained, fine-tuned, or trained from scratch. One example is the StarSpace package.

  2. Use a distance metric that combines features measured on different scales. One example is Gower’s distance which uses a combination of Manhattan distance (continuously measured features), rank order (ordinal measured features), and Sørensen–Dice coefficient (categorical measured features).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.