文字分词 隐马尔可夫模型-JavaScript
/** 文字分词 隐马尔可夫模型 共4种状态S B M E AMap 为状态转移概率矩阵 4*4,表示从{S B M E}到{S B M E}的概率 BMap 为当前字属于某种状态{S B M E}的概率 * */ //有限状态 const S=['S','B','M','E'] const startB=['S','B'] const endB=['S','E'] //所有文字的默认概率 const wzState={ S:0.5, B:0, E:0, M:0, } const AMap={ SS:0.5, SB:0.5, SM:0, SE:0, BS:0, BB:0, BM:0.5, BE:0.5, MS:0, MB:0, MM:0.5, ME:0.5, ES:0.5, EB:0.5, EM:0, EE:0, } const BMap={}; const mekf={ add(text){ if(text.length>1){ if(text.length===2){ this.push(text[0],'B') this.push(text[1],'E') this.pushState('BE') }else{ for(let i=1;i<text.length;i++){ if(i===1){ this.push(text[i-1],'B') this.pushState('BM') }else if(i===text.length-1){ this.push(text[i-1],'M') this.push(text[i],'E') this.pushState('ME') }else{ this.push(text[i-1],'M') this.pushState('MM') } } } }else{ this.push(text,'S') } }, pushState(key){ if(!AMap[key]){ AMap[key]=0 } AMap[key]++; }, push(key,state){ if(!BMap[key]){ BMap[key]=Object.create(wzState) } BMap[key][state]++; }, getGl(obj,t){ return obj[t]/(obj.S+obj.B+obj.M+obj.E) }, solve(text){ let AMapFm={ S:0, B:0, M:0, E:0, }; for(let key in AMap){ const t0=key[0]; AMapFm[t0]=AMapFm[t0]+AMap[key] } //马尔可夫链条 const liantiao={ arr:[],//n-2 S:0, B:0, M:0, E:0, }; let linkArr=[] let lglArr=[] for(let i=0;i<text.length;i++){ const nlinkArr=[] const nlglArr=[] const glObj=BMap[text[i]]||Object.create(wzState) //求t0Arr t1Arr let t0Arr,t1Arr; let glArr; if(i===0){ t0Arr=['S'] lglArr=[1] }else if(i===text.length-1){ t1Arr=['S','E'] } //t0表示上一个可能的状态 if(!t0Arr){ t0Arr=[]; glArr=[]; for(let j=0;j<linkArr.length;j++){ const link=linkArr[j]; t0Arr.push(link[link.length-1]); } } //t1表示当前可能的状态 if(!t1Arr){ t1Arr=['S','B','M','E'] } for(let k=0;k<t1Arr.length;k++){ const t1=t1Arr[k] //找出相同状态t1最大的马尔可夫链 let maxArr=[]; let maxglArr=[0]; for(let j=0;j<t0Arr.length;j++){ const t0=t0Arr[j] const link=linkArr[j]||'';//已存在的马尔可夫链 let lgl=lglArr[j]||1;//马尔可夫链的概率 const nlink=link+t1; const key=t0+t1; if(AMap[key]!==0){ if(glObj[t1]!==0){ const cgl=lgl*this.getGl(glObj,t1)*(AMap[key]/AMapFm[t0]); if(cgl>maxglArr[0]){ maxArr=[nlink] maxglArr=[cgl] }else if(cgl===maxglArr[0]){ maxArr.push(nlink) maxglArr.push(cgl) } } } } if(maxArr.length>0){ for(let m=0;m<maxArr.length;m++){ nlinkArr.push(maxArr[m]) nlglArr.push(maxglArr[m]) } } } linkArr=nlinkArr; lglArr=nlglArr; } let maxLink; let maxGL=0; for(let i=0;i<linkArr.length;i++){ if(lglArr[i]>maxGL){ maxGL=lglArr[i] maxLink=linkArr[i] } } console.log(linkArr) console.log(lglArr) return maxLink } } mekf.add('太平洋保险') mekf.add('保险') mekf.add('一个') mekf.add('例子') mekf.add('隐马尔科夫链') mekf.add('科夫') console.log(AMap) console.log(BMap) const link=mekf.solve('科夫链') console.log(link)