PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Postgres:lập chỉ mục về độ tương tự cosine của mảng float cho tìm kiếm từ một đến nhiều

Tôi thu thập rằng không có tiện ích mở rộng nào làm được điều này, vì vậy tôi đã tìm thấy một giải pháp hạn chế:

Nếu A và B đều được chuẩn hóa (độ dài 1), cos(A, B) = 1 - 0.5 * ||A - B||^2 . ||A - B|| là khoảng cách Euclide và cos(A, B) là sự đồng dạng cosine. Vì vậy, khoảng cách Euclide lớn hơn <=> độ tương tự cosin nhỏ hơn (có ý nghĩa trực quan nếu bạn tưởng tượng một vòng tròn đơn vị), và nếu bạn có các vectơ không bình thường, việc thay đổi độ lớn của chúng mà không thay đổi hướng của chúng sẽ không ảnh hưởng đến độ tương đồng cosin của chúng. Thật tuyệt, vì vậy tôi có thể chuẩn hóa các vectơ của mình và so sánh khoảng cách Euclide của chúng ...

Có một câu trả lời hay ở đây về Cube , hỗ trợ điểm n-chiều và chỉ mục GiST trên Euclidean khoảng cách, nhưng nó chỉ hỗ trợ 100 chiều hoặc ít hơn (có thể bị tấn công cao hơn, nhưng tôi đã gặp vấn đề xung quanh 135 và cao hơn, vì vậy bây giờ tôi sợ). Cũng yêu cầu Postgres 9.6 trở lên.

Vì vậy:

  1. Đảm bảo rằng tôi không quan tâm đến việc có nhiều nhất 100 thứ nguyên. Nâng cấp lên Postgres 9.6 trở lên.
  2. Điền vào bảng của tôi bằng các mảng để đại diện cho vectơ.
  3. Chuẩn hóa các vectơ để tạo thêm một cột cube điểm. Tạo chỉ mục GiST trên cột này.
  4. Thứ tự theo khoảng cách Euclide tăng dần để có độ tương tự cosin giảm dần:EXPLAIN SELECT * FROM mytable ORDER BY normalized <-> cube(array[1,2,3,4,5,6,7,8,9,0]) LIMIT 10;

Nếu tôi cần hơn 100 thứ nguyên, tôi có thể đạt được điều này bằng cách sử dụng nhiều cột được lập chỉ mục. Sẽ cập nhật câu trả lời trong trường hợp đó.

Cập nhật: Khá chắc chắn rằng tôi không thể làm gì với việc chia vector> 100 chiều thành nhiều cột. Cuối cùng tôi phải quét toàn bộ bảng.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tham gia bên trong so với thực hiện mệnh đề where in

  2. Thay đổi sqlite thành PostgreSQL bằng ruby ​​trên đường ray

  3. Làm thế nào để giải quyết vấn đề về quyền khi chạy Postgresql từ minikube?

  4. Chuyển đổi quyền truy cập sang PostgreSQL?

  5. KitchenPC và Ironpython