zoukankan      html  css  js  c++  java
  • 文字分词 隐马尔可夫模型-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)
    

      

  • 相关阅读:
    Java学习8.17
    Java学习8.16
    Java学习8.15
    Java学习8.14
    Java学习8.13
    Java学习8.12
    Java学习8.11
    131. Palindrome Partitioning 回文串分割
    40. Combination Sum II 不允许使用重复元素
    39. Combination Sum 凑出一个和,可以重复用元素(含duplicates)
  • 原文地址:https://www.cnblogs.com/caoke/p/13542854.html
Copyright © 2011-2022 走看看