使用Sql计算TF-IDF

时间:2010-07-31 09:41:50

标签: sql sql-server-2008 tf-idf

我的数据库中有一个包含自由文本字段列的表。

我想知道每个单词出现在所有行上的频率,或者甚至可能为所有单词计算TF-IDF,其中我的文档是每行的字段值。

是否可以使用Sql Query来计算?如果没有或有更简单的方法,请指导我吗?

非常感谢,

乔恩

2 个答案:

答案 0 :(得分:7)

在SQL Server 2008中,根据您的需要,您可以对列应用全文索引,然后查询sys.dm_fts_index_keywordssys.dm_fts_index_keywords_by_document table valued functions以获取发生次数。

编辑实际上即使没有创建持久性全文索引,您仍然可以利用解析器

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

答案 1 :(得分:2)

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))(取自here):

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