News新闻

业界新闻动态、技术前沿
Who are we?

您的位置:首页      乐道系统FAQ      转:PHP自动提取关键字

转:PHP自动提取关键字

发布日期:2014-04-28 00:00:00 487

不能说是提取关键字了,可以说是取词,根据就是出现2次以上就可以认为是词,做些修改可以提取指定词频的词,效果还不算好,有些高词频的词,由于其会形成组词,这样这个词的子词取代其,因此没有取到

 

基本方法:2个字符构成最小的词,而其的词频必定是从该词的起点构成的词中最大的,通过不断的加字符,路过出现小于这个最大的次品,可以认为这个词到了结束位置,取出这个词,并且把所有的该词占据的位置记录下来,以减少重复判断

 

加了些过滤的标识符---词不能包含标点符号等

 

不足:对歧义没有过多处理,利用的是最大正向遍历,取2个字符假设为初始词,可能是词的一部分,路过出现没有取到应该取到的词(路前面说的组合词,只能证明这个词还可以再分,是由几个词组合而来,按照最小词原则,可以认为这样是可以的)

 

返回数组:

[0] => Array ( [0] => 大话西游 [1] => 2 [2] => Array ( [0] => 1 [1] => 892 ) [3] => 4 )

 

[0] =>词字符串      [1] => 词频          [2] => 该词出现的各个位置           [3] => 词的长度,几个字符

 

PHP代码:里面的词“周星星”出现了问题,因为前面有  “周星驰“,周星最多出现的,所以还是不好,速度也不行,可能判断重复的数组,修改下用键直接引用会快些

 

 

[php] view plaincopy
 
  1.   

<?php
set_time_limit(0);


//解析字符串中英文支付,成为字符数组,得长度
//$fustr='dddddddddddddgdg大股东广东';//带解析的字符串
function str_arr($fustr,$mudi=1)
{$wz=0;
$arr=array();
while($wz<strlen($fustr)){
$zifu=$fustr[$wz];
if(ord($zifu)>127){$str=$zifu.$fustr[$wz+1];$wz=$wz+2;}


else{$str=$zifu;$wz++;}


$arr[]=$str;//放到数组里


}//end while($wz<strlen($fustr))
if($mudi==1)return $arr;
else return count($arr);
}
//测试
//$arr=str_arr($fustr,$mudi=1);
//print_r($arr);


//end 解析字符串


//截取函数,截取字符串数组,得到部分字符串
//$arr=array();//字符串数组
$ks=0;//截取开始位置
$long=10;//截取长度,多少个字符


function jiequ($arr,$ks,$long=0){
if($ks+$long>count($arr))return false;
$str=';
$maxlen=count($arr);
if($long==0)$end=$maxlen;
else $end=$ks+$long;
for($i=$ks;$i<$end;$i++){
$str.=$arr[$i];
}


return $str;


}//echo jiequ($arr,$ks,$long);




//查询函数,得到从查询位置开始的第一个匹配位置
$wz=0;//查询位置
$arr=array();//字符串数组


$str='gjgg';//目标字符串
$strarr=str_arr($str,1);
function dingwei($arr,$strarr,$kswz){


$len1=count($arr);//总字符串数组长度
$len2=count($strarr);//查询字符串数组长度
$you=0;
$wz=$kswz;
//判断是全等的第一个位置
while($wz+$len2<=$len1){
$isyou=0;
$wz1=$wz;
for($i=0;$i<$len2;$i++){


if($strarr[$i]!=$arr[$wz1]){
$isyou=1;


break;
}//end if($strarr[$i]!=$arr[$wz1])
$wz1++;
}//end for($i=0;$i<count($strarr)


if($isyou==1)$wz++;//位置移1
else {$you=1;$pos=$wz;break;}
}


if($you==0)return false;
else return $pos;
}
//全角半角转换函数
function banjiao($str) 

$arr = array('0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4','5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', 'A' => 'A', 'B' => 'B', 'C' => 'C', 'D' => 'D', 'E' => 'E','F' => 'F', 'G' => 'G', 'H' => 'H', 'I' => 'I', 'J' => 'J', 'K' => 'K', 'L' => 'L', 'M' => 'M', 'N' => 'N', 'O' => 'O','P' => 'P', 'Q' => 'Q', 'R' => 'R', 'S' => 'S', 'T' => 'T','U' => 'U', 'V' => 'V', 'W' => 'W', 'X' => 'X', 'Y' => 'Y','Z' => 'Z', 'a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd','e' => 'e', 'f' => 'f', 'g' => 'g', 'h' => 'h', 'i' => 'i','j' => 'j', 'k' => 'k', 'l' => 'l', 'm' => 'm', 'n' => 'n','o' => 'o', 'p' => 'p', 'q' => 'q', 'r' => 'r', 's' => 's', 't' => 't', 'u' => 'u', 'v' => 'v', 'w' => 'w', 'x' => 'x', 'y' => 'y', 'z' => 'z','(' => '(', ')' => ')', '〔' => '[', '〕' => ']', '【' => '[','】' => ']', '〖' => '[', '〗' => ']', '“' => '[', '”' => ']','‘' => '[', '\' => ']', '{' => '{', '}' => '}', '《' => '<','》' => '>','%' => '%', '+' => '+', '—' => '-', '-' => '-', '~' => '-',':' => ':', '。' => '.', '、' => ',', ',' => '.', '、' => '.', ';' => ',', '?' => '?', '!' => '!', '…' => '-', '‖' => '|', '”' => '"', '\' => '`', '‘' => '`', '|' => '|', '〃' => '"',' ' => ' '); 
return strtr($str, $arr); 





//测试例子
$fuhao=array(',','.',';',':','"','/','>','<','?','=','+','|','\\','!','`','#','&','*','(',')','[',']','{','}','^','%','$',' ' );
$huaizi='的是得吗嘛呀丫怎么啥哦啊嗄噢喔你我他她它从了很不这';
$fustr='《大话西游》:曾经有一份真诚的爱情放在我面前,我没有珍惜,等我失去的时候我才后悔莫及,人世间最痛苦的事莫过于此。你的剑在我的咽喉上割下去吧!不用再犹豫了!如果上天能够给我一个再来一次的机会,我会对那个女孩子说三个字:我爱你。如果非要在这份爱上加上一个期限,我希望是——一万年
周星弛泡妞经典对白(先有心理准备..~笑死你) 
一.公车站台 
周星星:“小姐你踩到我脚了.“ 
漂亮小妞: “没有吧,我离你那么远.“ 
周星星: “我是说,如果你把脚不小心放在了我脚上,就是踩到我脚了.“ 
漂亮小妞: “神经病.“ 
周星星: “哇,小姐好眼力,我确实有神经病史,一般看见漂亮的女孩就发作.“ 
漂亮小妞: “你们男人总是那样,说些无聊的话故意引女孩子故意.好象以为自己很帅.  
周星星: “小姐你错了,我从不以为我自己帅,而是我本身就很帅.“ 
漂亮小妞: “别那么恶心人好吧.我要吐了.“ 
周星星: “在你吐之前我可以问你个问题吗?“ 
漂亮小妞: “有屁快放“. 
周星星: “你为什么要昧着良心否定我的帅?“ 
漂亮小妞: “滚........“ 


二.公车上 
漂亮小妞: “怎么又是你?“ 
周星星: “有时候我的确无处不在.“ 
漂亮小妞: “你知不知道你很烦人,那么多位置不坐,偏要坐我旁边.“ 
周星星: “小姐,你搞清楚,我只是坐了个空位置,而空位置的旁边,刚好有个你,如此而已.“ 
漂亮小妞: “前面也有个空位置你怎么不去?“ 
周星星: “噢,明白了,原来你是想看我屁股,或者我用屁股看你?“ 
漂亮小妞: “快滚....“ 


三.下了公车 
漂亮小妞:“你为什么又下车?“ 
周星星: “反正不是因为你!我喜欢闲逛.“ 
漂亮小妞: “我告你性骚扰,你哪个单位的?“ 
周星星: “你是说斤,还是焦耳,牛顿?“ 
漂亮小妞: “我跟你很熟吗?老说这种无厘头话,对不起,我不感冒!“ 
周星星: “是呀,我们一点都不熟.我们好比一个枝头的两棵青草莓,酸酸的.“ 
漂亮小妞: “看了几次大话西游,学了几句唐僧话,以为你很幽默么?“ 
周星星: “幽默是天生的,要怪,你去怪我妈嘛.对了,还有我爸爸...“ 
漂亮小妞: “神经.“ 
周星星: “你妈神经.“ 
漂亮小妞: “你妈神经.“ 
周星星: “你看你,明明是你妈却要硬说成是我妈,莫非你想....“ 
漂亮小妞: “给我滚....“ 
四.肯得基门口 
漂亮小妞:“不会吧,我怎么那么倒霉又遇到你.“ 
周星星:“ “我也发觉了,我想我前辈子的罪一定很重“ 
漂亮小妞:“你说清楚点!小心我扁你!“ 
周星星:““你敢.我会叫的.“ 
漂亮小妞: “叫什么?“ 
周星星:““非礼呀.“ 
漂亮小妞:“你以为会有人理你么?“ 
周星星:“ “没有也好,我非礼回来好了.“ 
漂亮小妞:“天拉,你这样的无赖都有,真是瞎了老天的眼!“ 
周星星:“ “恩,是呀,要不然这世界上也不会存在什么所谓的精英.“ 
漂亮小妞:“........“ 
五.肯得基里 
漂亮小妞:“别说话,你一说话我就烦.“ 
周星星:“ “我还没说呀,讲点道理好不好?“ 
漂亮小妞: “我都叫你别说了,你说起话来象只苍蝇,恶心死了.“ 
周星星:““噢,本来话能起到这么大的作用,实在是惊天地,泣鬼神哟,我可以做个兼职哟?“ 
漂亮小妞:“做什么?“ 
周星星:““去医院帮人洗胃.“ 
漂亮小妞: “你没的救了,早点回去料理后事吧.“ 
周星星:““临死前我没有什么要求,我只想对你说几个字,又怕你不答应.你答应么?“ 
漂亮小妞: “说吧,合理要求可以考虑.“ 
周星星:““这顿肯得基你请我好吗?“ 
漂亮小妞:“去死.....“ 
六.出肯得基 
漂亮小妞:“你没女朋友吗?星期天一个人闲逛?“ 
周星星:““准确的说我没女朋友,但有女性朋友,你问这个干嘛?“ 
漂亮小妞:“没什么呀,关心你终生大事,不好吗?“ 
周星星:““好,怎么不好?你好象我一个我深爱的人。“ 
漂亮小妞:“谁?..“ 
周星星:““我老妈.她也老喜欢问这问那。“ 
漂亮小妞: “要不是在街上这么多人看着,我真想揍你.“ 
周星星:““我都不怕别人看见你揍我,你怕什么呀?你呢,不陪男朋友吗?“ 
漂亮小妞:“不要你管!“ 
周星星:““噢,明白了.被男朋友抛弃了,揍我想找心理平衡.“ 
漂亮小妞: “狗嘴里吐不出象牙.明说吧,我不想找.“ 
周星星:““考虑一下我吧,我吃点亏.“ 
漂亮小妞:“求你别再恶心我了.“ 
周星星:““我可以无条件充当你的临时演员,如果需要男朋友的时候请打***********“ 
漂亮小妞:“到时候再说.“ 
周星星:““告诉我你的电话好吧?“ 
漂亮小妞:“到时候再说.再烦我骂你了呀.“ 
周星星:““好呀,那你就发条信息骂我.“ 
漂亮小妞:.................. 


七.各自回家 
漂亮小妞:“奇怪,我真的好想发条信息去骂他.“ 
周星星:““呵呵.她不发信息骂我才奇怪.“ 
漂亮小妞:“完蛋了,难道我真的喜欢那个无赖了?“ 
周星星:“嘿嘿,她不喜欢我这个无赖那才叫完蛋.';
$arr=str_arr($fustr,1);
$maxlen=count($arr);
$str='玛德';
$strarr=str_arr($str,1);
$kswz=0;
$pos=dingwei($arr,$strarr,21);
var_dump($pos);
$ciarr=array();


//分词过程,给定初始位置,由该位置查询 ,假想每个位置都可以取出词,然后判断其是否有2个
$kswz=0;//开始取词位置
while($kswz<$maxlen-1){
//首先判断词的开始点是否位于某个重复区域,若在则把词的位置移到这一区域的后方


$isduan=0;//是否是断的区域
for($i=0;$i<count($ciarr)&&$isduan==0;$i++){
$qu=$ciarr[$i][2];//已用的词的区间,若在其内则记录该区间,并跳过
$qulen=$ciarr[$i][3];//区间的长度
for($i1=0;$i1<count($qu)&&$isduan==0;$i1++){
if($qu[$i1]<=$kswz&&$kswz<$qu[$i1]+$qulen){
$nextwz=$qu[$i1]+$qulen;
$isduan=1;
break;
}//end if($qu[$i1]<=$kswz


}//end for($i1=0;$i1<count($qu)


}//end for($i=0;$i<count($ciarr)


//路过在断的区域,重新设置词的开始位置,并跳过这次处理
if($isduan==1){
$kswz=$nextwz;


continue;
}
//判断是否是符号,是着跳过
$zi=banjiao($arr[$kswz]);
if(in_array($zi,$fuhao)){
$kswz++;continue;
}
//是否坏字
if(strpos($huaizi,$arr[$kswz])!==false){$kswz++;continue;}


$nowci=array($arr[$kswz]);//初始词,单个字符,还不能称为词
//依次取字符,构成词,得到该词的个数,瞒住条件,记录
$wz=$kswz+1;
$isci=0;//是否可以取到有效的词
$first=1;//第1个词,最小词
//不断加字的过程,通过加字,比较和2个字的词的次数比较,取最长的词
while($wz<$maxlen){
//判断新增的字是否会在重复区间,从不在---在的过程,路过在,结束while
$isduan=0;//是否是断的区域
for($i=0;$i<count($ciarr)&&$isduan==0;$i++){
$qu=$ciarr[$i][2];//已用的词的区间,若在其内则记录该区间,并跳过
$qulen=$ciarr[$i][3];//区间的长度
for($i1=0;$i1<count($qu)&&$isduan==0;$i1++){
if($qu[$i1]<=$wz&&$wz<$qu[$i1]+$qulen){
//$nextwz=$qu[$i1]+$qulen;
$isduan=1;
break;
}//end if($qu[$i1]<=$kswz


}//end for($i1=0;$i1<count($qu)


}//end for($i=0;$i<count($ciarr)


//路过在断的区域,重新设置词的开始位置,并跳过这次处理
if($isduan==1){
break;
}//end 加字
//判断是否是符号,是着跳过
$zi=banjiao($arr[$wz]);
if(in_array($zi,$fuhao)){
break;
}
//是否遇到坏字
if(strpos($huaizi,$arr[$wz])!==false)break;


//进行区域
$nowci[]=$arr[$wz];//当前词的字符分割数组


$cishu=1;//初始词数1
$wzarr=array($kswz);
//统计词数,给出查询的初始位置
$chaxunwz=$wz+1;
$cilen=count($nowci);
while($chaxunwz<$maxlen){
if(($pos=dingwei($arr,$nowci,$chaxunwz))!==false)//路过有则记录
{
$chaxunwz=$pos+$cilen;//下次的查询位置,位置+词长
$cishu++;//词数+1 
$wzarr[]=$pos; 
 
}//end if(($pos=dingwei($arr,$nowci,$chaxunwz))!==false


else break;


}//end while($chaxunwz<$maxlen)


//路过词数》=2
if($cishu>=2){
//路过是最小词时,记录其词频,并作为最大词频
if($first==1){
$cistr=implode(',$nowci);//词连成字符串
$maxcishu=$cishu;//最大词数
$save=array($cistr,$maxcishu,$wzarr,$cilen);//说明0=》词,1=》位置的数组。2=》词的长度
$isci=1;
$first=0;
}//end if($first==1)


//非第1次记录,需要与最大的词频比较,当等于时记录更新,否则停止
else{
//路过大于等于最大词频,更新
if($cishu>=$maxcishu){


$cistr=implode(',$nowci);//词连成字符串
//$maxcishu=$cishu;//最大词数
$save=array($cistr,$cishu,$wzarr,$cilen);//说明0=》词,1=》位置的数组。2=》词的长度




}//end if($cishu>=$maxcishu)
//路过词数小于最大,结束
else break;


}//end else




}//end if($cishu>=2)


//路过小于2,直接结束
else break;
$wz++;


}//end while($wz<$maxlen)


//判断是否该位置有有效的词,路过有,记录到词组里
//路过有有效的词
if($isci==1){
$ciarr[]=$save;//记录一个词


$kswz=$kswz+$save[3];//把开始位置移位


}//end if($isci==1)
//路过没有有效词,把词的开始位置移1
else{
$kswz=$kswz+1;


}




}//end while($kswz<$maxlen-1)


print_r($ciarr);


  


?>