ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

文本分割-隐马尔可夫模型

2020-09-17 17:03:14  阅读:244  来源: 互联网

标签:分割 文本 const 马尔可夫 BMap AMap key let gl


/**
 文字分词 隐马尔可夫模型
 共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','Mn','E']

const mekflink={
  empty:{S:1/16},
  AMap:{
    'S-S':1000,
    'S-B':1000,
    'E-B':1000,
    'E-S':1000,
  },
  BMap:{},
  AMapGl:{},
  BMapGl:{},
  add(text){
    if(text.length>1){
      for(let i=0;i<text.length;i++){
        if(i===0){
          this.push(text[i],'B')
        }else if(i===text.length-1){
          this.push(text[i],'E')
          if(text.length>2){
            this.pushState('M'+(i-1),'E')
          }else{
            this.pushState('B','E')
          }
        }else if(i===1){
          this.push(text[i],'M'+i)
          this.pushState('B','M'+i)
        }else{
          this.push(text[i],'M'+i)
          this.pushState('M'+(i-1),'M'+i)
        }
      }
    }else{
      this.push(text,'S')
    }
  },
  pushState(t0N,t1N){
    const AMap=this.AMap;
    const key=t0N+'-'+t1N
    if(!AMap[key]){
      AMap[key]=0
    }
    AMap[key]++;
  },
  push(key,state){
    const BMap=this.BMap
    if(!BMap[key]){
      BMap[key]={}
    }
    if(!BMap[key][state]){
      BMap[key][state]=0
    }
    BMap[key][state]++;
  },
  //生成模型
  makeGl() {
    const AMap=this.AMap;
    const BMap=this.BMap;
    const AMapGl=this.AMapGl;
    const BMapGl=this.BMapGl;
    //统计A
    const AMapT={}
    for(let key in AMap){
      const [t0,t1]=key.split('-')
      if(!AMapT[t0]){
        AMapT[t0]=0;
      }
      AMapT[t0]=AMapT[t0]+AMap[key];
    }
    for(let key in AMap){
      const [t0,t1]=key.split('-')
      AMapGl[key]=this.chu(AMap[key],AMapT[t0])
    }
    //统计B
    for(let key in BMap){
      let t=0;
      for(let k in BMap[key]){
        t=t+BMap[key][k]
      }
      const obj=Object.create(this.empty)
      for(let k in BMap[key]){
        obj[k]=this.chu(BMap[key][k],t)
      }
      BMapGl[key]=obj;
    }
    return {
      AMapGl,BMapGl
    }
  },
  chu(p1,p2){
    return p1/p2;
  },
  exex(p1,p2){
    return p1*p2;
  },
  isBig(p1,p2){
    return p1>p2
  },
  getT1Arr(t0Obj,BObj){
    const AMapGl=this.AMapGl;
    const t1Obj={};
    let glAll=0;
    for(let t0 in t0Obj){
      const link=t0Obj[t0]
      for(let k in AMapGl){
        const arr=k.split('-')
        if(t0===arr[0]&&BObj[arr[1]]){
          const gl=this.exex(link.gl,this.exex(AMapGl[k],BObj[arr[1]]))
          if(gl>0){
            if(!t1Obj[arr[1]]){
              glAll=glAll+gl;
              t1Obj[arr[1]]={
                gl:gl,
                data:link.data+'-'+arr[1]
              }
            }else if(this.isBig(gl,t1Obj[arr[1]].gl)){
              glAll=glAll+gl-t1Obj[arr[1]].gl;
              t1Obj[arr[1]]={
                gl:gl,
                data:link.data+'-'+arr[1]
              }
            }
          }

        }
      }
    }
    for(let k in t1Obj){
      const gl=parseInt(t1Obj[k].gl/glAll*100);
      t1Obj[k].gl=gl
      if(gl===0){
        delete t1Obj[k]
      }
    }
    return t1Obj;
  },
  solve(text){
    const AMapGl=this.AMapGl;
    const BMapGl=this.BMapGl;
    console.log('状态转移概率',AMapGl)
    console.log('特征统计概率',BMapGl)
    //马尔可夫链条
    //获取当前状态可能的下一个状态
    let t0Obj={
      'S':{
        gl:1,data:'S'
      },
      'B':{
        gl:1,data:'B'
      }
    }

    for(let i=1;i<text.length;i++){
      t0Obj=this.getT1Arr(t0Obj,BMapGl[text[i]]||Object.create(this.empty))
    }
    const lArr=[]
    const cache={}
    for(let k in t0Obj){
      const dstr=t0Obj[k].data.replace(/[\d-]/g,'')
      const data=[]
      let start,end;
      for(let i=0;i<text.length;i++){
        if(dstr[i]==='B'){
          start=i;
        }else if(dstr[i]==='E'){
          end=i;
          data.push(text.substring(start,end));
        }
        // else if(dstr[i]==='S'){
        //   data.push(text[i]);
        // }
      }
      t0Obj[k].data=data
      const key=JSON.stringify(data)
      if(typeof cache[key]!=='undefined'){
        if(t0Obj[k].gl>lArr[cache[key]].gl){
          lArr[cache[key]]=t0Obj[k]
        }
      }else{
        cache[key]=lArr.length;
        lArr.push(t0Obj[k])
      }
    }
    if(lArr.length>1){
      lArr.sort(function (p1,p2) {
        return p2.gl-p1.gl;
      })
    }
    return lArr;
  }
}

module.exports=mekflink;

const arrH=['1ec66668876666666']
arrH.forEach(function (text) {
  mekflink.add(text)
})
mekflink.makeGl()
const text='1ec666688766666661ec66668876666666211ec6666887666666621';

console.log(mekflink.solve(text))

  

标签:分割,文本,const,马尔可夫,BMap,AMap,key,let,gl
来源: https://www.cnblogs.com/caoke/p/13686121.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有