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,便于生成脚本。
版本检测:
是一个从文件Makefile.am自动生成Makefile.in的工具。每个Makefile.am基本上是一系列make的宏定义。生成的Makefile.in,服从GNU Makefile标准。为了生成Makefile.in,automake还需用到perl(它本身就是一个perl程序)。
版本检测:
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这个问题了。
现在的状况是本机的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分词工具安装了:
-
- 进入scws-1.2.3安装源码的目录 phpext/
cd ~/scws-1.2.3/phpext/
-
-
在/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 -
在/phpext/目录中执行PHP安装目录下的bin目录下的phpize
如果你是Php7.0的话用就用如下命令:
# /opt/remi/php70/root/bin/phpize
返回如下:
Configuring for:
PHP Api Version: 20151012
Zend Module Api No: 20151012
Zend Extension Api No: 320151012
- 就在上面的当前目录执行
# ./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
返回了一堆的信息,那么恭喜你,估计你应该离成功不远了。
-
执行
make
返回如下信息:Libraries have been installed in:
/root/scsws-1.2.3/phpext/modulesIf 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'. -
然后用 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/
-
最后一步是在 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信息如下图:
测试分词效果:
Linux系的服务器测试代码test.php如下
<?php $msg = '大家好,我的名字叫李白,很高兴认识大家!';
$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);
运行结果见下图。
经验分享: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. 统计词条出现频率,标记属性,提交给后续任务做内容分析。
试验下来,用时基本相同,效果比单纯的词库分词要好,容易发现新词和敏感词,这对分析舆情内容非常有帮助。