SCWS-1.2.3高效分词组件

发布时间:2019-07-28 17:40:01编辑:丝画阁阅读(1216)

环境: 
CentOS7.0 64bit
Web环境为LNMP

基于yum扩展源remi安装的Php7.0(php70-php-fpm)和Php5.5(php55-php-fpm)两PHP版本共存环境(需要了解如何安装共存环境的将另外发布攻略)



一、工具本身的安装

1、在官方网站下载SCWS 中文分词(http://www.xunsearch.com/scws/download.php
Linux系的系统直接用下面的命令操作(本人用的是CentOS7 64bit):
wget http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2
2、 解开压缩包
[root@AY8152859Z ~]# tar xvjf scws-1.2.3.tar.bz2

3、 进入目录执行配置脚本和编译
[root@AY8152859Z ~]# cd scws-1.2.3[hightman@d1 ~/scws-1.2.3]$ ./configure --prefix=/usr/local/scws ; make ; make install





注:这里和通用的 GNU 软件安装方式一样,具体选项参数执行 ./configure --help 查看。
常用选项为:--prefix=<scws的安装目录>

4、 顺利的话已经编译并安装成功到 /usr/local/scws 中了,执行下面命令看看文件是否存在
[root@AY8152859Z ~]# ls -al /usr/local/scws/lib/libscws.la
5、 试试执行 scws-cli 文件看有没有返回正确的信息





6、用 wget 下载并解压词典,或从主页下载然后自行解压再将 *.xdb 放入 /usr/local/scws/etc 目录中




首先,让我们来了解下官方在安装前的准备工作中模糊提到的几个概念吧:

autoconf:
是一个shell脚本的工具,可以自动地配置软件源代码包以适应多种UNIX类系统。由autoconf生成的配置脚本在运行的时候不需要用户的手工干预;通常它们甚至不需要手工给出参数以确定系统的类型。其中autoconf需要用到m4,便于生成脚本。
版本检测:


automake:
是一个从文件Makefile.am自动生成Makefile.in的工具。每个Makefile.am基本上是一系列make的宏定义。生成的Makefile.in,服从GNU Makefile标准。为了生成Makefile.in,automake还需用到perl(它本身就是一个perl程序)。
版本检测:

Phpize:
phpize是用来扩展php模块的,通过phpize可以热编译php的PECL扩展模块 。一般情况是编译php时忘记添加某扩展,后来想添加扩展,而你又不想删除目录重装PHP的话,就可以使用phpize,比如你想在原来已经编译好可以正常运行的php中加入memcached或者别的扩展模块等。
英文好的朋友可以参看官方文档:http://php.net/manual/en/install.pecl.phpize.php

幸运的是CentOS7.0 64bit系统已经自带了上述两个工具,如何安装上述两款工具我就不在此展开了,感兴趣的朋友可以检索下《Linux下的Autoconf和AutoMake》这篇文章,那么接下来就只有Phpize这个问题了。


phpize在哪里?
现在的状况是本机的Php坏境是用的yum扩展源Remi直接安装的,当时的安装命令用的是:
`# yum --enablerepo=remi install php55-php-fpm~和 ~# yum --enablerepo=remi install php70-php-fpm~
上面两个包安装时会自动附加运行PHP时必要的依赖安装文件,相当于PHP的极简安装包,但是正是这个极简安装包在我们需要做扩展的时候就成了障碍了。
phpize一般在PHP安装目录的bin/目录下,但是,当我定位到安装目录/opt/remi/php55/root/时并没有发现bin目录里有任何文件或文件夹,Php7的情况同样如此,目录/opt/remi/php7/root/bin/下面没有任何东西。因此我在想Remi源这么多用户因该是有解决方案的,所以检索了Remi源下所有的与之相关的扩展包的情况,果然有发现:


用phpize编译安装Php的SCWS插件

如果上述环境都没有任何问题,那么接下来你可以正式开始你的SCWS分词工具安装了:

    1. 进入scws-1.2.3安装源码的目录 phpext/

    cd ~/scws-1.2.3/phpext/

    1. 在/phpext/目录中执行PHP安装目录下的bin目录下的phpize
      安装命令如下(Php5.5):
      # /opt/remi/php55/root/bin/phpize
      Php7.0的安装方式就用如下命令:
      # /opt/remi/php70/root/bin/phpize
      返回如下:

    Configuring for:
    PHP Api Version: 20121113
    Zend Module Api No: 20121212
    Zend Extension Api No: 220121212

如果你是Php7.0的话用就用如下命令:
# /opt/remi/php70/root/bin/phpize
返回如下:

Configuring for:
PHP Api Version:         20151012
Zend Module Api No:      20151012
Zend Extension Api No:   320151012
  1. 就在上面的当前目录执行

# ./configure --with-scws=/usr/local/scws

结果有提示如下错误:

configure: error: Cannot find php-config. Please use --with-php-config=PAT

看来我们需要指定文件php-config的具体位置了,改成如下的形式:
命令如下(Php5.5):

# ./configure --with-scws=/usr/local/scws--with-php-config=/opt/remi/php55/root/bin/php-config 

如果你是Php7.0的话用就用如下命令:

# ./configure --with-scws=/usr/local/scws --with-php-config=/opt/remi/php70/root/bin/php-config 

返回了一堆的信息,那么恭喜你,估计你应该离成功不远了。

  1. 执行
    make
    返回如下信息:

    Libraries have been installed in:
    /root/scsws-1.2.3/phpext/modules

    If you ever happen to want to link against installed libraries
    in a given directory, LIBDIR, you must either use libtool, and
    specify the full pathname of the library, or use the-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to theLD_LIBRARY_PATH' environment variable
    during execution
    - add LIBDIR to theLD_RUN_PATH' environment variable during linking - use the-Wl,-rpath -Wl,LIBDIR' linker flag
    - have your system administrator add LIBDIR to `/etc/ld.so.conf'

    See any operating system documentation about shared libraries for
    more information, such as the ld(1) and ld.so(8) manual pages.


    Build complete.
    Don't forget to run 'make test'.

  2. 然后用 root 身份执行
    make install

返回如下信息的话证明SCWS分词插件安装成功!
PHP5.5环境返回信息

Installing shared extensions: /opt/remi/php55/root/usr/lib64/php/modules/

PHP7.0环境返回信息

Installing shared extensions: /opt/remi/php70/root/usr/lib64/php/modules/
  1. 最后一步是在 php.ini 文件中加入以下几行
    PHP5.5的路径
    /opt/remi/php55/root/etc/php.ini

PHP7.0的路径跟Php5.5的路径略有不同
/etc/opt/remi/php70/php.ini

[scws]
;
; 注意请检查 php.ini 中的 extension_dir 的设定值是否正确, 否则请将 extension_dir 设为空,
; 再把 extension = scws.so 指定绝对路径。
;
extension = scws.so
scws.default.charset = gbk
scws.default.fpath = /usr/local/scws/etc

注:上文的
scws.default.charset = gbk可按你的需要改为scws.default.charset = UTF-8

设定完毕保存,再重启php服务

# systemctl restart php55-php-fpm.service 

才能使新的 php.ini 生效,查看phpinfo信息如下图:



scws_success

测试分词效果:

Linux系的服务器测试代码test.php如下

<?php $msg = '大家好,我的名字叫  李白  (《SCWS-1.2.3高效分词组件》),很高兴认识大家!';
$shfc = scws_open();
scws_set_dict($shfc, '/usr/local/scws/etc/dict.utf8.xdb');
scws_set_rule($shfc, '/usr/local/scws/etc/rules.utf8.ini');
scws_set_ignore($shfc,true);
scws_send_text($shfc, $msg);
$Amsg2 = scws_get_result($shfc);
scws_close($shfc); foreach($Amsg2 as $value)
{ foreach($value as $key => $value2)
        { echo $value2 .',';
       } echo '<br />';
} ?> 

如果是windows系的服务器的话,只需要把上面的词库地址的参数更改为相应的地址就行。

scws_set_dict($shfc, ini_get("scws.default.fpath").'\dict.utf8.xdb', SCWS_XDICT_XDB);

或者是

scws_set_dict($shfc,'c:\program Files\scws\dict.utf8.xdb', SCWS_XDICT_XDB);

运行结果见下图。


https://www.jianshu.com/p/c1dbad3a3630

https://www.jianshu.com/p/b708ba06d1f4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

http://www.xunsearch.com/scws/download.php


经验分享:linux 下 制作PHP扩展出现的问题 Module compiled with module API=20090626

制作出.so 文件后,php -v 出现下面的提示

PHP Warning:  PHP Startup: checkcode: Unable to initialize module
Module compiled with module API=20090626
PHP    compiled with module API=20131226
These options need to match
 in Unknown on line 0
PHP Warning:  PHP Startup: taint: Unable to initialize module
Module compiled with module API=20090626
PHP    compiled with module API=20131226
These options need to match
 in Unknown on line 0
PHP 5.6.10 (cli) (built: Jul  2 2015 13:26:19)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies

在网上http://www.th7.cn/Program/php/201408/253791.shtml 看到说是 debug和release 的问题,很是怀疑。
猜测:应该是运行的php和实现的插件版本不统一的问题
但是是在php源代码基础上构建的插件,问题出现在哪里呢?

使用idapro 分析 so文件发现 20090626 在so文件内,那就说明被什么文件带入了so文件中,在生成的插件框架文件中 .c 找不到这个串的定义,一定处在include 文件中,那么在哪里?


原来:机器上有php,后来下载源码编译,然后产生插件。是否这个插件的编译使用了原php的头文件呢?
:在Makefile中发现
INCLUDES = -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib
使用的的确是原来安装的php版本

20090626 这个串在 Zend_modules.h 中
/usr/include/php/Zend 这个目录下
定义为:
#define ZEND_MODULE_API_NO 20090626
而在源码中:
#define ZEND_MODULE_API_NO 20131226

正因为此,所以php和它的插件不配对,不能初始化
附:

#define PHP_5_0_X_API_NO        220040412
#define PHP_5_1_X_API_NO        220051025
#define PHP_5_2_X_API_NO        220060519
#define PHP_5_3_X_API_NO        220090626
#define PHP_5_4_X_API_NO        220100525
#define PHP_5_5_X_API_NO        220121212
#define PHP_5_6_X_API_NO        220131226


1、word 分词器

2、ansj 分词器

3、mmseg4j 分词器

4、ik-analyzer 分词器

5、jcseg 分词器

6、fudannlp 分词器

7、smartcn 分词器

8、jieba 分词器

9、stanford 分词器

10、hanlp 分词器

一个人工智能项目里的中文分词方案

做搜索的都知道,中文分词,一般都是先建一个词库,再根据词库进行分词。但是这样做有两个问题:1.存在歧义词,2.不容易发现新词。尤其第2点,在处理舆情类内容时更是如此。如果想减少这类问题,现在的主要解决手段,一般都是在后端建一个词条系统,通过累积找到高频词,然后把高频词加到词库中,再进行分词。但是这样做仍然有一个时间差问题,不适合即时性的内容判断。

最近接手了一个舆情类的人工智能项目,为了避免上述问题,采用以下手段。方法如下:
1. 拿到整个文本。
2. 按照文本段落,分成多个文本块。
3. 每个文本块,根据标点符号,切成多个文本句。
4. 对文本句进行二元分词。
5. 统计高频词,记录这些高频词的文本位置。
6. 以高频词为断点,重新对文本句进行分词,得到非高频词。
7. 结合词库分词。
8. 统计词条出现频率,标记属性,提交给后续任务做内容分析。

试验下来,用时基本相同,效果比单纯的词库分词要好,容易发现新词和敏感词,这对分析舆情内容非常有帮助。



关键字