{"id":361736,"date":"2024-05-21T01:20:00","date_gmt":"2024-05-21T01:20:00","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=361736"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T01:20:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=361736","title":{"rendered":"<span>\u041d\u0430 \u0433\u0440\u0430\u043d\u0438 \u0418\u0418: \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0432 PostgreSQL + pgvector<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041d\u0430\u00a0\u0425\u0430\u0431\u0440\u0435\u00a0\u0431\u044b\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439 pgvector \u0432\u00a0\u043e\u0431\u0437\u043e\u0440\u0430\u0445 Postgresso. \u0418 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043d\u043e\u0432\u043e\u0441\u0442\u044c\u00a0\u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u00a0\u043c\u0435\u0441\u0442\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0433\u0434\u0435\u2011\u0442\u043e \u0437\u0430\u00a0\u0433\u0440\u0430\u043d\u0438\u0446\u0435\u0439 \u0438 \u0434\u0430\u043b\u0435\u043a\u043e. \u041c\u043d\u043e\u0433\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f\u00a0\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u0438\u0441\u043a\u0430 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0432\u00a0\u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u044b\u043d\u0447\u0435 \u043d\u0435\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b, \u0430\u00a0pgvector \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043b\u044e\u0431\u043e\u043c\u0443, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0432\u00a0\u0441\u0430\u043c\u043e\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0439 \u0431\u0430\u0437\u0435 \u0432\u00a0\u0420\u043e\u0441\u0441\u0438\u0438. \u041f\u0440\u0438\u043c\u0435\u043d\u0438\u043c pgvector \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u0434\u043e\u043c\u043e\u0432 \u043f\u043e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435.<\/p>\n<p>\u0412\u00a0\u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u043a\u0430\u0436\u0443 \u043d\u0430\u00a0\u044d\u0442\u043e\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u0430\u043a\u00a0\u0445\u0440\u0430\u043d\u0438\u0442\u044c, \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c <code>DBSCAN<\/code>\u0432\u0435\u043a\u0442\u043e\u0440\u044b \u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u043f\u043e\u00a0\u043d\u0438\u043c \u0432\u00a0\u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u0441 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u043d\u0430 \u0433\u0440\u0430\u043d\u0438 \u0442\u0438\u043f\u0438\u0447\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430\u0434\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c pgvector \u0432\u00a0PostgreSQL, \u043e\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u00a0\u0432\u0438\u0434\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0441\u00a0\u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437\u00a0Docker, \u0442\u043e \u043c\u043e\u0433\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u00a0Dockerfile \u0441\u0442\u0440\u043e\u0447\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0437:<\/p>\n<pre><code>RUN git clone --branch v0.5.1 https:\/\/github.com\/pgvector\/pgvector.git RUN cd pgvector &amp;&amp; make &amp;&amp; make install<\/code><\/pre>\n<p>\u0410 \u0432 \u0441\u0430\u043c\u043e\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435:<\/p>\n<pre><code>osmworld=# CREATE EXTENSION vector; CREATE EXTENSION Time: 32,606 ms<\/code><\/pre>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f\u00a0\u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0437\u00a0\u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u00a0python \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u0438\u043b\u0438\u00a0ML \u043c\u043e\u0434\u0435\u043b\u0438 \u0432\u00a0spark \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u00a0\u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u00a0\u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439 \u0442\u0438\u043f\u0430 vector. \u0410\u00a0\u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u00a0SQL \u043a\u0430\u043a\u00a0\u0433\u0438\u0441\u0442\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439. \u0412\u00a0\u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u00a0\u043c\u0430\u0441\u0441\u0438\u0432\u0430\u0445 <code>real[]<\/code>, <code>integer[]<\/code> \u0438\u043b\u0438\u00a0<code>double precision[]<\/code>, <code>numeric[]<\/code> \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a\u00a0\u0442\u0438\u043f\u0443 <code>::vector<\/code>. <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u043b\u044f\u00a0\u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u0441\u043b\u0443\u0436\u0430\u0442 \u0433\u0438\u0441\u0442\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0447\u0438\u0441\u043b\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u0435\u0442\u0441\u043a\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u00a0\u043e\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0441\u0442\u044f\u0445 \u0436\u0438\u043b\u044b\u0445 \u0434\u043e\u043c\u043e\u0432 \u0432\u00a0\u041c\u043e\u0441\u043a\u0432\u0435. \u041f\u0440\u043e\u00a0\u0442\u043e \u043a\u0430\u043a\u00a0\u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u044f <a href=\"https:\/\/habr.com\/ru\/articles\/776582\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0437\u0434\u0435\u0441\u044c<\/a>, \u0430\u00a0\u0432\u00a0\u044d\u0442\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u044c\u043c\u0443 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u043e\u0437\u0434\u0430\u043c \u0438\u0437\u00a0\u043d\u0438\u0445 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u00a0\u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439 \u0442\u0438\u043f\u0430 \u043e\u0434\u0438\u043d\u0430\u0434\u0446\u0430\u0442\u0438\u043c\u0435\u0440\u043d\u044b\u0439 vector:<\/p>\n<pre><code class=\"sql\">create table infrastructure_for_children_features as    select (row_number() over ())::integer id, null::integer cluster,           district, street, housenumber,           ARRAY[kindergarten::integer, school::integer,college::integer, university::integer, language_school::integer, music_school::integer,training::integer,sports_centre::integer,community_centre::integer,playground::integer,clinic::integer]    ::vector(11) feature  from infrastructure_for_children; alter table infrastructure_for_children_features add primary key(id);<\/code><\/pre>\n<p>\u0422\u0430\u043a \u0432 \u0431\u0430\u0437\u0435 \u0441\u043e\u0437\u0434\u0430\u043b \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043d\u0430 30237 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439:<\/p>\n<pre><code class=\"sql\">osmworld=# \\d infrastructure_for_children_features    Table \"public.infrastructure_for_children_features\"    Column    |    Type    |  -------------+------------|  id          | integer    |   cluster     | integer    |   district    | text       |   street      | text       |   housenumber | text       |   feature     | vector(11) | Indexes:     \"infrastructure_for_children_features_pkey\" PRIMARY KEY, btree (id)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c\u00a0\u0431\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0438\u0445 \u0432\u00a0\u0433\u0440\u0443\u043f\u043f\u044b \u043f\u043e\u00a0\u0431\u043b\u0438\u0437\u043e\u0441\u0442\u0438 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432. \u041e\u043f\u044f\u0442\u044c\u00a0\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0438, \u0430\u00a0\u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438\u00a0\u2014 \u043c\u0435\u0442\u043e\u0434 k\u2011\u0441\u0440\u0435\u0434\u043d\u0438\u0445(k\u2011means) \u0438\u043b\u0438\u00a0\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043d\u0430\u00a0\u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f\u00a0\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441\u00a0\u0448\u0443\u043c\u0430\u043c\u0438 (DBSCAN). \u0414\u043b\u044f\u00a0\u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0431\u043b\u0438\u0437\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0415\u0432\u043a\u043b\u0438\u0434\u043e\u0432\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0438\u0437\u00a0\u043a\u043e\u043b\u043e\u043d\u043a\u0438 feature. <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0447\u0438\u0441\u043b\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u043c\u043d\u0435 \u043d\u0435\u00a0\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0442\u043e \u044f \u0432\u044b\u0431\u0435\u0440\u0443 \u043c\u0435\u0442\u043e\u0434 DBSCAN \u0438 \u043f\u0440\u043e\u0433\u043e\u043d\u044e \u044d\u0442\u043e\u0442 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442\u00a0epsilon \u0447\u0438\u0441\u043b\u0430 \u0433\u0440\u0443\u043f\u043f \u0438 \u0447\u0438\u0441\u043b\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435\u00a0\u043f\u043e\u043f\u0430\u0432\u0448\u0438\u0445 \u0432\u00a0\u0433\u0440\u0443\u043f\u043f\u044b:<\/p>\n<pre><code>eps|clusters|not_in_cluster 0.07529667 0.57529667 1.020228648 1.547526904 2.092822630 2.5122717620 3.0117311778 3.58567605 4.06014562 4.53642760 5.02321574 5.5138972 6.077604 6.551377 7.029265 7.514168 8.01096 8.5454 9.0437 9.5230<\/code><\/pre>\n<p>\u041d\u0430 \u0441\u0432\u043e\u0439 \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0432\u044b\u0431\u0435\u0440\u0443 eps=5.5 \u0438 \u0437\u0430\u043f\u0443\u0449\u0443 Java \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 cluster \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 DBSCAN \u0434\u043b\u044f minPoints=3 \u0438 eps=5.5:<\/p>\n<pre><code class=\"java\">package com.github.isuhorukov;  import com.pgvector.PGvector; import org.apache.commons.math3.ml.clustering.Cluster; import org.apache.commons.math3.ml.clustering.Clusterable; import org.apache.commons.math3.ml.clustering.DBSCANClusterer; import org.apache.commons.math3.ml.distance.EuclideanDistance;  import java.sql.*; import java.util.ArrayList; import java.util.List;  public class Main {     public static void main(String[] args) throws Exception {         try (Connection connection = DriverManager.getConnection(                 System.getenv(\"jdbc_url\"), System.getenv(\"user\"), System.getenv(\"password\"))) {             connection.setAutoCommit(false);             PGvector.addVectorType(connection);             float eps = Float.parseFloat(System.getenv(\"eps\"));             int minPoints = Integer.parseInt(System.getenv(\"minPoints\"));             DBSCANClusterer&lt;Feature> dbscanClusterer = new DBSCANClusterer&lt;>(eps,minPoints,new EuclideanDistance());             List&lt;Feature> features = fetchFeatures(connection,                                                     \"select id,feature from infrastructure_for_children_features\");             List&lt;Cluster&lt;Feature>> cluster = dbscanClusterer.cluster(features);             saveClusters(connection, cluster);         }     }      private static void saveClusters(Connection connection, List&lt;Cluster&lt;Feature>> cluster) throws SQLException {         try (PreparedStatement clusterPs = connection.prepareStatement(              \"update infrastructure_for_children_features set cluster = ? where id = ?\")){             for (int idx = 0; idx &lt; cluster.size(); idx++) {                 List&lt;Feature> featureCluster = cluster.get(idx).getPoints();                 for (Feature feature : featureCluster) {                     clusterPs.setInt(1, idx);                     clusterPs.setInt(2, feature.id);                     clusterPs.addBatch();                 }                 clusterPs.executeBatch();             }             connection.commit();         } catch (Exception e) {             connection.rollback();             throw new RuntimeException(e);         }     }      private static List&lt;Feature> fetchFeatures(Connection connection, String query) {         List&lt;Feature> features = new ArrayList&lt;>();         try (Statement statement = connection.createStatement();              ResultSet resultSet = statement.executeQuery(query))         {             while (resultSet.next()) {                 int id = resultSet.getInt(1);                 float[] feature = ((PGvector) resultSet.getObject(2)).toArray();                 features.add(new Feature(id, feature));             }         } catch (Exception e) {             throw new RuntimeException(e);         }         return features;     }      static class Feature implements Clusterable {         public int id;         public double[] feature;         public Feature(int id, float[] feature) {             this.id = id;             this.feature = new double[feature.length];             for (int i = 0; i &lt; feature.length; i++) {                 this.feature[i] = feature[i];             }         }          @Override         public double[] getPoint() {             return feature;         }     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0443\u0436\u0435\u043d pom.xml \u0434\u043b\u044f maven:<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?> &lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"          xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"          xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\">     &lt;modelVersion>4.0.0&lt;\/modelVersion>      &lt;groupId>com.github.igor-suhorukov&lt;\/groupId>     &lt;artifactId>vectors&lt;\/artifactId>     &lt;version>1.0-SNAPSHOT&lt;\/version>      &lt;properties>         &lt;maven.compiler.source>11&lt;\/maven.compiler.source>         &lt;maven.compiler.target>11&lt;\/maven.compiler.target>         &lt;project.build.sourceEncoding>UTF-8&lt;\/project.build.sourceEncoding>     &lt;\/properties>     &lt;dependencies>         &lt;dependency>             &lt;groupId>org.apache.commons&lt;\/groupId>             &lt;artifactId>commons-math3&lt;\/artifactId>             &lt;version>3.6.1&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>com.pgvector&lt;\/groupId>             &lt;artifactId>pgvector&lt;\/artifactId>             &lt;version>0.1.3&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.postgresql&lt;\/groupId>             &lt;artifactId>postgresql&lt;\/artifactId>             &lt;version>42.6.0&lt;\/version>         &lt;\/dependency>     &lt;\/dependencies> &lt;\/project><\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f URL \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0436\u0438\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0442\u0438\u043f \u0432\u0435\u043a\u0442\u043e\u0440\u0430 <code>PGvector<\/code> \u0432 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u00a0<code>fetchFeatures<\/code>\u00a0\u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u043d\u0430\u043c\u0438 \u0440\u0430\u043d\u0435\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b infrastructure_for_children_features.<\/p>\n<\/li>\n<li>\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u00a0<code>eps<\/code>\u00a0\u0438\u00a0<code>minPoints<\/code>\u00a0\u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0442\u0438\u043f\u044b\u00a0<code>float<\/code>\u00a0\u0438\u00a0<code>int<\/code>\u00a0\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u00a0<code>DBSCANClusterer<\/code>\u00a0\u0438\u0437 commons-math3 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c\u00a0<code>eps<\/code>,\u00a0<code>minPoints<\/code>\u00a0\u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f (<code>EuclideanDistance<\/code>). \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u00a0<code>cluster<\/code>\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u00a0<code>DBSCANClusterer<\/code>\u00a0\u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u043d\u0435\u0435 \u0438\u0437 \u0431\u0430\u0437\u044b \u0432 \u043c\u0435\u0442\u043e\u0434\u0435<code>fetchFeatures<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u00a0<code>saveClusters<\/code>\u00a0\u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u043b\u0435 cluster \u0442\u0430\u0431\u043b\u0438\u0446\u044b infrastructure_for_children_features, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u043d\u043e\u043c\u0435\u0440 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0438 id \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u043b\u0438\u0441\u044c, \u0442\u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 &#8212; \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/590\/649\/1da\/5906491da5be70b9211f79353f484f1f.png\" alt=\"\u0427\u0435\u043c \u0436\u0435 \u043f\u043e\u0445\u043e\u0436\u0438 \u044d\u0442\u0438 \u0440\u0430\u0439\u043e\u043d\u044b, \u0435\u0449\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c \u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 epsilon\" title=\"\u0427\u0435\u043c \u0436\u0435 \u043f\u043e\u0445\u043e\u0436\u0438 \u044d\u0442\u0438 \u0440\u0430\u0439\u043e\u043d\u044b, \u0435\u0449\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c \u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 epsilon\" width=\"1011\" height=\"852\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/590\/649\/1da\/5906491da5be70b9211f79353f484f1f.png\"\/><\/p>\n<div><figcaption>\u0427\u0435\u043c \u0436\u0435 \u043f\u043e\u0445\u043e\u0436\u0438 \u044d\u0442\u0438 \u0440\u0430\u0439\u043e\u043d\u044b, \u0435\u0449\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c \u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 epsilon<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d05\/263\/12f\/d0526312fa7a0ceddc0547a604f320f1.png\" alt=\"\u041e\u0434\u0438\u043d \u0434\u043e\u043c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u0443\u0433\u0430\u0434 \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \" title=\"\u041e\u0434\u0438\u043d \u0434\u043e\u043c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u0443\u0433\u0430\u0434 \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \" width=\"1749\" height=\"1051\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d05\/263\/12f\/d0526312fa7a0ceddc0547a604f320f1.png\"\/><\/p>\n<div><figcaption>\u041e\u0434\u0438\u043d \u0434\u043e\u043c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u0443\u0433\u0430\u0434 \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 <\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u0439\u0434\u0435\u043c \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u043c \u0441\u043e \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430 \u043f\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0443:<\/p>\n<pre><code class=\"sql\">osmworld=# select * from infrastructure_for_children_features where id=831;  id  | cluster |     district      |        street         | housenumber |             feature              -----+---------+-------------+--------------------+-------------------+-----------------------+-------------+---------------------------------  831 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430 | 19          | [37,28,3,23,6,4,17,23,9,148,92] (1 row)<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0432 PostgreSQL \u043d\u0430\u0439\u0434\u0435\u043c 10 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445 \u043a \u043d\u0435\u043c\u0443 \u0434\u043e\u043c\u043e\u0432 \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u0432\u0435\u043a\u0442\u043e\u0440\u0430:<\/p>\n<pre><code class=\"sql\">osmworld=# select id, cluster, district,street,housenumber from infrastructure_for_children_features order by  feature&lt;-> '[37,28,3,23,6,4,17,23,9,148,92]' limit 10;   id  | cluster |     district      |            street            | housenumber  ------+---------+-------------------+------------------------------+-------------   831 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430        | 19  1011 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430        | 17   897 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0421\u044b\u0442\u0438\u043d\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a           | 5\/10 \u04413   827 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a        | 8\/15  1019 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430        | 16   823 |       4 | \u0422\u0432\u0435\u0440\u0441\u043a\u043e\u0439 \u0440\u0430\u0439\u043e\u043d    | \u041c\u0430\u043b\u044b\u0439 \u041f\u0430\u043b\u0430\u0448\u0451\u0432\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a   | 4   893 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u043e\u0439 \u041a\u043e\u0437\u0438\u0445\u0438\u043d\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a | 4   631 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430        | 25 \u04413   821 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0421\u044b\u0442\u0438\u043d\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a           | 5\/10 \u04414  1117 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a        | 5 (10 rows)  Time: 25,777 ms  osmworld=# explain select id, cluster, district,street,housenumber from infrastructure_for_children_features order by  feature&lt;-> '[37,28,3,23,6,4,17,23,9,148,92]' limit 10;                                                QUERY PLAN                                                --------------------------------------------------------------------------------------------------------  Limit  (cost=2375.37..2375.40 rows=10 width=90)    ->  Sort  (cost=2375.37..2450.97 rows=30237 width=90)          Sort Key: ((feature &lt;-> '[37,28,3,23,6,4,17,23,9,148,92]'::vector))          ->  Seq Scan on infrastructure_for_children_features  (cost=0.00..1721.96 rows=30237 width=90) (4 rows)<\/code><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0433\u043e\u0440\u043e\u0434\u0435 \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u0434\u043e\u043c\u0430 \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435, \u043f\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u0432 \u043e\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0441\u0442\u044f\u0445 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c? \u0414\u0430, \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0438\u043d\u0434\u0435\u043a\u0441\u044b IVFFlat \u0438 HNSW. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c HNSW \u043e\u043d \u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0438 \u0442\u043e\u0447\u043d\u044b\u0439, \u0435\u0441\u043b\u0438 \u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0443\u0447\u043d\u044b\u043c \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f\u043c:<\/p>\n<pre><code class=\"sql\">osmworld=# CREATE INDEX ON infrastructure_for_children_features USING hnsw (feature vector_l2_ops) WITH (m = 16, ef_construction = 64); CREATE INDEX Time: 12705,611 ms (00:12,706)  osmworld=# \\d infrastructure_for_children_features        Table \"public.infrastructure_for_children_features\"    Column    |       Type       | Collation | Nullable | Default  -------------+------------------+-----------+----------+---------  id          | integer          |           | not null |   cluster     | integer          |           |          |   lon         | double precision |           |          |   lat         | double precision |           |          |   district    | text             |           |          |   street      | text             |           |          |   housenumber | text             |           |          |   feature     | vector(11)       |           |          |  Indexes:     \"infrastructure_for_children_features_pkey\" PRIMARY KEY, btree (id)     \"infrastructure_for_children_features_feature_idx\" hnsw (feature vector_l2_ops) WITH (m='16', ef_construction='64')  osmworld=# explain select id, cluster, district,street,housenumber from infrastructure_for_children_features order by  feature&lt;-> '[37,28,3,23,6,4,17,23,9,148,92]' limit 10;                                                                         QUERY PLAN                                                                          -----------------------------------------------------------------------------------------------------------------------------------------------------------  Limit  (cost=5.00..5.61 rows=10 width=90)    ->  Index Scan using infrastructure_for_children_features_feature_idx on infrastructure_for_children_features  (cost=5.00..1861.36 rows=30237 width=90)          Order By: (feature &lt;-> '[37,28,3,23,6,4,17,23,9,148,92]'::vector) (3 rows) Time: 1,022 ms<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u0441\u0442\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0438\u043d\u0434\u0435\u043a\u0441 \u0438 \u043f\u043e\u0438\u0441\u043a \u043f\u043e\u00a0\u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c \u0441\u0442\u0430\u043b\u00a0\u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430\u00a0\u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u043e\u00a0\u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441\u00a0seqscan, \u0438 \u0432\u00a0\u044d\u0442\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0443\u0433\u0430\u0434\u0430\u043b \u0441\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0434\u043b\u044f\u00a0DBSCAN:<\/p>\n<pre><code class=\"sql\">osmworld=# select id, cluster, district,street,housenumber from infrastructure_for_children_features order by  feature&lt;-> '[37,28,3,23,6,4,17,23,9,148,92]' limit 10;   id  | cluster |     district      |            street            | housenumber  ------+---------+-------------------+------------------------------+-------------   831 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430        | 19  1011 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430        | 17   827 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a        | 8\/15   897 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0421\u044b\u0442\u0438\u043d\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a           | 5\/10 \u04413  1019 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430        | 16   823 |       4 | \u0422\u0432\u0435\u0440\u0441\u043a\u043e\u0439 \u0440\u0430\u0439\u043e\u043d    | \u041c\u0430\u043b\u044b\u0439 \u041f\u0430\u043b\u0430\u0448\u0451\u0432\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a   | 4   893 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u043e\u0439 \u041a\u043e\u0437\u0438\u0445\u0438\u043d\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a | 4   631 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430        | 25 \u04413   821 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0421\u044b\u0442\u0438\u043d\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a           | 5\/10 \u04414  1117 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0443\u043b\u043e\u043a        | 5 (10 rows)  Time: 1,644 ms<\/code><\/pre>\n<h2>\u0412\u044b\u0432\u043e\u0434<\/h2>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 pgvector PostgreSQL \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0432\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0438 \u0441\u00a0\u043d\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435\u00a0\u0442\u043e\u043b\u044c\u043a\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430\u043c\u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u043d\u043e\u00a0\u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430\u043c\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0437\u00a0\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u043e JDBC, \u0430\u00a0\u0442\u0430\u043a\u00a0\u0436\u0435\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u0438\u0441\u043a\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u043e\u0438\u0441\u043a \u043f\u043e\u00a0\u0431\u043b\u0438\u0437\u043e\u0441\u0442\u0438 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 HNSW.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/777734\/\"> https:\/\/habr.com\/ru\/articles\/777734\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041d\u0430\u00a0\u0425\u0430\u0431\u0440\u0435\u00a0\u0431\u044b\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439 pgvector \u0432\u00a0\u043e\u0431\u0437\u043e\u0440\u0430\u0445 Postgresso. \u0418 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043d\u043e\u0432\u043e\u0441\u0442\u044c\u00a0\u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u00a0\u043c\u0435\u0441\u0442\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0433\u0434\u0435\u2011\u0442\u043e \u0437\u0430\u00a0\u0433\u0440\u0430\u043d\u0438\u0446\u0435\u0439 \u0438 \u0434\u0430\u043b\u0435\u043a\u043e. \u041c\u043d\u043e\u0433\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f\u00a0\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u0438\u0441\u043a\u0430 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0432\u00a0\u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u044b\u043d\u0447\u0435 \u043d\u0435\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b, \u0430\u00a0pgvector \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043b\u044e\u0431\u043e\u043c\u0443, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0432\u00a0\u0441\u0430\u043c\u043e\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0439 \u0431\u0430\u0437\u0435 \u0432\u00a0\u0420\u043e\u0441\u0441\u0438\u0438. \u041f\u0440\u0438\u043c\u0435\u043d\u0438\u043c pgvector \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u0434\u043e\u043c\u043e\u0432 \u043f\u043e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435.<\/p>\n<p>\u0412\u00a0\u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u043a\u0430\u0436\u0443 \u043d\u0430\u00a0\u044d\u0442\u043e\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u0430\u043a\u00a0\u0445\u0440\u0430\u043d\u0438\u0442\u044c, \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c <code>DBSCAN<\/code>\u0432\u0435\u043a\u0442\u043e\u0440\u044b \u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u043f\u043e\u00a0\u043d\u0438\u043c \u0432\u00a0\u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u0441 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u043d\u0430 \u0433\u0440\u0430\u043d\u0438 \u0442\u0438\u043f\u0438\u0447\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430\u0434\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c pgvector \u0432\u00a0PostgreSQL, \u043e\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u00a0\u0432\u0438\u0434\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0441\u00a0\u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437\u00a0Docker, \u0442\u043e \u043c\u043e\u0433\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u00a0Dockerfile \u0441\u0442\u0440\u043e\u0447\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0437:<\/p>\n<pre><code>RUN git clone --branch v0.5.1 https:\/\/github.com\/pgvector\/pgvector.git RUN cd pgvector &amp;&amp; make &amp;&amp; make install<\/code><\/pre>\n<p>\u0410 \u0432 \u0441\u0430\u043c\u043e\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435:<\/p>\n<pre><code>osmworld=# CREATE EXTENSION vector; CREATE EXTENSION Time: 32,606 ms<\/code><\/pre>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f\u00a0\u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0437\u00a0\u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u00a0python \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u0438\u043b\u0438\u00a0ML \u043c\u043e\u0434\u0435\u043b\u0438 \u0432\u00a0spark \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u00a0\u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u00a0\u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439 \u0442\u0438\u043f\u0430 vector. \u0410\u00a0\u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u00a0SQL \u043a\u0430\u043a\u00a0\u0433\u0438\u0441\u0442\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439. \u0412\u00a0\u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u00a0\u043c\u0430\u0441\u0441\u0438\u0432\u0430\u0445 <code>real[]<\/code>, <code>integer[]<\/code> \u0438\u043b\u0438\u00a0<code>double precision[]<\/code>, <code>numeric[]<\/code> \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a\u00a0\u0442\u0438\u043f\u0443 <code>::vector<\/code>. <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u043b\u044f\u00a0\u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u0441\u043b\u0443\u0436\u0430\u0442 \u0433\u0438\u0441\u0442\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0447\u0438\u0441\u043b\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u0435\u0442\u0441\u043a\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u00a0\u043e\u043a\u0440\u0435\u0441\u0442\u043d\u043e\u0441\u0442\u044f\u0445 \u0436\u0438\u043b\u044b\u0445 \u0434\u043e\u043c\u043e\u0432 \u0432\u00a0\u041c\u043e\u0441\u043a\u0432\u0435. \u041f\u0440\u043e\u00a0\u0442\u043e \u043a\u0430\u043a\u00a0\u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u044f <a href=\"https:\/\/habr.com\/ru\/articles\/776582\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0437\u0434\u0435\u0441\u044c<\/a>, \u0430\u00a0\u0432\u00a0\u044d\u0442\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u044c\u043c\u0443 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u043e\u0437\u0434\u0430\u043c \u0438\u0437\u00a0\u043d\u0438\u0445 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u00a0\u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439 \u0442\u0438\u043f\u0430 \u043e\u0434\u0438\u043d\u0430\u0434\u0446\u0430\u0442\u0438\u043c\u0435\u0440\u043d\u044b\u0439 vector:<\/p>\n<pre><code class=\"sql\">create table infrastructure_for_children_features as    select (row_number() over ())::integer id, null::integer cluster,           district, street, housenumber,           ARRAY[kindergarten::integer, school::integer,college::integer, university::integer, language_school::integer, music_school::integer,training::integer,sports_centre::integer,community_centre::integer,playground::integer,clinic::integer]    ::vector(11) feature  from infrastructure_for_children; alter table infrastructure_for_children_features add primary key(id);<\/code><\/pre>\n<p>\u0422\u0430\u043a \u0432 \u0431\u0430\u0437\u0435 \u0441\u043e\u0437\u0434\u0430\u043b \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043d\u0430 30237 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439:<\/p>\n<pre><code class=\"sql\">osmworld=# \\d infrastructure_for_children_features    Table \"public.infrastructure_for_children_features\"    Column    |    Type    |  -------------+------------|  id          | integer    |   cluster     | integer    |   district    | text       |   street      | text       |   housenumber | text       |   feature     | vector(11) | Indexes:     \"infrastructure_for_children_features_pkey\" PRIMARY KEY, btree (id)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c\u00a0\u0431\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0438\u0445 \u0432\u00a0\u0433\u0440\u0443\u043f\u043f\u044b \u043f\u043e\u00a0\u0431\u043b\u0438\u0437\u043e\u0441\u0442\u0438 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432. \u041e\u043f\u044f\u0442\u044c\u00a0\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0438, \u0430\u00a0\u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438\u00a0\u2014 \u043c\u0435\u0442\u043e\u0434 k\u2011\u0441\u0440\u0435\u0434\u043d\u0438\u0445(k\u2011means) \u0438\u043b\u0438\u00a0\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043d\u0430\u00a0\u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f\u00a0\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441\u00a0\u0448\u0443\u043c\u0430\u043c\u0438 (DBSCAN). \u0414\u043b\u044f\u00a0\u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0431\u043b\u0438\u0437\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0415\u0432\u043a\u043b\u0438\u0434\u043e\u0432\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0438\u0437\u00a0\u043a\u043e\u043b\u043e\u043d\u043a\u0438 feature. <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0447\u0438\u0441\u043b\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u043c\u043d\u0435 \u043d\u0435\u00a0\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0442\u043e \u044f \u0432\u044b\u0431\u0435\u0440\u0443 \u043c\u0435\u0442\u043e\u0434 DBSCAN \u0438 \u043f\u0440\u043e\u0433\u043e\u043d\u044e \u044d\u0442\u043e\u0442 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442\u00a0epsilon \u0447\u0438\u0441\u043b\u0430 \u0433\u0440\u0443\u043f\u043f \u0438 \u0447\u0438\u0441\u043b\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435\u00a0\u043f\u043e\u043f\u0430\u0432\u0448\u0438\u0445 \u0432\u00a0\u0433\u0440\u0443\u043f\u043f\u044b:<\/p>\n<pre><code>eps|clusters|not_in_cluster 0.07529667 0.57529667 1.020228648 1.547526904 2.092822630 2.5122717620 3.0117311778 3.58567605 4.06014562 4.53642760 5.02321574 5.5138972 6.077604 6.551377 7.029265 7.514168 8.01096 8.5454 9.0437 9.5230<\/code><\/pre>\n<p>\u041d\u0430 \u0441\u0432\u043e\u0439 \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0432\u044b\u0431\u0435\u0440\u0443 eps=5.5 \u0438 \u0437\u0430\u043f\u0443\u0449\u0443 Java \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 cluster \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 DBSCAN \u0434\u043b\u044f minPoints=3 \u0438 eps=5.5:<\/p>\n<pre><code class=\"java\">package com.github.isuhorukov;  import com.pgvector.PGvector; import org.apache.commons.math3.ml.clustering.Cluster; import org.apache.commons.math3.ml.clustering.Clusterable; import org.apache.commons.math3.ml.clustering.DBSCANClusterer; import org.apache.commons.math3.ml.distance.EuclideanDistance;  import java.sql.*; import java.util.ArrayList; import java.util.List;  public class Main {     public static void main(String[] args) throws Exception {         try (Connection connection = DriverManager.getConnection(                 System.getenv(\"jdbc_url\"), System.getenv(\"user\"), System.getenv(\"password\"))) {             connection.setAutoCommit(false);             PGvector.addVectorType(connection);             float eps = Float.parseFloat(System.getenv(\"eps\"));             int minPoints = Integer.parseInt(System.getenv(\"minPoints\"));             DBSCANClusterer&lt;Feature> dbscanClusterer = new DBSCANClusterer&lt;>(eps,minPoints,new EuclideanDistance());             List&lt;Feature> features = fetchFeatures(connection,                                                     \"select id,feature from infrastructure_for_children_features\");             List&lt;Cluster&lt;Feature>> cluster = dbscanClusterer.cluster(features);             saveClusters(connection, cluster);         }     }      private static void saveClusters(Connection connection, List&lt;Cluster&lt;Feature>> cluster) throws SQLException {         try (PreparedStatement clusterPs = connection.prepareStatement(              \"update infrastructure_for_children_features set cluster = ? where id = ?\")){             for (int idx = 0; idx &lt; cluster.size(); idx++) {                 List&lt;Feature> featureCluster = cluster.get(idx).getPoints();                 for (Feature feature : featureCluster) {                     clusterPs.setInt(1, idx);                     clusterPs.setInt(2, feature.id);                     clusterPs.addBatch();                 }                 clusterPs.executeBatch();             }             connection.commit();         } catch (Exception e) {             connection.rollback();             throw new RuntimeException(e);         }     }      private static List&lt;Feature> fetchFeatures(Connection connection, String query) {         List&lt;Feature> features = new ArrayList&lt;>();         try (Statement statement = connection.createStatement();              ResultSet resultSet = statement.executeQuery(query))         {             while (resultSet.next()) {                 int id = resultSet.getInt(1);                 float[] feature = ((PGvector) resultSet.getObject(2)).toArray();                 features.add(new Feature(id, feature));             }         } catch (Exception e) {             throw new RuntimeException(e);         }         return features;     }      static class Feature implements Clusterable {         public int id;         public double[] feature;         public Feature(int id, float[] feature) {             this.id = id;             this.feature = new double[feature.length];             for (int i = 0; i &lt; feature.length; i++) {                 this.feature[i] = feature[i];             }         }          @Override         public double[] getPoint() {             return feature;         }     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0443\u0436\u0435\u043d pom.xml \u0434\u043b\u044f maven:<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?> &lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"          xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"          xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\">     &lt;modelVersion>4.0.0&lt;\/modelVersion>      &lt;groupId>com.github.igor-suhorukov&lt;\/groupId>     &lt;artifactId>vectors&lt;\/artifactId>     &lt;version>1.0-SNAPSHOT&lt;\/version>      &lt;properties>         &lt;maven.compiler.source>11&lt;\/maven.compiler.source>         &lt;maven.compiler.target>11&lt;\/maven.compiler.target>         &lt;project.build.sourceEncoding>UTF-8&lt;\/project.build.sourceEncoding>     &lt;\/properties>     &lt;dependencies>         &lt;dependency>             &lt;groupId>org.apache.commons&lt;\/groupId>             &lt;artifactId>commons-math3&lt;\/artifactId>             &lt;version>3.6.1&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>com.pgvector&lt;\/groupId>             &lt;artifactId>pgvector&lt;\/artifactId>             &lt;version>0.1.3&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.postgresql&lt;\/groupId>             &lt;artifactId>postgresql&lt;\/artifactId>             &lt;version>42.6.0&lt;\/version>         &lt;\/dependency>     &lt;\/dependencies> &lt;\/project><\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f URL \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0436\u0438\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0442\u0438\u043f \u0432\u0435\u043a\u0442\u043e\u0440\u0430 <code>PGvector<\/code> \u0432 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u00a0<code>fetchFeatures<\/code>\u00a0\u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u043d\u0430\u043c\u0438 \u0440\u0430\u043d\u0435\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b infrastructure_for_children_features.<\/p>\n<\/li>\n<li>\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u00a0<code>eps<\/code>\u00a0\u0438\u00a0<code>minPoints<\/code>\u00a0\u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0442\u0438\u043f\u044b\u00a0<code>float<\/code>\u00a0\u0438\u00a0<code>int<\/code>\u00a0\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u00a0<code>DBSCANClusterer<\/code>\u00a0\u0438\u0437 commons-math3 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c\u00a0<code>eps<\/code>,\u00a0<code>minPoints<\/code>\u00a0\u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f (<code>EuclideanDistance<\/code>). \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u00a0<code>cluster<\/code>\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u00a0<code>DBSCANClusterer<\/code>\u00a0\u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u043d\u0435\u0435 \u0438\u0437 \u0431\u0430\u0437\u044b \u0432 \u043c\u0435\u0442\u043e\u0434\u0435<code>fetchFeatures<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u00a0<code>saveClusters<\/code>\u00a0\u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u043e\u043b\u0435 cluster \u0442\u0430\u0431\u043b\u0438\u0446\u044b infrastructure_for_children_features, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u043d\u043e\u043c\u0435\u0440 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0438 id \u043a\u0430\u0436\u0434\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u043b\u0438\u0441\u044c, \u0442\u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 &#8212; \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\">\n<div><figcaption>\u0427\u0435\u043c \u0436\u0435 \u043f\u043e\u0445\u043e\u0436\u0438 \u044d\u0442\u0438 \u0440\u0430\u0439\u043e\u043d\u044b, \u0435\u0449\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c \u0438\u043b\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 epsilon<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u0434\u0438\u043d \u0434\u043e\u043c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u0443\u0433\u0430\u0434 \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 <\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u0439\u0434\u0435\u043c \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u043c \u0441\u043e \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430 \u043f\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0443:<\/p>\n<pre><code class=\"sql\">osmworld=# select * from infrastructure_for_children_features where id=831;  id  | cluster |     district      |        street         | housenumber |             feature              -----+---------+-------------+--------------------+-------------------+-----------------------+-------------+---------------------------------  831 |       4 | \u041f\u0440\u0435\u0441\u043d\u0435\u043d\u0441\u043a\u0438\u0439 \u0440\u0430\u0439\u043e\u043d | \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0411\u0440\u043e\u043d\u043d\u0430\u044f \u0443\u043b\u0438\u0446\u0430 | 19          | [37,28,3,23,6,4,17,23,9,148,92] (1 row)<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0432 PostgreSQL \u043d\u0430\u0439\u0434\u0435\u043c 10 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445 \u043a \u043d\u0435\u043c\u0443 \u0434\u043e\u043c\u043e\u0432 \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u0432\u0435\u043a\u0442\u043e\u0440\u0430:<\/p>\n<pre><code class=\"sql\">osm<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-361736","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/361736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=361736"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/361736\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=361736"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=361736"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=361736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}