Heim  >  Artikel  >  Backend-Entwicklung  >  Thinkphp 3.2 中词分词 加权搜寻

Thinkphp 3.2 中词分词 加权搜寻

WBOY
WBOYOriginal
2016-06-13 12:21:051282Durchsuche

Thinkphp 3.2 中词分词 加权搜索

 原文地址:http://www.cnblogs.com/kekukele/p/4544349.html

 前段时间,利用业余时间做了一个磁力搜索的网站Btdog,其中使用到了简单的中文分词与加权搜索,在这里分享给大家,供大家参考。

  在我的网站中,中文分词使用的是SCWS分词系统,这个分词系统提供PHP两种使用方式:一种是你可以采用源码安装,具体安装步骤请参考这里;

另外一种是使用其提供的API接口,具体方法参考这里。

  下面,我们假设你已经掌握了SCWS的使用,事实上,其使用也非常简单,若你不会其使用,也不影响本文下面的阅读。 

  SCWS系统中其每个分好的词包括以下属性/键值:

  1. word 词的内容
  2. off 该词在未分词文本中的偏移位置
  3. idf 该词的 IDF 值
  4. attr 词性 (北大标注格式) 参见这里。

  在这里我们重点介绍下分词属性中的idf,这个是我们在我们的分词算法中需要用到的。

  IDF全称inverse document frequency(逆向文档频率)是一个词普遍重要性的度量,某一特定词的IDF值,用总文件数除以包含该词的文章数量,再将得到的商取对数(log)。计算公式:IDF = log(D/Dt),D为文章总数,Dt为该词出现的文章数量。IDF的主要思想是:如果包含词条t的文档越少,也就是Dt越小,IDF越大,则说明词条t具有很好的类别区分能力。

  我们举例说明下,如 搜索内容 ”复仇者的联盟“,其SCWS的分词结果如下:

 

  可以看出,其分词结果中,关键词”复仇者“的idf为9.06,最具区分能力,而关键词”的“的idf值为0,基本没有区分能力,”联盟“的idf为4.34也具有较强的区别能力。因此,我们在我们的分词搜索中,可以简单地使用idf值作为加权排序的依据。

  在scws分词系统中,其idf的取值为0-10,因此在我们下面给出的算法中,我们把内容全文匹配的权重设为10,即最大。其他分词后关键词的权重值设为其idf值,然后根据权重大小将结果逆序排列。这要我们就实现了简单的中文分词加权排序。核心代码具体如下: 

<em id="__mceDel"><em id="__mceDel"> [email protected]:需要分词的内容<em id="__mceDel">    <br>//Return:mysql查询条件字符串,加权排序字符串,关键词</em>   <br> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> split_words(<span style="color: #800080;">$text</span><span style="color: #000000;">){        </span><span style="color: #800080;">$split_words</span> =<span style="color: #000000;"> scws_new();        </span><span style="color: #800080;">$split_words</span>->set_charset('utf-8'<span style="color: #000000;">);        </span><span style="color: #800080;">$split_words</span>->set_ignore(<span style="color: #0000ff;">true</span><span style="color: #000000;">);        </span><span style="color: #800080;">$split_words</span>->set_dict('/usr/local/scws/etc/dict.utf8.xdb'<span style="color: #000000;">);        </span><span style="color: #800080;">$split_words</span>->set_rule('/usr/local/scws/etc/rules.utf8.ini'<span style="color: #000000;">);        </span><span style="color: #800080;">$split_words</span>->send_text(<span style="color: #800080;">$text</span><span style="color: #000000;">);        </span><span style="color: #800080;">$weight</span>=10<span style="color: #000000;">;        </span><span style="color: #800080;">$condition</span>['where'] = "name LIKE '%".<span style="color: #800080;">$text</span>."%'"<span style="color: #000000;">;        </span><span style="color: #800080;">$condition</span>['order'] = "(CASE WHEN name LIKE '%".<span style="color: #800080;">$text</span>."%' THEN <span style="color: #800080;">$weight</span> ELSE 0 END)"<span style="color: #000000;">;  //设置全文匹配最大权重</span>        <span style="color: #0000ff;">while</span> (<span style="color: #800080;">$words_result</span> = <span style="color: #800080;">$split_words</span>-><span style="color: #000000;">get_result())        {            </span><span style="color: #0000ff;">foreach</span>(<span style="color: #800080;">$words_result</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$word_arr</span><span style="color: #000000;">){</span>                    <span style="color: #800080;">$condition</span>['where'] .= " OR name LIKE '%".<span style="color: #800080;">$word_arr</span>['word']."%'"<span style="color: #000000;">;<br>            //设置分词后关键词的权重为其idf的值<br></span>                    <span style="color: #800080;">$condition</span>['order'] .= " + (CASE WHEN name LIKE '%".<span style="color: #800080;">$word_arr</span>['word']."%' THEN ".<span style="color: #800080;">$word_arr</span>['idf']." ELSE 0 END)"<span style="color: #000000;">; </span>                <span style="color: #800080;">$condition</span>['keywords'][<span style="color: #800080;">$cnt</span>++] = <span style="color: #800080;">$word_arr</span>['word'<span style="color: #000000;">];            }        }        </span><span style="color: #800080;">$split_words</span>-><span style="color: #000000;">close();        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$condition</span><span style="color: #000000;">;    }</span></em></em>

  当然,更复杂的分词还要考虑词的词频TF,不过即使简单的这样,我们也基本能达到比较好的效果了,具体效果,大家可以到http://btdog.com.cn体验下。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn