使用tf*idf实现对文档集合的检索

本文介绍了一种基于文档内容的检索方法,通过分词、词频统计等步骤计算文档特征向量,并利用余弦相似度来匹配搜索词与文档的相关性。示例展示了如何处理三份文本文件并找出与特定查询词最相关的文档。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

步骤:

  1. 读取三篇文档1.txt,2.txt,3.txt,里边的内容分别为“this is php”,“this is html html”,“this is java”

  2. 分词,并统计词频tf

  3. 计算文档频率df

  4. 计算每篇文档的特征向量

  5. 计算搜索词与文档的夹角余弦值

    <?php
        $_txts = array('1.txt','2.txt','3.txt');
        $_len = count($_txts);
        for ($i = 0;$i < $_len;$i++){
            $_contents[] = file_get_contents($_txts[$i]);   //读取内容
        }
                 
        for ($i = 0;$i < $_len;$i++){
            //分词
            $_words[] = explode(' ',trim($_contents[$i]));
            foreach ($_words[$i] as $_key=>$_value){
                $_value = trim($_value);
                $_value = preg_replace('/[.|,|(|)|-|;]/','',$_value);
                $_words[$i][$_key]=strtolower($_value);
                         
            }
            //统计文档所有词的长度,一般计算tf需要除以这个值,为了简便,本次试验省去这步
            //$_words_count[]=count($_words[$i]);
            //词频tf
            $_tf[] = array_count_values($_words[$i]);
            //去重
            $_words[$i]= array_unique($_words[$i]);
        } 
                 
        //合并
        $_words_com = array_merge($_words[0],$_words[1],$_words[2]);
        //文档频率
        $_df = array_count_values($_words_com);
        //特征向量
        for ($i = 0;$i < $_len;$i++){
            //初始化,与文档频率的维度相同
            $_vsm[$i] = $_df;
            //把每个维度的值设置为0
            foreach($_vsm[$i] as $_key=>$_value){
                $_vsm[$i][$_key] = 0;
            }
            for ($j=0;$j<count($_words[$i]);$j++){
                if (in_array($_words[$i][$j],$_words_com)){
                    $_vsm[$i][($_words[$i][$j])] = ($_tf[$i][($_words[$i][$j])])*(log($_len/$_df[($_words[$i][$j])]));
                             
                } 
            }
        } 
                 
        for($i = 0;$i < count($_vsm); $i++){
            echo '第'.($i+1).'篇文档的特征向量: ('. implode(",",$_vsm[$i]).')<br/>';
        }
                 
        //测试
        $_query = 'java';
        $_vsm_que = $_df;
        foreach($_vsm_que as $_key=>$_value){
            $_vsm_que[$_key] = 0;
        }
        if (in_array($_query,$_vsm_que)){
            $_vsm_que[$_query] = 1;
        }
                 
        for ($i = 0; $i < count($_vsm); $i++){
            foreach($_vsm_que as $_key=>$_value){
                $_sim[$i] += ($_vsm[$i][$_key]) * ($_vsm_que[$_key]);
                $_w1 += pow($_vsm_que[$_key],2);
                $_w2 += pow($_vsm[$i][$_key],2);
            }
            //求夹角余弦值,相似度计算
            $_cos[$i] = $_sim[$i]/(sqrt($_w1)*sqrt($_w2));
            echo '<br/>';
            echo '第'.($i+1).'篇文档的相似度:'.$_cos[$i];
        }
                 
        arsort($_cos);
        foreach($_cos as $_key=>$_value){
            echo '<br/><br/>';
            echo '最符合的结果为第'.($_key+1).'篇文档';
                     
            break;
        }
    ?>

    在浏览器运行的结果:


    第1篇文档的特征向量: (0,0,1.09861228867,0,0)
    第2篇文档的特征向量: (0,0,0,2.19722457734,0)
    第3篇文档的特征向量: (0,0,0,0,1.09861228867)

    第1篇文档的相似度:0
    第2篇文档的相似度:0
    第3篇文档的相似度:0.235702260396

    最符合的结果为第3篇文档


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值