基于信息熵原理分词这个概念很早了,用php实现了个,一气呵成,代码自然是,反正我也没有二次检查,呵呵。不过耗费内存是真的,真的很消耗内存!
写这个的好处就是我明白了很多东西…
代码如下
<?php /** * 基于信息熵的无词典分词 */ class partword{ /** * 词语最大长度 */ public $maxwordlen = 5; /** * 需要进行分词的文字 */ public $text; /** * 字符串长度 */ private $len; /** * 切分的单个文字 */ private $textarr; /** * 文字信息数组 */ private $wordinfo; /** * 初始化文字,将文字进行分割 */ public function initWords(){ $i = 0; $len = strlen($this->text); $strarr = array(); $word = '';//单词缓存 $en_write = False; while( $i<$len ){ $ascnum = ord($this->text[$i]); if( $ascnum >=224 ){ //高位大于244,utf8规定为3个字节 $zh_word = substr($this->text, $i, 3); $en_write = True; $i += 3; }elseif( $ascnum >=192 ){ //高位大于192,utf8规定为2个字节 $zh_word = substr($this->text, $i, 2); $i+=2; $en_write = True; }elseif( $ascnum <= 32 ){ //空字符,英文的空格 $en_write = True; $i += 1; }else{ $en_write = False; $word .= substr($this->text, $i, 1); $i += 1; } if( $en_write && $word != '' ){ $strarr[] = $word; $word = ''; $en_write = False; $this->len += 1; } if( $zh_word !='' ){ $strarr[] = $zh_word; $zh_word = ''; $this->len += 1; } } return $this->textarr = $strarr; } /** * 发送文本 */ public function sendText($text){ $this->text = $text; $this->initWords(); $this->calInfo(); $this->calEntropy(); } /** * 整理词汇,用于后面的凝聚度和信息熵获取 */ public function calInfo(){ // if( !isset($this->textarr) ) die("no text"); $newarr = array(); $word = ''; $i = 0; /* 遍历整个单个文字数组 将所设定的词组阈值之内的所有可能的词进行提取 l=> 左边文字的位置 r=> 右侧文字的位置 c=> 词频 */ for ($i=0,$len = count($this->textarr); $i<$len; $i++) { $word = ''; for( $wordlen = 0; $wordlen < $this->maxwordlen; $wordlen++ ){ if( !isset( $this->textarr[$i+$wordlen] ) ) continue; $word .= $this->textarr[$i+$wordlen]; $newarr[$word]['w'] = $word; //左侧词 $newarr[$word]['l'][] = $i; //左侧词 $newarr[$word]['r'][] = $i+$wordlen; //右侧词 //统计词频 if( !isset($newarr[$word]['c']) ) $newarr[$word]['c'] = 1; else $newarr[$word]['c'] += 1; } } return $this->wordinfo = $newarr; } /** * 计算信息熵 */ public function calEntropy(){ foreach ($this->wordinfo as $key => $v) { $left_entropy = 0; $right_entropy = 0; //求左邻字的信息熵,需要大于0才可以 $left_word = array(); //print_r($v); foreach( $v['l'] as $l ){ if( $l >0 ){ if( !isset($left_word[ $this->textarr[$l-1] ]) ) $left_word[ $this->textarr[$l-1] ] = 1; else $left_word[ $this->textarr[$l-1] ] += 1; } } foreach( $left_word as $word=>$num ){ $left_entropy += -($num/$v['c'])*log($num/$v['c']); } //求右邻字的信息熵,需要小于整个长度 $right_word = array(); foreach( $v['r'] as $r ){ if( $r < $this->len-1 ){ if( !isset($right_word[ $this->textarr[$r+1] ]) ) $right_word[ $this->textarr[$r+1] ] = 1; else $right_word[ $this->textarr[$r+1] ] += 1; } } foreach( $right_word as $word=>$num ){ $right_entropy += -($num/$v['c'])*log($num/$v['c']); } //echo $key."--".$left_entropy."--".$right_entropy."\n"; //取坐信息熵和又信息熵里面最小的一个 $entropy = ($left_entropy < $right_entropy) ? $left_entropy : $right_entropy; $this->wordinfo[$key]['entropy'] = $entropy; unset($this->wordinfo[$key]['l']); unset($this->wordinfo[$key]['r']); } unset($this->textarr); return $this->wordinfo; } /** * 对词进行排序,根据信息熵排序 */ public function sortResult(){ usort($this->wordinfo, array(&$this,'sortByEntropy')); return $this->wordinfo; } private function sortByEntropy($a,$b){ if( $a['entropy'] === $b['entropy'] ) return 0; return ($a['entropy'] > $b['entropy']) ? -1: 1; } } //应用 header("Content-type:text/html;charset=utf-8"); $smen = memory_get_usage(); $partword = new partword(); $text = "吃葡萄不吐葡萄皮不吃葡萄倒吐葡萄皮"; $partword->sendText($text); print_r( $partword->sortResult() ); $emen = memory_get_usage(); echo (($emen - $smen)/1024) ."kb"; ?>
你可能还喜欢下面这些文章
Varnish是一个HTPP反向代理缓存,它接受来自客户端的请求并试图从缓存中取出相应的数据来应答,如果缓存中并没有相应的数据,它将会把请求指向后端机器,获取并且储存响应的数据,之后再交付给用户。当varnish有缓存的时候响应通常只需要几微秒的时间,比直接访问后端机器通常要快两个数量级,所以要做的就是尽可能的将页面缓存到varnish中。varnish可以根据后端响应的内容来决定是否储存,在响应头中加入cache-control将会被varnish缓存。使用cookie可以让varnish不缓存。这些都是可以在一个vcl的配置文件( Varnish Configuration Languag
在php中,没有多线程让编程变得简单。但在一些需要并发提升性能的场景下,显得有些无能为力,比如发起一些http请求。但好在curl扩展可以让我们“并发”去请求网络资源。利用这个特点,我们能做很多有趣的事情。最基础的,并发请求网络资源,提升处理速度。并发访问代码<?phpclass ConcurrencyHTTP { private $_requests; private $_callbacks; private $_currentIndex = 0; public function get($url, $header = array(), $timeout = 3
在我的程序中,基本都使用utf8来编码(除非历史原因,实在是无法转换)。但我用的php在处理中文语言的时候,总显得有些生硬,总感觉没有处理英文那么流畅。比如为什么统计字符的数目要远大于汉字的个数?为什么截断中文乱码?为什么一串英文所组成的字符串可以使用数组的方式访问但是中文字符串为什么就是乱码?等等等等之类的问题。这一切的一切,都是因为对utf8编码不了解所导致的!虽然我们有mb_string这个扩展的对中文有很友好的支持,但对于编码原理,还是需要好好的了解一下。但对于初学者,我想你未必有耐心看完这篇文章,可以跳过直接看程序实例,这篇文章可以作为实例程序的参考作用。
一、基本位操作|或&与~取反^异或<<左移>>右移二、位操作的常见用法1.获取某位的值#define BitGet(Number,pos) ((Number)|= 1<<(pos)) //把某位置1#define BitGet(Number,pos) ((Number) &= ~(1<<(pos)) //把某位置0#define BitGet(Number,pos) ((Number) >> (pos)&1)) //用宏得到某数的某位#define BitGet(Number,pos) ((Number) ^=
shell中的if语法是最让我头疼的语法之一,它的判断就向使用USB插头一样——拿起来插入不行,翻转再插入还不行,再翻转插入行了!为了搞清楚这部分语言,我收集了一些文章关于if条件判断的用法,希望对你也有些帮助。一、基本语法if [ command ]; then 符合该条件执行的语句fiif [ command ];then 符合该条件执行的语句elif [ command ];then 符合该条件执行的语句else 符合该条件执行的语句fi语法说明bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语
赞赏微信赞赏
支付宝赞赏