免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123456
最近访问板块 发新帖
楼主: crazyhadoop
打印 上一主题 下一主题

互联网文本处理挑战巨大 中文分词系统设计如何面对? [复制链接]

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
51 [报告]
发表于 2012-06-05 09:31 |只看该作者
回复 52# to407


    那你可以去告某狗了,哈哈

论坛徽章:
2
午马
日期:2015-01-27 11:22:392015年辞旧岁徽章
日期:2015-03-03 16:54:15
52 [报告]
发表于 2012-06-05 09:37 |只看该作者
回复 53# crazyhadoop


    像google拼音和搜狗拼音的例子,北邮方那啥 曾经作过精辟的论断, 然后 他被砸了。

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
53 [报告]
发表于 2012-06-10 20:04 |只看该作者
想想现在的形式,精准分词很重要啊

论坛徽章:
0
54 [报告]
发表于 2012-06-16 11:42 |只看该作者
本帖最后由 huihui_2012 于 2012-06-16 12:27 编辑

基于成词概率的中文分词算法(WRSeg)解码算法


由于切分路径有2^(n-1)种,要从里面选一条最优路径,一一列举是不行的。本文采取维特比规划(即动态规划)的方法来实现。
为了进一步提高效率,因为长度很长的词语很少,因此,通常对词语的长度设定一个上限。就是认为如果长度超过这个上限,其成词概率都设为0。在本文所述的系统中,最大长度M设为8。
下面我们讲述在用二元语法的WR值来估计切分概率的解码过程。为了使用动态规划,我们需要记录截止到每个位置上已有的最优切分路径。在每个位置上,我们要保存截止到该位置的字串的最多M(注:M是我们设定的最大词语长度)条可能的最优路径,分别是:最后一个词语长度是1,2,3,…,M的最优路径。
对每个位置可能的M条路径,要分别计算。假设当前位置为i上最后一个词语长度为j的最优切分路径的切分概率为P[j]。P[j]的递推计算过程如下:

其中M是设定的最大长度; 是待分词的句子中从位置(i-j)到i之间的字符组成的字串,长度为j; 则是从位置(i-j-k)到(i-j)之间的字串,长度为k。
这样,我们就可以从左到右递推地求得每个位置上的若干条最优路径。我们从最后位置上的若干最优切分路径中选出一条最优路径作为分词结果输出。
以“它是一条黄狗”为例。首先看第0个位置,截止到该位置,只有一个字“它”,因此只有1条最优切分路径,该切分路径的最后一个词语就是“它”,长度为1。该切分路径的切分概率P[0][1]是Pr(“它”|<s>)
然后,我们逐字向右扫描。看第1个位置,截止到该位置的字串是“它是”。我们需要分别获得两条最优路径,
一条是最后一个词语长度为1,即最后一个词是“是”的最优切分路径;该路径是“它/是”,其切分概率 P[1][1]=P[0][1]*WR(是|它).
另一条是最后一个词语的长度为2,即最后一个词语是“它是”的最优切分路径,该路径是“它是”,切分概率是 P[1][2]=WR(它是|<s>)。
再往后看一个位置,此时字串是“它是一”,我们需要在该路径上保存三条不同最优路径,三条路径的概率分别是P[2][1],P[2][2],P[2][3]。
其计算方式分别如下:
(1) P[2][1]=max{P[1][1]*WR(一|是),P[1][2]*WR(一|它是)}
在上式中,假设P[1][1]*WR(一|是) >P[1][2]*WR(一|是) ,则P[2][1]=P[1][1]*WR(一|是),则P[2][1]所对应的切分路径是“它是/一”。
(2) P[2][2]=P[0][1]*WR(是一|它)
该切分路径是“它/是一”。
(3) P[2][3]=WR(它是一|<s>)
对应的切分路径是“它是一”。
我们依次类推后续各个位置的最优切分路径和对应的切分概率。
该解码算法的具体实现参见后文提到的java工程中的BigramSeg类的segment(String sentence)方法。注意:在实际的计算中,为了避免向下溢出和提高效率,通过对WR取对数,在求切分概率时,将各个WR值的连乘运算变成了对数值的相加运算。

论坛徽章:
0
55 [报告]
发表于 2012-06-16 12:04 |只看该作者
本帖最后由 huihui_2012 于 2012-06-16 13:19 编辑

WRSeg分词器的java工程模块
本文所实现的WRSeg分词器以java语言开发。主要步骤在ChineseSegment这个工程中实现。这个工程引用了Tools工程中的一些工具类。因此,在使用时,要将Tools导入到ChineseSegment中。源代码见附件。源代码内有已经训练好的分词器,用户可以直接使用。因为受附件大小的限制,原始的训练语料没有在源代码包中(训练语料用的是北大标注的1998年1月的语料)。

源代码仅供学术参考使用,若用于商业用途,请联系我:zhonghui830506@163.com

ChineseSegment项目的目录结构如下:

其中Count类是用来统计词频,进而计算成词概率的类;CountBiGram继承Count,专门对二元语法概率进行计算。
MergeNameEntity类是用于解决人名、地名、机构名等的词语粒度问题。在原始语料中,人名中姓和名字被当作是两个词语。如“江 泽民”中姓氏“江”和名字“泽民”被当作两个词语。但是,这往往不符合实际需求。在实际需求中,我们通常不希望将名字分割。在地名、机构名中也会存在类似的情况。MergeNameEntity类中提供方法将人名、地名、机构名中的各个组成部分合成一个单一的词语。
统计的成词概率结果放在数据结构类SegModel类的对象中。
UnigramSeg是利用Unigram语法,利用动态规划进行分词的类。BigramSeg是利用二元语法进行分词的类。
199801q.txt是原始训练语料,语料中的人名、地名和机构名都没有采取MergeNameEntity类中所提供的合并策略。词典.txt是前面所提到的外部词典,里面的词语不是来自于199801q.txt。
biWordRate.out,wordFrequence.out,wordRate.out都是已经训练好的分词模型。这些模型中都已经对人名中的姓氏和名字进行了合并,但是没有对地名和机构名进行MergeNameEntity类中所提供的合并。wordFrequence.out是基于wordfreq的一元语法,wordRate.out是基于wordrate的一元语法。biWordRate.out是基于二元语法,分词效果最好。
SplitSentence_seg是基于分词开发的一些工具方法,可以忽略。

调用示例
调用方法。下面的例子展示了如何调用本文所述的工程:
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.tseg.seg.SegModel;
import org.tseg.seg.BigramSeg;

public class ChineseSegment {
       
       
//假如原句是:
//        邓玉娇是湖北人,在09年是热点新闻人物
//        则分词后的结果是(返回结果的词语之间用空格隔开):
//        邓玉娇 是 湖北 人 , 在 09年 是 热点 新闻 人物
        public String seg(String line){
                //用单例方法来获得分词器,这样为了避免分词器的重复加载
                BigramSeg seg = BigramSeg.getSeg();
                return seg.segment(line);
        }
       
        //假如原句是:
//        邓玉娇是湖北人,在09年是热点新闻人物
//        则分词后的结果是(返回结果放在一个ArrayList中):
//        [邓玉娇, 是, 湖北, 人, ,, 在, 09年, 是, 热点, 新闻, 人物]
        public ArrayList<String> getSegList(String line){
                //用单例方法来获得分词器,这样为了避免分词器的重复加载
                BigramSeg seg = BigramSeg.getSeg();
                return seg.getSegWordList(line);
        }
       
//        给分词器加入新词
        public BigramSeg seggerWithNewWords(Collection<String> newWords){
                 //没有用取得单例的方法来获得分词器,这是为了不让新生成的分词器影响别的应用
                BigramSeg seg = new BigramSeg(SegModel.biWordRateType);
                for(String word : newWords){
                        if(!seg.getModel().wordLogProb.containsKey(word)){
                                seg.getModel().wordLogProb.put(word, 0.0);
                        }
                }
               
                return seg;
        }
       
        //将加入了新词的新的分词器保存到文件中
        public void save(BigramSeg seg, String segPath) throws IOException{
                seg.getModel().writeModel(segPath);
        }
       
        //从文件中读取分词器
        public BigramSeg read(String segPath) throws IOException{
                return new BigramSeg(segPath);
        }
       
        public void segTest() throws IOException{
                String line = "邓玉娇是湖北人,在09年是热点新闻人物";
               
                System.out.println(this.seg(line));
                System.out.println(this.getSegList(line));
               
                line = "邓玉娇刺官案在社会上反响很大!";
                System.out.println(this.getSegList(line));
//                输出结果:[邓玉娇, 刺, 官案, 在, 社会, 上, 反响, 很, 大, !]
                 
                Set<String> newWords = new HashSet<String>();
                newWords.add("刺官案");
                BigramSeg seg = this.seggerWithNewWords(newWords); //往分词器里加入新词,生成一个新的分词器
                System.out.println(seg.getSegWordList(line));
//                输出结果:[邓玉娇, 刺官案, 在, 社会, 上, 反响, 很, 大, !]
               
                String segPath = "D:/xing/seg.out";
                this.save(seg, segPath); //保存新分词器
                BigramSeg newSeg = this.read(segPath);  //读取刚保存的新分词器
                System.out.println(newSeg.getSegWordList(line));
//                输出结果:[邓玉娇, 刺官案, 在, 社会, 上, 反响, 很, 大, !]
               
        }
       
        public static void main(String args[]) throws IOException{
                ChineseSegment cst = new ChineseSegment();
                cst.segTest();
               
        }
       
       
}

Tools.rar

542.71 KB, 下载次数: 19

ChineseSegment.rar

4.7 MB, 下载次数: 30

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP