• PHP中文分词的简单实现


    对于中文搜索引擎来说, 中文分词是整个系统最基础的部分之一, 因为目前基于单字的中文搜索算法并不是太好。 当然, 本文不是要对中文搜索引擎做研究, 而是分享如果用 PHP 做一个站内搜索引擎。 本文是这个系统中的一篇。

    我使用的分词工具是中科院计算所的开源版本的 ICTCLAS。 另外还有开源的 Bamboo, 我随后也会对该工具进行调研。

    从 ICTCLAS 出发是个不错的选择, 因为其算法传播比较广泛, 有公开的学术文档, 并且编译简单, 库依赖少。 但目前只提供了 C/C++, Java 和 C# 版本的代码, 并没有 PHP 版本的代码。 怎么办呢? 也许可以学习它的 C/C++ 源码和学术文档中, 然后再开发一个 PHP 版本出来。 不过, 我要使用进程间通信, 在 PHP 代码里调用 C/C++ 版本的可执行文件。

    下载源码解压后, 在有 C++ 开发库和编译环境的机器上直接 make ictclas 即可。 它的 Makefile 脚本有个错误, 执行测试的代码没有加上'。/', 当然不能像 Windows 下执行成功了。 但也不影响编译结果。

    进行中文分词的 PHP 类就在下面了, 用 proc_open() 函数来执行分词程序, 并通过管道和其交互, 输入要进行分词的文本, 读取分词结果。

    <?php
    class NLP{
        private static $cmd_path;
    
        // 不以'/'结尾
        static function set_cmd_path($path){
            self::$cmd_path = $path;
        }
    
        private function cmd($str){
            $descriptorspec = array(
               0 => array("pipe", "r"),
               1 => array("pipe", "w"),
            );
            $cmd = self::$cmd_path . "/ictclas";
            $process = proc_open($cmd, $descriptorspec, $pipes);
    
            if (is_resource($process)) {
                $str = iconv('utf-8', 'gbk', $str);
                fwrite($pipes[0], $str);
                $output = stream_get_contents($pipes[1]);
    
                fclose($pipes[0]);
                fclose($pipes[1]);
    
                $return_value = proc_close($process);
            }
    
            /*
            $cmd = "printf '$input' | " . self::$cmd_path . "/ictclas";
            exec($cmd, $output, $ret);
            $output = join("
    ", $output);
            */
    
            $output = trim($output);
            $output = iconv('gbk', 'utf-8', $output);
    
            return $output;
        }
    
        /**
         * 进行分词, 返回词语列表.
         */
        function tokenize($str){
            $tokens = array();
    
            $output = self::cmd($input);
            if($output){
                $ps = preg_split('/s+/', $output);
                foreach($ps as $p){
                    list($seg, $tag) = explode('/', $p);
                    $item = array(
                        'seg' => $seg,
                        'tag' => $tag,
                        );
                    $tokens[] = $item;
                }
            }
    
            return $tokens;
        }
    }
    NLP::set_cmd_path(dirname(__FILE__));
    ?>
    

      使用起来很简单(确保 ICTCLAS 编译后的可执行文件和词典在当前目录):

    <?php
    require_once('NLP.php');
    var_dump(NLP::tokenize('Hello, World!'));
    ?>

  • 相关阅读:
    bzoj 5092: [Lydsy1711月赛]分割序列
    bzoj1173: [Balkan2007]Point
    bzoj1536: [POI2005]Akc- Special Forces Manoeuvres
    bzoj2178: 圆的面积并
    bzoj1043 下落的圆盘
    bzoj2674 Attack
    bzoj1201: [HNOI2005]数三角形
    bzoj3135: [Baltic2013]pipesd
    bzoj1760 [Baltic2009]Triangulation
    bzoj3136
  • 原文地址:https://www.cnblogs.com/fyy-888/p/5103674.html
Copyright © 2020-2023  润新知