朴素贝叶斯经典案例:语言识别(language detection)

我对语言识别的问题一直很感兴趣,记得10年做全网爬虫时同事写了一个简单的网页语言检测,比较简单,只是判断unicode code point是否有足够数量落在中文的code point上,连基本的html标签都没有去除,当时也没有测试效果,很可能会把日本,韩文网页也当做中文页面了.

最近学习solr/lucene,里面就带有language detection功能,可以使用两个库,一个是tika的language detection,另一个是日本人写的托管在google code上的language detection,后者支持的语言数更多(53种哦),很快借助google和源码学习了这个好东西,思路值得借鉴.

看作者的slideshare上的介绍,这就是使用朴素贝叶斯进行分类的经典案例,特征采用ngram(最高3),当然之前要去噪声(越南文要做个normalize,去掉url,email,对于拉丁字母占比小于1/3的直接去掉拉丁字母以免干扰),还有抽取的特征并不完全是这些去掉噪声的字符,它对字符进行分类之后当做feature,具体就是如,阿拉伯文统一一类不关心具体字符,汉语按照常用程度分为122类,韩文一类等等,都是不关心具体字符,而关心所属分类(当然也有很多字符是不做这些分类的,字符编码即是特征),可以解决一般识别器对中日韩分类不准确,以及语料库不充分造成误判的问题.
具体到贝叶斯的计算过程,也很聪明.

cleaningText();
ArrayList<String> ngrams = extractNGrams();
langprob = new double[langlist.size()];

Random rand = new Random();
if (seed != null) rand.setSeed(seed);
for (int t = 0; t < n_trial; ++t) {
  double[] prob = initProbability();
  double alpha = this.alpha + rand.nextGausian() * ALPHA_WIDTH;
  for (int i = 0;; ++i) {
    int r = rand.nextInt(ngrams.size());
    updateLangProb(prob, ngrams.get(r), alpha);
    if (i % 5 == 0) {  // 感觉上这里最好还是加上i > 0更好
      if (normalizeProb(prob) > CONV_THRESHOLD || i >= ITERATION_LIMIT) break;
      if (verbose) System.err.println("> " + sortProbability(prob));
    }
  }
  for (int j = 0; j < langprob.length; ++j) langprob[j] += prob[j] / n_trial;
  if (verbose) System.out.println("==> " + sortProbability(prob))
}
随机采样,采样过程中如果发现有一种语言的概率是压倒性的直接停止,这样做很快速.

initProbability可以载入一个priorMap,严谨一点priorMap中各语言的概率之和应该是1,就是预设的各个语言的概率,updateLangProb直接将原概率乘以P(F|L)(F是feature,L是Language),这里的alpha是为了做平滑,防止出现*0之后直接变未0 的情况,normalizeProb则是将单语言的概率除以所有语言的概率.CONV_THRESHOLD是0.99999,的确是令人信服的阈值,理论上的确是practical了.

参考资料4是一个detector使用的例子,需要loadProfile载入语料库(corpus)得到probability map,源码中GenProfile.java可以生成profile供使用.

最后说一句,很佩服作者!


参考:

1.http://wiki.apache.org/solr/LanguageDetection

2.http://www.slideshare.net/shuyo/language-detection-library-for-java

3.http://code.google.com/p/language-detection/

4.http://www.cnblogs.com/makemelaugh/archive/2012/09/26/2704802.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值