PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

PostgreSQL, триграми и подобие

Концепцията за сходство на триграмите разчита на това, че всяко изречение е разделено на „триграми“ (последователности от три последователни букви) и третирането на резултата като SET (т.е.:редът няма значение и нямате повтарящи се стойности). Преди да се разгледа изречението, две празни интервали се добавят в началото и един в края, а единичните интервали се заменят с двойни.

Триграми са специален случай на N-грами .

Комплектът триграми, съответстващ на "Chateau blanc", се намира чрез намиране на всички последователности от три букви, които се появяват върху него:

  chateau  blanc
---                 => '  c'
 ---                => ' ch'
  ---               => 'cha'
   ---              => 'hat'
    ---             => 'ate'
     ---            => 'tea'
      ---           => 'eau'
       ---          => 'au '
        ---         => 'u  '
         ---        => '  b'
          ---       => ' bl'
           ---      => 'bla'
            ---     => 'lan'
             ---    => 'anc'
              ---   => 'nc '

Сортирането им и премахването на повторения ви осигурява:

'  b'
'  c'
' bl'
' ch'
'anc'
'ate'
'au '
'bla'
'cha'
'eau'
'hat'
'lan'
'nc '
'tea'

Това може да бъде изчислено от PostgreSQL с помощта на функцията show_trgm :

SELECT show_trgm('Chateau blanc') AS A

A = [  b,  c, bl, ch,anc,ate,au ,bla,cha,eau,hat,lan,nc ,tea]

... който има 14 триграми. (Проверете pg_trgm ).

И комплектът триграми, съответстващ на "Chateau Cheval Blanc" е:

SELECT show_trgm('Chateau Cheval Blanc') AS B 

B = [  b,  c, bl, ch,anc,ate,au ,bla,cha,che,eau,evl,hat,hev,la ,lan,nc ,tea,vla]

... който има 19 триграми

Ако преброите колко триграми имат и двата набора, ще откриете, че те имат следните:

A intersect B = 
    [  b,  c, bl, ch,anc,ate,au ,bla,cha,eau,hat,lan,nc ,tea]

и тези, които имат общо са:

A union B = 
    [  b,  c, bl, ch,anc,ate,au ,bla,cha,che,eau,evl,hat,hev,la ,lan,nc ,tea,vla]

Тоест двете изречения имат 14 общи триграми и общо 19.
Сходството се изчислява като:

 similarity = 14 / 19

Можете да го проверите с:

SELECT 
    cast(14.0/19.0 as real) AS computed_result, 
    similarity('Chateau blanc', 'chateau cheval blanc') AS function_in_pg

и ще видите, че получавате:0.736842

... което обяснявакак сходството се изчислява и защо получавате стойностите, които получавате.

ЗАБЕЛЕЖКА:Можете да изчислите пресечната точка и обединението с помощта на:

SELECT 
   array_agg(t) AS in_common
FROM
(
    SELECT unnest(show_trgm('Chateau blanc')) AS t 
    INTERSECT 
    SELECT unnest(show_trgm('chateau chevla blanc')) AS t
    ORDER BY t
) AS trigrams_in_common ;

SELECT 
   array_agg(t) AS in_total
FROM
(
    SELECT unnest(show_trgm('Chateau blanc')) AS t 
    UNION 
    SELECT unnest(show_trgm('chateau chevla blanc')) AS t
) AS trigrams_in_total ;

И това е начин да изследвате сходството на различни двойки изречения:

WITH p AS
(
    SELECT 
      'This is just a sentence I''ve invented'::text AS f1,
      'This is just a sentence I''ve also invented'::text AS f2
),
t1 AS
(
    SELECT unnest(show_trgm(f1)) FROM p
),
t2 AS
(
    SELECT unnest(show_trgm(f2)) FROM p
),
x AS
(
    SELECT
        (SELECT count(*) FROM 
            (SELECT * FROM t1 INTERSECT SELECT * FROM t2) AS s0)::integer AS same,
        (SELECT count(*) FROM 
            (SELECT * FROM t1 UNION     SELECT * FROM t2) AS s0)::integer AS total,
        similarity(f1, f2) AS sim_2
FROM
    p 
)
SELECT
    same, total, same::real/total::real AS sim_1, sim_2
FROM
    x ;

Можете да го проверите на Rextester



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Преглед на различните методи за сканиране в PostgreSQL

  2. Как да изчислим ненадут брой от денормализирана таблица

  3. Най-добра практика за създаване на SQL SELECT заявки при обработка на потенциални недефинирани стойности

  4. Разгръщане и поддръжка на PostgreSQL с Ansible

  5. последователни дни в sql