发布一个纯PHP的中文关键字自动提取工具
周末的时候看到腾讯的空间里面写日志的时候能自动提取关键字,感觉这个功能非常的好,于是我自己准备也写一个。因为,提取关键字,肯定要涉及分词,现在的分词算法,最好的估计是统计算法,但是实现稍微复杂一点,用PHP的话,性能往往也不够。于是,我一切从简,争取星期天一天能写完这个工具。我翻了一下最简单的分词,好像就是向前最大匹配。而且如果字典好的话,据说准确率还挺高的。当然,我没有什么好字典,从中科院的分词软件里面,拿了一本字典。大概有10万的词汇量。当然,你可以用其他的字典,但是一定要有词频。
当然,只是简单的分词,算法没有什么好说的,我就说说我写的时候遇到的问题。
1. 字典管理。
本来我想把字典先读成一个PHP Array 来实现,但是,发现内存占用很大,而且非常的慢。这样,即使写出来,也太慢了。于是乎,我想到了给字典设计一个简单的索引。
索引建立的方法是这样的:
1.1 所有的词汇进行排序。
1.2 然后对每个词汇的第一个字,建立索引,放在字典文件的开头。
1.3 索引区后面就是内容,为了方便进行二分查找,所有的项必须对齐,所以某个字下面按照最长的那个词汇进行对齐。
我写了一个工具,把中科院分词的字典,转换成我的格式的字典。
这样,一测试, 发现性能还可以。但是,每秒查询 2000次左右。为了加速这本字典,减少IO的次数。又写了一个类:MFile,先把整个文件读入内存,我发现读取200K,和读取1M的文件,花费的时间差不多,所以自己加载进入内存算了。
这本字典足足让我写了一个下午才搞定(上午我还没有起床)。
2. PHP不支持Unicode,所以,其实,它不把汉字当作一个字,而是两个char。于是,我还显得把文章转换成一个字的数组。这里,
本来不需要这样复杂,但是我为了以后扩展方便,给字加了分类。
define("T_CHINESE", 1); //中文
define("T_SEP", 1 << 1); //分割符合
define("T_NUM", 1 << 2); //数字
define("T_INDEX", 1 << 3);//索引 ① ② ③ ④ ⑤ ⑥ ⑦
define("T_LETTER", 1 << 4); //字母
define("T_WORD", 1 << 5); //正常单词
define("T_OTHER", 1 << 6);
用一个Int 的位,表示一种类型。比如中文数字就是 T_CHINESE | T_NUM
正确区分数字我觉得对提取关键字不是非常的有用。所以,我其实没有对数字进行特殊的处理。这样,我分词的基本思路是:
先根据句子的分割符号,分成子句。如果子句中还有中文和英文的话,那就分成切分中文部分,和切分英文部分。当然,我这个分法还不是非常的合理。我把阿拉伯数字也算成英文了,这点我没有深入去判断,因为数量词一般不会成为文章的关键字。
写完所有的分词部分,已经是晚上11点了。我不得不草草收场了。本来想支持英文的提取,但是,找不到一本有词频的英文字典,所以,只能算了,时间已经很晚了,大家就凑合着用。我估计也没有什么人会用,哈哈。只是,无聊的时候看连续剧,好不如时间这样打发来的快。
下面是一个测试:
真的不知道博客园的同志们是怎么想的,给我了写Javascript的权限,不给我iframe 的权限。害我不得不动态生成iframe。
如今北京许多光鲜靓丽、冠冕堂皇、和谐兴旺的街巷名字,追溯历史,从前,也就是明清时期,往往土得掉渣、充满戾气、属于“三俗”之列。请看:辟才胡同,原名劈材胡同,在西单北大街西侧。颂年胡同,原名宋姑娘胡同;在东直门南小街。福绥境胡同,原名苦水井胡同。大小雅宝胡同,原名哑巴胡同;在朝阳门南小街。南、北锣鼓巷,原名罗锅巷;在公鼓楼东大街。迺兹府,原名奶子府;在八面槽。东、西交民巷,原名江米巷;在天安门广场两侧。甘雨胡同,原名乾鱼胡同;在王府井大街。多福巷,原名豆腐巷;在王府井大街。韶九胡同,原名烧酒胡同;在王府井大街。大小淹通胡同,原名烟筒胡同;在朝阳门内大街。东西珠市口,原名猪市口;在前门大街。留学路,原名牛血胡同;在珠市口西大街。高义伯胡同,原名狗尾巴胡同;在太仆寺街。礼士胡同,原名驴市胡同;在东四西大街。吉兆胡同,原名鸡罩胡同;在朝阳门内北小街。锦帽胡同,原名鸡毛胡同;在广宁伯街。达智(营、花园、庙、桥),原名鞑子(营、花园、庙、桥)。无量大人胡同,原名无良大人胡同;在东单北大街。大吉巷,原名打劫巷;在宣武门外骡马市大街。延旺庙街,原名阎王庙街;在宣武门外南横街。库藏胡同,原名裤裆胡同;在珠市口西大街陕西巷。绶水河,原名臭水河;在民族宫南街。奋章胡同,原名粪场大院;在崇文门外东西兴隆寺。时刻亮胡同,原名屎壳郎胡同;在新街口北大街。其中有一些街巷,随着城市建设的日新月异,今天已经没有了,或者改名字了。但是,它们的确都曾经存在过。据已故著名语言学家张清常先生说,北京城区街道的名字,历史上一直在变化着,到上世纪八十年代,辽金以前的名字已经所剩无几,确知为元朝使用的名字,像“砖塔胡同儿”(在西四南大街南侧。元杂剧《张生煮海》里边侍女说:“你去兀那羊市角头砖塔儿胡同总铺门前来寻我。”)、“刘蓝塑胡同”(在西什库大街东侧。刘蓝塑,元朝著名雕塑家刘元),也屈指可数了。新旧地名的更迭,最大规模的一次可能是新中国成立后不久。新中国政府大概是认为,翻身做了国家主人的人民百姓,应该在有个美好名字的地方,安居乐业。用心不可谓不良苦。但是,我认为,其中多数新名字,因为过于美好,反倒失去了人间的韵味,不让人感到亲切、温馨了。我想起了那个著名的故事:老和尚第一次带他收养的从未下过山的十八岁小和尚去市镇办事。小和尚初次看见漂亮女子,十分好奇,就问老和尚那是什么。老和尚担心小和尚动了凡心尘念,无法修成正果,就吓唬他说,她们是老虎,会吃人的。小和尚唯唯而已。可是,回到山寺不久,小和尚就病倒了。老和尚问他怎么不舒服,小和尚回答说:“我想老虎。”政府有点像老和尚,担心在土得掉渣、充满戾气、属于“三俗”之列名字的街巷中,老百姓生活会不幸福。但是,身为小百姓一分子的我,此时此刻,却有点像那不谙世事的小和尚,心里更喜欢过去那些街巷旧名字,觉得那些名字充满了烟火人间的亲切和温馨。 代码在这里下载,我写代码的习惯不是很好,欢迎大家批评指正。
http://code.google.com/p/keywordcn/
页:
[1]