powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Подбор ключевых слов к тексту
22 сообщений из 22, страница 1 из 1
Подбор ключевых слов к тексту
    #36405030
SELECT *
FROM fts_tbl
WHERE to_tsvector (column) @@ to_tsquery ('language','Text')

ищет все вхождения 'Text' в fts_tbl

а как сделать наоборот: поиск всех вхождений ключевых слов (из справочной таблицы) в заданный текст?

Т.е. нужно подобрать ключевые слова к тесту из справочной таблицы
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405052
Конкретно: меня интересуют операции сравнения двух векторов to_tsvector
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405090
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мигратор данныхТ.е. нужно подобрать ключевые слова к тесту из справочной таблицыСлова же у Вас уже есть в тексте, зачем их подбирать ? Может быть Вы хотели спросить «как получить основную словоформу для каждого слова заданного текста» ?
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405096
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мигратор данныхКонкретно: меня интересуют операции сравнения двух векторов to_tsvector
Код: plaintext
1.
2.
3.
4.
select to_tsvector('купили ёлку на ёлочном базаре') = to_tsvector('на базаре ёлочном была куплена ёлка');
 ?column?
----------
 f
Вы хотите что бы тут было true ? :)
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405128
Ёш,

Таблица тегов (ключевых слов):
Школа
Вечер
Утро

Текст: Посещение школы вечером

Автоматически подобранные теги:
Школа
Вечер

Сейчас у меня тупо ищет для каждой строки из таблицы тегов вхождение в искомый текст.

Недостатки:
низкая скорость
ложные срабатывания - отсутствует разбор на слова/лексемы

П.С. Текст сам не на русском - ангийский, немецкий.
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405134
для русского языка тупой поиск вхожения вообще не подходит - нужно обязательно обрезать окончания.
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405229
sourcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну тут по моему очевидно что вам надо взять текст, разбить его по словам и сделать выборку с помощью ts_query в справочную таблицу по каждому из слов текста. :) ну а как это оптимизировать это уже дело техники
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405274
Oleg Bartunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мигратор данных,

значит вам нужен результат пересечения двух стрипнутых векторов. Такой функции нет, но вы можете написать ее сами. Чтобы быстро вытаскивать слова со статистикой вам понадобится функция

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
CREATE OR REPLACE FUNCTION ts_stat(tsvector, weights text, OUT word text, OUT ndoc
integer, OUT nentry integer)
RETURNS SETOF record AS
$$
    SELECT ts_stat('SELECT ' || quote_literal( $ 1 ::text ) || '::tsvector', quote_literal( $ 2 ::text) );
$$ LANGUAGE SQL RETURNS NULL ON NULL INPUT IMMUTABLE;


Использование ее для получения массива из tsvectora paper.fts

Код: plaintext
1.
2.
select ARRAY ( select (ts_stat(fts,'*')).word from papers where id= 2 );


Дальше напишите (и поделитесь со всеми) функцией которая сравнивает два сортированных списка.
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405285
Почти решение:

SELECT tg.tag
FROM tags tg
WHERE
to_tsvector('russian', tg.tag) @@ plainto_tsquery('russian', 'Учителю русского языка')

нужно только в plainto_tsquery AND заменить на OR.
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405330
помогите решить:
>в plainto_tsquery AND заменить на OR.

это не работает:
to_tsvector('russian', tg.tag) @@ replace (plainto_tsquery('russian', 'Учителю русского языка'), '&', '|')
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405343
http://www.mail-archive.com/pgsql-general@postgresql.org/msg102694.html]Решение последнего вопроса:

Код: plaintext
1.
2.
3.
CREATE OR REPLACE FUNCTION plainto_or_tsquery (TEXT) RETURNS tsquery AS $$
  SELECT to_tsquery( regexp_replace( $ 1 , E'[\\s\'|:&()!]+','|','g') );
$$ LANGUAGE SQL STRICT IMMUTABLE;
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405522
или проще:

SELECT replace (plainto_tsquery('russian', 'Учителю русского языка')::text, '&', '|')::tsquery
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36405707
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мигратор данных, что-то я Вас не пойму, а какая разница что с чем сравнивать ? теги с текстом или текст с тегами ? Почему Вас не устраивает обычный join и зачем Вы текст в tsquery преобразуете ? проще же тег в tsquery, а текст в tsvector.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create table tags (id serial, v text, ts tsquery);
create table texts (id serial, v text, ts tsvector);
insert into tags (v) values ('школа'), ('вечер'), ('утро'), ('учитель');
insert into texts (v) values ('Посещение школы вечером');
insert into texts (v) values ('Учителю русского языка');
update tags set ts = plainto_tsquery(v);
update texts set ts = to_tsvector(v);
create index texts_fts_indx on texts using gin (ts);

select texts.v, array_agg(tags.v) from texts join tags on texts.ts @@ tags.ts group by texts.v;
            v            |   array_agg
-------------------------+---------------
 Посещение школы вечером | {школа,вечер}
 Учителю русского языка  | {учитель}
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36406560
Oleg Bartunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёш,

очень интересное решение, но у меня вот разыгрался аппетит.
1. Как найти 10 ближайших похожих текстов для данного текста
2. Как найти 10 самых похожих текстов

Похожесть считать как w1 && w2/ (w1 U w2)
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36406842
>Ёш

огромное спасибо за скорректированный алгоритм!

это решение есть идеальное.
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36407246
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg Bartunov1. Как найти 10 ближайших похожих текстов для данного текстадля каждого текста сделать массив словоформ, отфильтровать по пересечению с массивом словоформ данного текста (... where words && nwords('данный текст')) и отсортировать по похожести

Oleg Bartunov2. Как найти 10 самых похожих текстовможно через cross join только там будет в два раза больше из-за повторов «A похоже на Б» и «Б похоже на А»

Oleg BartunovПохожесть считать как w1 && w2/ (w1 U w2)количество общих слов разделить на общее количество слов ?
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36407747
Oleg Bartunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg Bartunov1. Как найти 10 ближайших похожих текстов для данного текста
Ёшдля каждого текста сделать массив словоформ, отфильтровать по пересечению с массивом словоформ данного текста (... where words && nwords('данный текст')) и отсортировать по похожести
[/quot Ёш]
Да, можно просто взять массив из tsvector-а, как я приводил выше.

[quot Oleg Bartunov]2. Как найти 10 самых похожих текстов
Ёшможно через cross join только там будет в два раза больше из-за повторов «A похоже на Б» и «Б похоже на А»
[/quot Ёш]

ну, это легко фильтруется "tab1.id ne tab2.id" или просто взять диагональную матрицу "tab1.id > tab2.id"

[quot Oleg Bartunov]Похожесть считать как w1 && w2/ (w1 U w2)
Ёш
количество общих слов разделить на общее количество слов ?
Да, пересечение делить на объединение, Jaccard. Но это не принципиально, это как раз предмет исследования.
Меня просто давно такая идея преследует, в постгресе найти простой способ поиска похожих документов,
но сил и времени нет.
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36417809
вот еще очень серьезная задача:

предположим теги выбираются на базе ts_vector из нескольких полей

иногда подбираются слишком много тегов.

как более-менее правильно убрать лишние теги?

у нас есть только функцуия ts_rank_cd.
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36431443
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #36431936
решил проблему "похожести" по другому:

кандидаты на дубли нужно выбирать условием:

plainto_tsquery ('Hello, our World World') <@ plainto_tsquery ('Hello, our worndefull World!'),
length(to_tsvector ('Hello, our World World')) - length(to_tsvector ('Hello, our worndefull World!'));

первое выражение должно быть true
второе - по модулю накладываем ограничение <=1,2 или 3 - как много значимых слов можно добавить в исходный текст, чтобы его все еще считать дубликатом

Например:

Приглашение на концерт
Приглашение на большой симфонический концерт

Но разные:
Красная машина
Красный домик

по моему вложение гораздо адекватней пересечения
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Подбор ключевых слов к тексту
    #39557071
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sourcerНу тут по моему очевидно что вам надо взять текст, разбить его по словам и сделать выборку с помощью ts_query в справочную таблицу по каждому из слов текста. :) ну а как это оптимизировать это уже дело техники

вот мне аккурат нужно это--ссамое "дело техники"

только теги не простые слова, а "ключевые" -- 2---3--4 слова . часто с токенами, отбрасываемыми стандартными словарями (сплошь 12 токен "A[1:1]")

взять пару килобайт текста, и последовательно запрыгивать на него своей ф--ей гибкого совпадения последовательностей токенов позаписно из таблички в 30--50МБ ключевых -- дорого. нужен предфильтр какойта. (у меня -- гин--индексы по массиву дистинктных лексем "ключевого" после спеллера. проверяется наличие всех токенов(кастрированных спеллером) ключевого в тексте. медленно. даже если забить на точность).

хочется удобств типа "Ахо-Корасика" и иже с ними("Рабина — Карпа"). оно же наверняка на уровне обращения к словарям при лексемайзинге и реализовано. а вот то же самое -- но к табличке -- и не в С а чтобы концы торчали в SQL -- было бы интересно.

ну и если у кого идеи есть сбора на коленке из овна и палок -- велкам.
...
Рейтинг: 0 / 0
Подбор ключевых слов к тексту
    #39558279
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
продолжу постановку:

есть дорогая ф--я проверки "кейворда" в теле текста(ов).
есть таблица кейвордов.
я "индексирую" тексты , отыскивая совпадения. допустимы небольшие потери.
проверить 100000 кейвордов дорогой ф--ей дорого.
нужна дешовая предфильтрация.
я её делаю выделив массив дистинктных токенов в "кейворде" и в "тексте" . выделяю спелл-овским словарем. возможны небольшие потери из-за разного стемминга разных словоформ.

основные потери времени -- на 2. речек довольно дорогой ф--ей выделения массива. и 1. -- на речек основной ф--ей проверки вхождения.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
  CTE jn
    ->  Nested Loop  (cost=27.02..692876.20 rows=479997 width=89) (actual time=48.524..664771.377 rows=119324 loops=1)
          Buffers: shared hit=5984023 read=152
          ->  CTE Scan on prjdat  (cost=0.00..17.90 rows=895 width=72) (actual time=1.033..1127.682 rows=1150 loops=1)
                Buffers: shared hit=12462
          ->  Bitmap Heap Scan on fok_keywords k1  (cost=27.02..768.78 rows=536 width=49) (actual time=57.808..577.039 rows=104 loops=1150)
                Recheck Cond: ((lexize_trim_to_uniq_array(keyword) <@ prjdat.av_tokens) AND (cardinality(fok_codes_wghts) <= 37))
                Rows Removed by Index Recheck: 13424
                Heap Blocks: exact=5415056
                Buffers: shared hit=5971561 read=152
                ->  Bitmap Index Scan on fok_keywords_lexize_trim_to_uniq_array_cardinality_keyword_idx  (cost=0.00..26.89 rows=536 width=0) (actual time=26.935..26.935 rows=13528 loops=1150)
                      Index Cond: ((lexize_trim_to_uniq_array(keyword) <@ prjdat.av_tokens) AND (cardinality(fok_codes_wghts) <= 37))
                      Buffers: shared hit=556505 read=152
  ->  Nested Loop  (cost=7.50..20407.37 rows=479997 width=48) (actual time=1756.383..1345239.164 rows=11532 loops=1)
        Buffers: shared hit=6310560 read=152, temp written=8701
        ->  CTE Scan on jn  (cost=0.00..9599.94 rows=479997 width=72) (actual time=48.530..664974.568 rows=119324 loops=1)
              Buffers: shared hit=5984023 read=152, temp written=8701
        ->  Function Scan on find_keyword_hunsp fk  (cost=7.50..7.51 rows=1 width=8) (actual time=5.700..5.700 rows=0 loops=119324)
              Filter: (fk > '0'::double precision)
              Rows Removed by Filter: 1
              Buffers: shared hit=326537
Planning time: 2.666 ms
Execution time: 1345276.880 ms



2-е снимается материализацией поля.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
  CTE jn
    ->  Nested Loop  (cost=11.02..84169.39 rows=479997 width=89) (actual time=49.888..131849.918 rows=119324 loops=1)
          Buffers: shared hit=8202201 read=8835 written=1144
          ->  CTE Scan on prjdat  (cost=0.00..17.90 rows=895 width=72) (actual time=18.886..5731.687 rows=1150 loops=1)
                Buffers: shared hit=11864 read=598 written=1
          ->  Bitmap Heap Scan on fok_keywords k1  (cost=11.02..88.66 rows=536 width=124) (actual time=66.897..109.631 rows=104 loops=1150)
                Recheck Cond: (kw_tokens <@ prjdat.av_tokens)
                Rows Removed by Index Recheck: 28715
                Filter: (cardinality(fok_codes_wghts) <= 37)
                Rows Removed by Filter: 108
                Heap Blocks: exact=7677353
                Buffers: shared hit=8190337 read=8237 written=1143
                ->  Bitmap Index Scan on fok_keywords_kw_tokens_idx  (cost=0.00..10.89 rows=872 width=0) (actual time=38.387..38.387 rows=28927 loops=1150)
                      Index Cond: (kw_tokens <@ prjdat.av_tokens)
                      Buffers: shared hit=454446 read=13 written=2
  ->  Nested Loop  (cost=7.50..20407.37 rows=479997 width=48) (actual time=620.177..809146.403 rows=11532 loops=1)
        Buffers: shared hit=8528738 read=8835 written=1144, temp written=8701
        ->  CTE Scan on jn  (cost=0.00..9599.94 rows=479997 width=72) (actual time=49.895..132060.603 rows=119324 loops=1)
              Buffers: shared hit=8202201 read=8835 written=1144, temp written=8701
        ->  Function Scan on find_keyword_hunsp fk  (cost=7.50..7.51 rows=1 width=8) (actual time=5.673..5.673 rows=0 loops=119324)
              Filter: (fk > '0'::double precision)
              Rows Removed by Filter: 1
              Buffers: shared hit=326537
Planning time: 2.610 ms
Execution time: 809179.745 ms



1-е требует улучшения способа преобразования текста и кейворда (желательно еще -- с уменьшением потерь), служащих для предфильтрации.
добавил в массивы все последовательные пары
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
  CTE jn
    ->  Nested Loop  (cost=15.37..105543.42 rows=483331 width=89) (actual time=65.591..308701.015 rows=20728 loops=1)
          Buffers: shared hit=10207597 read=14797 written=1972
          ->  CTE Scan on prjdat  (cost=0.00..17.90 rows=895 width=72) (actual time=2.001..1858.651 rows=1150 loops=1)
                Buffers: shared hit=11874 read=600 written=3
          ->  Bitmap Heap Scan on fok_keywords k1  (cost=15.37..112.51 rows=540 width=187) (actual time=178.421..266.807 rows=18 loops=1150)
                Recheck Cond: (kw_tokens <@ prjdat.av_tokens)
                Rows Removed by Index Recheck: 29917
                Filter: (cardinality(fok_codes_wghts) <= 37)
                Rows Removed by Filter: 56
                Heap Blocks: exact=9052124
                Buffers: shared hit=10195723 read=14197 written=1969
                ->  Bitmap Index Scan on fok_keywords_kw_tokens_idx  (cost=0.00..15.24 rows=872 width=0) (actual time=107.563..107.563 rows=29992 loops=1150)
                      Index Cond: (kw_tokens <@ prjdat.av_tokens)
                      Buffers: shared hit=1096942 read=15 written=4
  ->  Nested Loop  (cost=7.50..20549.07 rows=483331 width=48) (actual time=508.131..403618.232 rows=12185 loops=1)
        Buffers: shared hit=10253288 read=14797 written=1972
        ->  CTE Scan on jn  (cost=0.00..9666.62 rows=483331 width=72) (actual time=65.595..308725.633 rows=20728 loops=1)
              Buffers: shared hit=10207597 read=14797 written=1972
        ->  Function Scan on find_keyword_hunsp fk  (cost=7.50..7.51 rows=1 width=8) (actual time=4.577..4.577 rows=1 loops=20728)
              Filter: (fk > '0'::double precision)
              Rows Removed by Filter: 0
              Buffers: shared hit=45691
Planning time: 3.871 ms
Execution time: 403644.954 ms


выигрыш гулькин -- 3-ка со всего, плюс чуть потери снял.

откуда мораль -- нужно дешевое для 1. сравнения, 2 хранения (и/или для речека) преобразование[ия -- если разные] текста и "кейвордов", для предусекновения пр--ва "точного" перебора.


есть ли какие--то готовые подходы ? могабыть в триграмках что--то ? или комбинаторику записать не в длинных лексемах, а в подстановке какой ? нет ?
принимаю любые идеи

а то я пока слепил страшненького горбатенького примерно так :
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
--DROP FUNCTION lexize_uniq_array2 (in txt text);
CREATE OR REPLACE FUNCTION lexize_uniq_array2 (in txt text)
returns text[]
AS 
$x$
--var without 12
SELECT ARRAY_AGG(trim(u) ORDER BY u)FILTER(WHERE trim(u)<>'') FROM (

select string_to_array(
	regexp_replace(string_agg(lexeme,'' order by o),'[\.,\|;:] ',' ','ig') --cut potential separators
	,' ') arr
FROM (
SELECT 
	o::int,tokid,token
	,case tokid when 12 then ' ' else (ts_lexize('russian_all_stem',token))[1] -- стеммер, т.к. нужно попасть в любые словоформы => симпл не подойдет
		-- если ханспелл -- придется собирать все варианты дублей. пока отложим
	end as lexeme
FROM ts_parse('default',regexp_replace(txt,'[\s'||chr(160)||']+',' ','ig')) with ordinality ot (tokid,token,o)
where tokid not in (15,5) -- out twice -- as own and as parts
order by o) tokenz
) foo 
,lateral (with u AS (SELECT * FROM unnest(arr) with ordinality AS u(u,o))
			SELECT concat (v.u,' ',w.u) FROM u as v join u as w ON v.o+1 = w.o
					UNION
					SELECT u FROM u
			
		) u(u)
;
$x$
immutable strict
language sql
COST 1000
;

...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Подбор ключевых слов к тексту
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]