码迷,mamicode.com
首页 > 其他好文 > 详细

NLP: 中文分词---正向匹配 (Forward Matching)

时间:2014-07-12 22:23:26      阅读:383      评论:0      收藏:0      [点我收藏+]

标签:nlp   中文分词   正向匹配   fm   

在采用FMM (正向最大匹配) 进行中文分词的时候, 可能会存在比较多的交集歧义, 这个时候为了解决交集歧义的问题, 可以采用 FM (Forwar Matching, 正向匹配) 进行中文分词, 正向匹配会在最大匹配的路径上查找所有可能成词的term(这里所有可能成词的term的意思是在构建索引的时候所有切分出来的词, 因为不是路径上的所有节点都会是切分成的词)。


http://blog.csdn.net/watkinsong/article/details/37696389  这个文章中给出了FMM(正向最大匹配) 的算法实现。


算法描述如下图给出, 下面的图比较多, 但是描述的比较详细。 图后给出代码实现。

FM算法最大的问题就是切分的结果太琐碎, 因为在一次FMM(正向最大匹配)的过程中, 路径上所有是term的节点都会作为一个切分结果。 这样做的好处就是可以减少交集歧义的影响。


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


bubuko.com,布布扣


 接下来根据算法给出代码。 代码假设已经存在索引, 并且索引采用trie树进行保存。

仍然是JS代码。。。


var lunr = require("./lunr.js")
var idxdata = require("./idx.json")

var idx = lunr.Index.load(idxdata)
var ii = idx.tokenStore

var query1 = "中国人民银行指出我国最近经济不景气"
var query2 = "习近平今日出席了中央气象台的联欢晚会"
var query3 = "中国银行今日出台了最新的贷款政策"
var query5 = "全部门"
var query6 = "互联网金宝"
var query7 = "上下级别"
var query8 = "确定期"
var query9 = "引领土完整"

query = query6
var result = tokenizer(ii.root, query)
console.log(result)

/* tokenizer */
function tokenizer(root, str) {
  if ( root == null || root == undefined ) return []
  if ( str == null || str == undefined || str.length == 0 ) return []

  var out = []
  while ( str.length > 0 ) {
	var ret = forwardMatching(root, str)
    out = out.concat(ret)
    str = str.slice(1)
  }

  return out
}

/* FM, this will return all the possible terms in along the longest search path */
function forwardMatching(root, str) {
  if ( root == null || root == undefined ) return
  if ( str == null || str == undefined || str.length == 0 ) return

  var out = []
  var matches = ""
  var currentNode = root
  for( var i = 0; i < str.length; i++ ) {
    if (str[i] in currentNode ) {
      matches += str[i]
	  currentNode = currentNode[str[i]]
	  docs = currentNode.docs || {}
	  if ( Object.keys(docs).length ) {
		// if current node is a term, add this term as a segment piece
		out.push(matches)
	  }
    } else {
	  if ( matches.length == 0 ) {
	    // un-board word found
		out.push(str[i])
	  }
      break
    }
  }

  return out
}

function getAmbiguiousLength(root, str, word_length) {
  var i = 1
  while ( i < word_length && i < str.length ) {
    var wid = tokenize(root, str.slice(i))
    wid = wid[0]
    var length = wid.length
    if ( word_length < i + length ) word_length = i + length
    //console.log("i = " + i  + ",length=" + wid.length + ", wid :" + wid + ", word_length : " + word_length)
    i += 1
  }

  return word_length
}

测试: 

query: "互联网金宝"

切分结果: [ ‘互联网‘, ‘网‘, ‘网金宝‘, ‘金‘, ‘宝‘ ]


这里, 因为在切分 “联网金宝”子句时, “联” 在索引中出现, 但是并不是一个term, 所以跳过“联”, 进行下一次切分“网金宝

NLP: 中文分词---正向匹配 (Forward Matching),布布扣,bubuko.com

NLP: 中文分词---正向匹配 (Forward Matching)

标签:nlp   中文分词   正向匹配   fm   

原文地址:http://blog.csdn.net/watkinsong/article/details/37697451

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!