在采用FMM (正向最大匹配) 进行中文分词的时候, 可能会存在比较多的交集歧义, 这个时候为了解决交集歧义的问题, 可以采用 FM (Forwar Matching, 正向匹配) 进行中文分词, 正向匹配会在最大匹配的路径上查找所有可能成词的term(这里所有可能成词的term的意思是在构建索引的时候所有切分出来的词, 因为不是路径上的所有节点都会是切分成的词)。
http://blog.csdn.net/watkinsong/article/details/37696389 这个文章中给出了FMM(正向最大匹配) 的算法实现。
算法描述如下图给出, 下面的图比较多, 但是描述的比较详细。 图后给出代码实现。
FM算法最大的问题就是切分的结果太琐碎, 因为在一次FMM(正向最大匹配)的过程中, 路径上所有是term的节点都会作为一个切分结果。 这样做的好处就是可以减少交集歧义的影响。
接下来根据算法给出代码。 代码假设已经存在索引, 并且索引采用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)
原文地址:http://blog.csdn.net/watkinsong/article/details/37697451