Рассчитать TF-IDF, используя Sql - PullRequest
6 голосов
/ 31 июля 2010

В моей БД есть таблица, содержащая столбец свободного текстового поля.

Я хотел бы знать частоту появления каждого слова во всех строках или, может быть, даже рассчитать TF-IDF для всех слов, где мои документы представляют собой значения этого поля в строке.

Можно ли рассчитать это, используя Sql Query? если нет или есть более простой способ, пожалуйста, направьте меня к нему?

Большое спасибо,

Jon

Ответы [ 2 ]

7 голосов
/ 31 июля 2010

В SQL Server 2008, в зависимости от ваших потребностей, вы можете применить полнотекстовое индексирование к столбцу, а затем запросить sys.dm_fts_index_keywords и sys.dm_fts_index_keywords_by_document табличные функции , чтобы получить число вхождений.

Редактировать: На самом деле даже без создания постоянного полнотекстового индекса вы все равно можете использовать синтаксический анализатор

WITH testTable AS
(
SELECT 1 AS Id, N'how now brown cow' AS txt UNION ALL
SELECT 2, N'she sells sea shells upon the sea shore' UNION ALL
SELECT 3, N'red lorry yellow lorry' UNION ALL
SELECT 4, N'the quick brown fox jumped over the lazy dog'
)

SELECT display_term, COUNT(*) As Cnt
FROM testTable
CROSS APPLY sys.dm_fts_parser('"' + REPLACE(txt,'"','""') + '"', 1033, 0,0)
WHERE TXT IS NOT NULL
GROUP BY display_term
HAVING COUNT(*) > 1
ORDER BY Cnt DESC

Возвращает

display_term                   Cnt
------------------------------ -----------
the                            3
brown                          2
lorry                          2
sea                            2
2 голосов
/ 31 июля 2010

Решение для SQL Server 2008:

вот таблица:

CREATE TABLE MyTable (id INT, txt VARCHAR(MAX));

вот SQL-запрос:

SELECT sum(case when TSplitted.txt_word = 'searched' then 1 else 0 end) as cnt_searched
     , count(*) as cnt_all
FROM MyTable MYT 
INNER JOIN Fn_Split(MYT.id,' ',MYT.txt) TSplitted on MYT.id=TSplitted.id

здесь есть табличная функция Fn_Split (@id int, @separator VARCHAR (32), @string VARCHAR (MAX)) (взято из здесь ):

CREATE FUNCTION Fn_Split (@id int, @separator VARCHAR(32), @string VARCHAR(MAX))

RETURNS @t TABLE
    (
        ret_id INT
       ,txt_word VARCHAR(MAX)
    )   
AS
    BEGIN
        DECLARE @xml XML
        SET @XML = N'<root><r>' + REPLACE(@s, @separator, '</r><r>') + '</r></root>'

        INSERT INTO @t(ret_id, val)
        SELECT @id, r.value('.','VARCHAR(5)') as Item
        FROM @xml.nodes('//root/r') AS RECORDS(r)

        RETURN
    END
...