PostgreSQL hỗ trợ khoảng cách điều hành <->
và như tôi hiểu nó, điều này có thể được sử dụng cho phân tích văn bản (với module pg_trgrm) và geometry kiểu dữ liệu.
Tôi không biết cách bạn có thể sử dụng nó với nhiều hơn 1 thứ nguyên. Có lẽ bạn sẽ phải xác định chức năng khoảng cách của riêng bạn 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 loại văn bản hoặc hình học.Ví dụ nếu bạn có bảng với 8 cột (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 nó sang:
c1 c2 c3 c4 c5 c6 c7 c8
a b a b a b a c
Và sau đó đến bảng với một cột:
c1
abababac
Sau đó, bạn có thể sử dụng (sau khi tạo gist
index):
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 đổi dữ liệu đầu vào 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
);
này sẽ cung cấp cho bạn một biến trans_variable
nơi tất cả các 8 thứ nguyên được lưu trữ:
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
.210
Thay vì ||
điều hành 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 index
create index test_data_gist_index on tmp.test_data_trans using gist(trans_variable);
Kiểm tra khoảng cách Lưu ý: Tôi đã chọn một dòng từ bảng - 52;42;18;50;68;29;8;55
- và sử dụng giá trị hơi thay đổi (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 nhau trong dữ liệu thử nghiệm của bạn, bởi vì nó là ma trận RANDOM.
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 chức năng tương tự. Khoảng cách = 1 - Tương tự
Bạn có thể giải thích bạn có dữ liệu nào không, có thể cung cấp một số mẫu nhỏ? Tôi nghĩ khối 8D chỉ là một bảng với 8 cột (kích thước). –
Tôi đã chỉnh sửa câu hỏi để bao gồm dữ liệu mẫu. Có, khối 8D có thể được biểu diễn bằng 8 cột số khác nhau. –
Tôi đã thêm ví dụ hoàn chỉnh vào câu trả lời ban đầu của mình. –