php版简易中文分词实现 - mysql版本

chinaunix看到“php版简易中文分词实现”,原来的版本使用的是gdbm文本数据库,在php5下面测试老是不通过。今天将字典数据导入mysql,小小改动就可以用了.我觉得,如果要获取更好的性能,可以考虑将所有的词写入一个数组,并且写入内存(如memcache),查询速度应该有很大提高,不过今天没有时间试验了。

在class db_dictionary{}下面几行加入:

PHP:
  1. class db_dict extends db_dictionary {
  2.  
  3.         var $_table = 'dict';
  4.        
  5.         /** 加载词典 (参数: 词典路径) */
  6.         function load($fname) {
  7.                 include_once('DB.php');
  8.                 $this->_dbh = DB::connect($fname);
  9.                 if (DB::isError($this->_dbh))
  10.                 {
  11.                         echo "fail to open the dictionary: $fname <br />" . CRLF;
  12.                         die;
  13.                 }
  14.                 $res = $this->_dbh->query("SET NAMES 'gbk'"); //mysql 4.1以上要这行,否则注释掉
  15.         }
  16.  
  17.         /** 查词 */
  18.         function find($word)
  19.         {
  20.                 if (!DB::isError($this->_dbh))
  21.                 {
  22.                         $this->query_times++;
  23.  
  24.                         // check the cache
  25.                         if ($this->has_cache && isset($this->_cache[$word]))
  26.                                 return $this->_cache[$word];                       
  27.  
  28.                         // query from db
  29.                         $val = (int)$this->_dbh->getOne("SELECT `value`
  30.                         FROM {$this->_table} WHERE `key`=?", array($word) );
  31.  
  32.                         // save to cache
  33.                         if ($this->has_cache)
  34.                                 $this->_cache[$word] = $val;
  35.  
  36.                         return $val;
  37.                 } else {
  38.                         echo "you should load the dictionary file first! <br />" . CRLF;
  39.                         die;
  40.                 }
  41.         }
  42. }

然后修改:

/** 分词类: 逆向最大 (2级复查词频比较) */

PHP:
  1. class cword_segment {
  2. .................................
  3.  
  4.         /** 设定词典 (根据后缀名确定类型) */
  5.         function set_dict($fname)
  6.         {
  7.                 $this->_dict = new db_dict($fname);
  8.         }
  9.  
  10.  
  11. .................................
  12. }

调用的时候:

PHP:
  1. $wp->set_dict('mysql://root@localhost/test');

在win下php5.1.1 +apache 2.0.53测试通过,其中的include_once('DB.php');是调用的Pear::DB

作者: volcano 发表于12月 12, 2005 at 4:58 pm

版权信息: 可以任意转载, 转载时请务必以超链接形式标明文章原始出处作者信息及此声明

Tags:

10 条评论 »

  1. netman 于 2006-02-16 @ 16:29:45 留言

    能不能发一份例中的’DB.php’文件,谢谢。email:uteryod@163.com

  2. volcano 于 2006-02-17 @ 21:16:57 留言

    pear:DB在这里,要安装的
    http://pear.php.net/package/DB

  3. fufay 于 2006-03-27 @ 15:25:58 留言

    能不能发一份导入MYSQL 的字典表格给俺?

  4. volcano 于 2006-03-28 @ 10:03:29 留言

    回去找了一下,原来的数据库因为重装已经找不着了,再想想别的办法

  5. volcano 于 2006-03-28 @ 16:44:23 留言

    找了一下,这是我当是导出sql的脚本,在php5下面跑的,如果你mysql版本在4.1或以上,用下面这段代码还要注意字符集的问题:

    < ?php
    ob_start();
    $db = dba_open("dict.cdb", "r", "cdb");
    if ($key = dba_firstkey($db))
    {
    do {
    $value = dba_fetch($key, $db);
    echo "INSERT INTO dict VALUES ('', '$key', '$value');rn";
    }
    while ($key = dba_nextkey($db));
    }
    dba_close($db);
    file_put_contents('word.sql', ob_get_clean());
    ?>

  6. fufay 于 2006-03-31 @ 13:46:04 留言

    谢谢,我试试看。

  7. citizen 于 2006-08-02 @ 16:01:19 留言

    请给一份 DB.php, THKS

  8. volcano 于 2006-08-02 @ 21:10:08 留言

    请直接用pear的DB.php,我在上面已经回答过了。如果你不了解什么是pear,请搜索一下

  9. bigandy 于 2006-08-21 @ 12:25:24 留言

    关于使用数据库方面,我想,是否可以考虑采用MYSQL HEAP TABLE的方式,在程序第一次启动的时候,检测一下没有这个数据库,那么,就从任意一个cdb,gdbm 或者文本都行,读出字典文件,然后建立mysql的 heap table,这样只要机器不重启,这个table就一直存在,而且字典也就只是占了十几m的内存而已,mysql 的heap table应该是目前所有数据库类型中最快的一个了。

  10. volcano 于 2006-08-21 @ 12:35:15 留言

    你可以测试一下这样做的效率和资源占用情况,个人还是倾向于使用key->value形式的缓存如memcache之类的,会快的多。或者直接使用作者用c写的daemon,比php更是快上了一大截

RSS 为此帖反馈评论 · 反向跟踪 网站

留条评论