基于信息熵原理分词这个概念很早了,用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"; ?>
你可能还喜欢下面这些文章
原标题: 互联网时代的社会语言学:基于SNS的文本数据挖掘今年上半年,我在人人网实习了一段时间,期间得到了很多宝贵的数据,并做了一些还算有意义的事情,在这里和大家一块儿分享。感谢人人网提供的数据与工作环境,感谢赵继承博士、詹卫东老师的支持和建议。在这项工作中,我得到了很多与众人交流的机会,特别感谢 OpenParty 、 TEDxBeijing 提供的平台。本文已发表在了《程序员》杂志,分上下两部分刊于 2012 年 7 月刊和 8 月刊,在此感谢卢鸫翔编辑的辛勤工作。由于众所周知的原因,《程序员》刊出的文章被和谐过(看到后面大家就自动地知道被和谐的内容是什么了),因而我决定把完整版发在 Bl
今年上半年,我在人人网实习了一段时间,期间得到了很多宝贵的数据,并做了一些还算有意义的事情,在这里和大家一块儿分享。感谢人人网提供的数据与工作环境,感谢赵继承博士、詹卫东老师的支持和建议。在这项工作中,我得到了很多与众人交流的机会,特别感谢 OpenParty 、 TEDxBeijing 提供的平台。本文已发表在了《程序员》杂志,分上下两部分刊于 2012 年 7 月刊和 8 月刊,在此感谢卢鸫翔编辑的辛勤工作。由于众所周知的原因,《程序员》刊出的文章被和谐过(看到后面大家就自动地知道被和谐的内容是什么了),因而我决定把完整版发在 Blog 上,同时与更多的人一同分享。对此感兴趣的朋友可以给我
最近开始研究股票了,自己一个一个的去看,几千支股票完全看不过来啊,想着自己写一个程序,让程序来看股票吧!股票接口首先我们需要得到所有的股票代码,好在已经有网页帮我们列出了所有的股票名称和代码,地址是:http://quote.eastmoney.com/stocklist.html通过这个页面,就可以抓取了。抓取之后我们就可以存入mysql中,每一个股票可以存一张表,而每一张表中则可以存入股票的动态数据。这里我们只能获取到一些最简单的数据,一些更加详细的数据还需要获取,这里需要使用一个腾讯财经的接口http://qt.gtimg.cn/q=sz000858该接口为获取五粮液的股票数据,返回结果
PHP转Go的程序员很多,使用Go重写Web应用,代价不高,并且所带来性能的提升很明显,因此很多PHP程序员正在转Go。PHP是一个弱类型,解释型的语言,Go是一个强类型,编译型语言,两者的差别很大。如果长期使用PHP,使用Go的时候,一些惯性思维会带来不太好的效果。这里总结一些从PHP转到Go需要注意的点。警惕内存越界访问一个数组,在php中,如果a是一个空数组,直接访问a会出现警告,但程序还能继续运行,而在Go中,由于访问一个不存在的地址,程序会直接崩溃。因此Go中需要时刻警惕内存越界。在访问数组下标的时候,如果不能确认需要访问数据一定存在,那么一定要使用len判断数组长度,需要访问的下标
bash 4.1.2 版本增加了map数据结构。map是一种常用的数据结构,通过map可以将key映射到一个value。使用方法map在使用之前需要先声明,声明的方式如下map需要先声明再使用。参数-A表示声明的变量是一个map。需要注意的是这里的A是大写的字母A。赋值操作map的赋值有两种方式,一种是直接给map赋值,如下:另一种是使用下标给map添加key-value对输出所有的key在文中最开始提到map的使用需要先声明,在没有声明的情况下此处会输出一个0,如下图:输出所有value输出map长度遍历,根据key找到对应的value遍历所有的key遍历所有的value问题FAQQ:为什么
在一个高并发,但是数据量不大的系统中,使用Redis做数据库再好不过,结合Swoole,只需要很少的机器就能抗住很大的量。Redis大多数的应用可能都是当做缓存,当作为一个数据库用的时候,就必须要考虑持久化的问题了。持久化的意思就是将内存中的数据写到磁盘中,当再次重启之后,数据可以从磁盘中进行恢复,不会丢失。Redis持久化有两个策略,一个是RDB快照,一个AOF日志,不管是什么策略,最终的目的都是将数据保存在磁盘上,并不高深。只需要耐心的看看这两种策略,就能明白了。RDB快照从名字上我们就能知道这是RedisDB的缩写了,Redis快照是这样生成的,到了需要生成快照的时候,通过fork当前进
布隆过滤器(bloom filter)介绍以及php和redis实现布隆过滤器实现方法
引言在介绍布隆过滤器之前我们首先引入几个场景。场景一在一个高并发的计数系统中,如果一个key没有计数,此时我们应该返回0。但是访问的key不存在,相当于每次访问缓存都不起作用了。那么如何避免频繁访问数量为0的key而导致的缓存被击穿?有人说, 将这个key的值置为0存入缓存不就行了吗?这是确实是一种解决方案。当访问一个不存在的key的时候,设置一个带有过期时间的标志,然后放入缓存。不过这样做的缺点也很明显:浪费内存和无法抵御随机key攻击。场景二在一个黑名单系统中,我们需要设置很多黑名单内容。比如一个邮件系统,我们需要设置黑名单用户,当判断垃圾邮件的时候,要怎么去做。比如爬虫系统,我们要记录下
强化twenty fifteen主题,twenty fifteen pro主题制作过程
被最新的twenty fifteen主题迷上了,这就是我心目中的样式!但有功能还是需要添加的,因此在twenty fifteen的主题基础上,增加了一些功能,命名为twenty fifteen pro主题,目前我所用的主题就是twenty fifteen pro主题。目前增加的功能有这些1.专辑文章将一些文章整个成专辑,比如之前胡超的sublime这个专辑,随便点进去一篇文章,左侧栏都会出现该专辑的系列文章,并且在后台还可以手动控制其排序。这样的好处就是能够将同类别,教程之类的文章聚合起来,更加利于阅读。2.页脚文字增加统计或者版权文字,备案号等等一些附加的信息可能是需要的,但很遗憾twent
记得第一次了解中文分词算法是在 Google 黑板报 上看到的,当初看到那个算法时我彻底被震撼住了,想不到一个看似不可能完成的任务竟然有如此神奇巧妙的算法。最近在詹卫东老师的《中文信息处理导论》课上再次学到中文分词算法,才知道这并不是中文分词算法研究的全部,前前后后还有很多故事可讲。在没有建立统计语言模型时,人们还在语言学的角度对自动分词进行研究,期间诞生了很多有意思的理论。中文分词的主要困难在于分词歧义。“结婚的和尚未结婚的”,应该分成“结婚/的/和/尚未/结婚/的”,还是“结婚/的/和尚/未/结婚/的”?人来判断很容易,要交给计算机来处理就麻烦了。问题的关键就是,“和尚未”里的“和尚”也是
在我的程序中,基本都使用utf8来编码(除非历史原因,实在是无法转换)。但我用的php在处理中文语言的时候,总显得有些生硬,总感觉没有处理英文那么流畅。比如为什么统计字符的数目要远大于汉字的个数?为什么截断中文乱码?为什么一串英文所组成的字符串可以使用数组的方式访问但是中文字符串为什么就是乱码?等等等等之类的问题。这一切的一切,都是因为对utf8编码不了解所导致的!虽然我们有mb_string这个扩展的对中文有很友好的支持,但对于编码原理,还是需要好好的了解一下。但对于初学者,我想你未必有耐心看完这篇文章,可以跳过直接看程序实例,这篇文章可以作为实例程序的参考作用。
赞赏微信赞赏
支付宝赞赏