150 boyutlu alanda en yakın komşu arama


13

Olası RDBMS herhangi birini kullanarak bir veritabanı oluşturmak istiyorum. Yaklaşık 150 sütunlu bir tablo olacaktır. Amaç, diğer bazı nesnelerin en yakın komşu araştırmasını yapmaktır. Yani 150 boyutlu uzayda bir NNS.

Zaten L1 veya L2 mesafeleri gibi bazı bariz yöntemleri kullanmaya çalıştım, ancak elbette birçok satır içeren tablolar için çok zaman alıyor. Ayrıca KD-ağacına (test etmedim not) ve PG-Strom'a bakmaya çalıştım ama çok boyutlu veriler için iyi bir çözüm değiller.

Matematik yöntemlerini (KD ağacı gibi) veya teknoloji yöntemlerini (PG-Strom gibi) kullanarak bir şekilde açıklanan aramanın hızını artırabilir miyim?

NNS hızını artırmak için izin herhangi bir RDBMS kullanmaya çalışacağım. Ancak MySQL ve PostgreSQL benim için en uygun DBMS.


1
Bunlar başka problemler. Başka bir soru sormak @ don-prog
Evan Carroll

Yanıtlar:


17

PostgreSQL 9.6 kullanarak cube

Önce küp uzantısını yükleyin

CREATE EXTENSION cube;

Şimdi 50 boyutta 100.000 noktaya sahip n boyutlu bir alan yaratacağız. Ayrıca bir GIST endeksi ekleyeceğiz.

CREATE TEMP TABLE space_nd
AS
  SELECT i, cube(array_agg(random()::float)) AS c
  FROM generate_series(1,1e5) AS i
  CROSS JOIN LATERAL generate_series(1,50)
    AS x
  GROUP BY i;

CREATE INDEX ON space_nd USING gist ( c );
ANALYZE space_nd;

Şimdi tek bir nokta oluşturacağız ve <->operatörü Eucledian mesafesini kullanarak en yakın noktayı bulmak için kullanacağız.

WITH points AS (
  SELECT cube(array_agg(random()::float)) AS c
  FROM generate_series(1,50)
    AS x
)
SELECT i,
  pg_typeof(space_nd.c),
  pg_typeof(points.c),
  cube_distance(space_nd.c, points.c)
FROM space_nd
CROSS JOIN points
ORDER BY space_nd.c <-> points.c
LIMIT 5;

PostgreSQL 9.6+, diğer mesafe operatörlerini destekler cube. Bunların tümü oluşturduğumuz GIST dizinini kullanabilir. Yani,

a <-> b float8  Euclidean distance between a and b.
a <#> b float8  Taxicab (L-1 metric) distance between a and b.
a <=> b float8  Chebyshev (L-inf metric) distance between a and b.

Bir uyarı olduğunu söyledi,

İnsanların bir şeyleri kırmasını zorlaştırmak için , küplerin boyutlarında 100'lük bir sınır vardır. Daha büyük bir şeye ihtiyacınız varsa, cubedata.h dosyasında ayarlanır.

150 boyut istersiniz. Bu küçük bir komplikasyon oluşturabilir.


1
To edit, cubedata.hdeneyimimdeki 130 boyutu geçmiyor. Ayrıca , Postgres'in satır başına dizin boyutunda her sayı için kaç bayt kullandığınızdan kaçınabileceğiniz bir sınır olduğundan , uzantıdaki tüm doubles veya s'leri de değiştirebilirsiniz . Bazı testler yaptım ve bu şekilde daha fazla boyut aldım ve IIRC 150'yi geçtim, ama tam olarak emin değilim. float8float4
sudo

Boyutlarla ilgili sınırlama ile aynı sorunum vardı ve 2048 sınırıyla docker görüntüsü oluşturdum: hub.docker.com/r/expert/postgresql-large-cube
uzman

2

İlk olarak boyut küçültmeyi gerçekleştirmeyi düşünün (örn. Temel Bileşen Analizi).

Daha sonra, daha yüksek performansa sahip az sayıda boyutta NN yapıyorsunuz.

Gerekirse postgres içinde PCA gerçekleştirmek için Pl / R kullanabilirsiniz.



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.