ค้นหาเพื่อนบ้านที่ใกล้ที่สุดอย่างรวดเร็วในพื้นที่ 150 มิติ


13

ฉันต้องการสร้างฐานข้อมูลโดยใช้ RDBMS ที่เป็นไปได้ มันจะมีตารางที่มีประมาณ 150 คอลัมน์ มีวัตถุประสงค์เพื่อทำการค้นหาเพื่อนบ้านที่ใกล้ที่สุดของวัตถุอื่น ๆ มันคือ NNS ในพื้นที่ 150 มิติ

ฉันพยายามใช้วิธีที่ชัดเจนบางอย่างเช่นระยะทาง L1 หรือ L2 แต่แน่นอนว่าต้องใช้เวลานานสำหรับตารางที่มีหลายแถว ฉันพยายามลองดู KD-tree (หมายเหตุฉันไม่ได้ทดสอบ) และ PG-Strom แต่มันไม่ใช่วิธีแก้ปัญหาที่ดีสำหรับข้อมูลที่มีหลายมิติ

ฉันสามารถปรับปรุงความเร็วของการค้นหาที่อธิบายโดยใช้วิธีการทางคณิตศาสตร์ (เช่น KD-tree) หรือวิธีการทางเทคโนโลยี (เช่น PG-Strom) ได้หรือไม่?

ฉันจะพยายามใช้ RDBMS ใด ๆ ที่อนุญาตให้ปรับปรุงความเร็วของ NNS แต่ MySQL และ PostgreSQL นั้นเป็น DBMS ที่เหมาะสมที่สุดสำหรับฉัน


1
นี่คือปัญหาอื่น ๆ เพียงแค่ถามคำถามอื่น @ don-prog
Evan Carroll

คำตอบ:


17

ใช้ PostgreSQL 9.6 cube

ขั้นแรกติดตั้งส่วนขยาย cube

CREATE EXTENSION cube;

ตอนนี้เราจะสร้างพื้นที่ n- มิติด้วย 100,000 คะแนนใน 50 มิติ นอกจากนี้เราจะเพิ่มดัชนี GIST

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;

ตอนนี้เราจะสร้างจุดเดียวและใช้โอเปอเรเตอร์<->เพื่อค้นหาจุดที่ใกล้ที่สุดโดยใช้ระยะทางแบบยุคลิด

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+ สนับสนุนผู้ประกอบการในระยะที่อื่น ๆ cubeมากกว่า ทั้งหมดนี้สามารถใช้ดัชนี GIST ที่เราสร้างขึ้น กล่าวคือ

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.

ที่กล่าวว่ามีหนึ่งข้อแม้

เพื่อให้ผู้คนทำลายสิ่งต่าง ๆ ได้ยากขึ้นมีจำนวน จำกัด ที่ 100 กับจำนวนมิติของลูกบาศก์ สิ่งนี้ถูกตั้งค่าเป็น cubedata.h หากคุณต้องการอะไรที่ใหญ่กว่า

คุณขอ 150 มิติ ที่อาจมีอาการแทรกซ้อนเล็กน้อย


1
การแก้ไขcubedata.hไม่สามารถใช้งานในมิติ 130 มิติในประสบการณ์ของฉัน บางทีคุณอาจจะยังสามารถเปลี่ยนทั้งหมดdoubleหรือfloat8ในส่วนขยายไปfloat4ตั้งแต่ Postgres มีข้อ จำกัด เรื่องขนาดดัชนีต่อแถวที่คุณสามารถอยู่ห่างจากโดยลดลงครึ่งหนึ่งวิธีการหลายไบต์ที่คุณใช้ในแต่ละหมายเลข ฉันทำการทดสอบและมีมิติเพิ่มเติมในแบบนั้นและ IIRC ฉันผ่านมาแล้ว 150 ปี แต่ฉันไม่แน่ใจทั้งหมด
sudo

ฉันมีปัญหาแบบเดียวกันกับการ จำกัด ขนาดและสร้างภาพนักเทียบท่าด้วยขีด จำกัด 2048: hub.docker.com/r/expert/postgresql-large-cube
ผู้เชี่ยวชาญ

2

พิจารณาการลดขนาดก่อน (เช่นการวิเคราะห์องค์ประกอบหลัก)

จากนั้นคุณกำลังทำ NN ในมิติข้อมูลขนาดเล็กที่มีประสิทธิภาพสูง

คุณสามารถใช้ Pl / R เพื่อทำ PCA ภายใน postgres หากจำเป็น



0

ลองดูที่https://github.com/a-mma/AquilaDBเป็นฐานข้อมูลเวกเตอร์เพื่อจัดเก็บ Feature Vectors พร้อมกับ JSON Metadata เก็บไว้พร้อมกับ RDBMS ของคุณและใช้ข้อมูลเมตาเพื่อรักษาการอ้างอิงโยงระหว่างข้อมูล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.