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

Postgresql k-láng giềng gần nhất (KNN) trên khối lập phương đa chiều

PostgreSQL hỗ trợ toán tử khoảng cách <-> và như tôi hiểu, điều này có thể được sử dụng để phân tích văn bản (với mô-đun pg_trgrm) và hình học kiểu dữ liệu.

Tôi không biết làm thế nào bạn có thể sử dụng nó với nhiều hơn 1 chiều. Có thể bạn sẽ phải xác định hàm khoảng cách của riêng mình hoặc bằng cách nào đó chuyển đổi dữ liệu của bạn thành một cột với kiểu văn bản hoặc hình học. Ví dụ:nếu bạn có bảng có 8 cột (hình khối 8 chiều):

c1 c2 c3 c4 c5 c6 c7 c8
 1  0  1  0  1  0  1  2

Bạn có thể chuyển đổi nó thành:

c1 c2 c3 c4 c5 c6 c7 c8
 a  b  a  b  a  b  a  c

Và sau đó đến bảng có một cột:

c1
abababac

Sau đó, bạn có thể sử dụng (sau khi tạo gist chỉ mục ):

SELECT c1, c1 <-> 'ababab'
 FROM test_trgm 
 ORDER BY c1 <-> 'ababab';

Ví dụ

Tạo dữ liệu mẫu

-- Create some temporary data
-- ! Note that table are created in tmp schema (change sql to your scheme) and deleted if exists !
drop table if exists tmp.test_data;

-- Random integer matrix 100*8 
create table tmp.test_data as (
   select 
      trunc(random()*100)::int as input_variable_1,
      trunc(random()*100)::int as input_variable_2, 
      trunc(random()*100)::int as input_variable_3,
      trunc(random()*100)::int as input_variable_4, 
      trunc(random()*100)::int as input_variable_5, 
      trunc(random()*100)::int as input_variable_6, 
      trunc(random()*100)::int as input_variable_7, 
      trunc(random()*100)::int as input_variable_8
   from 
      generate_series(1,100,1)
);

Chuyển dữ liệu đầu vào thành văn bản

drop table if exists tmp.test_data_trans;

create table tmp.test_data_trans as (
select 
   input_variable_1 || ';' ||
   input_variable_2 || ';' ||
   input_variable_3 || ';' ||
   input_variable_4 || ';' ||
   input_variable_5 || ';' ||
   input_variable_6 || ';' ||
   input_variable_7 || ';' ||
   input_variable_8 as trans_variable
from 
   tmp.test_data
);

Điều này sẽ cung cấp cho bạn một biến trans_variable nơi lưu trữ tất cả 8 thứ nguyên:

trans_variable
40;88;68;29;19;54;40;90
80;49;56;57;42;36;50;68
29;13;63;33;0;18;52;77
44;68;18;81;28;24;20;89
80;62;20;49;4;87;54;18
35;37;32;25;8;13;42;54
8;58;3;42;37;1;41;49
70;1;28;18;47;78;8;17

Thay vì || bạn cũng có thể sử dụng cú pháp sau (ngắn hơn, nhưng khó hiểu hơn):

select 
   array_to_string(string_to_array(t.*::text,''),'') as trans_variable
from 
   tmp.test_data t

Thêm chỉ mục

create index test_data_gist_index on tmp.test_data_trans using gist(trans_variable);

Khoảng cách kiểm tra Lưu ý:Tôi đã chọn một hàng từ bảng - 52;42;18;50;68;29;8;55 - và sử dụng giá trị đã thay đổi một chút (42;42;18;52;98;29;8;55 ) để kiểm tra khoảng cách. Tất nhiên, bạn sẽ có các giá trị hoàn toàn khác trong dữ liệu thử nghiệm của mình, vì đó là ma trận NGẪU NHIÊN.

select 
   *, 
   trans_variable <->  '42;42;18;52;98;29;8;55' as distance,
   similarity(trans_variable, '42;42;18;52;98;29;8;55') as similarity,
from 
   tmp.test_data_trans 
order by
   trans_variable <-> '52;42;18;50;68;29;8;55';

Bạn có thể sử dụng toán tử khoảng cách <-> hoặc hàm tương tự. Khoảng cách =1 - Độ giống nhau



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. LỖI PostgreSQL:INSERT có nhiều cột mục tiêu hơn các biểu thức, khi nó không

  2. Tự động hóa Barman với Puppet:it2ndq / barman (phần hai)

  3. Làm thế nào để kiểm tra xem lược đồ công khai PostgreSQL có tồn tại hay không?

  4. Chuyển django RawQuerySet thành Queryset

  5. Tự động xác định các loại hàng trả về dựa trên một bảng đã cho đã truyền trong plpgsql?