精华内容
下载资源
问答
  • 最新逆向最大匹配分词算法 盘古分词 分词算法 中文分词 源码
  • 基于词典的中文Uni-gram分词算法代码(正/逆最大匹配,全切分)简介正向最大匹配算法逆向最大匹配算法全切分算法 简介 包含三种基于词典的Uni-gram中文分词算法代码,分别为正向最大匹配,逆向最大匹配,全切分。...

    基于词典的中文Uni-gram分词算法代码(正/逆最大匹配,全切分,维特比)

    简介

    包含四种基于词典的Uni-gram中文分词算法代码,分别为正向最大匹配逆向最大匹配全切分维特比。前三个代码自己写的,第四个在维特比算法 实现中文分词 python实现上进行了改进。其中“全切分算法”好难写,且在网上没找到能拿来用的python代码,无奈自己写。因写的繁琐(找时间修改),所以不做解释,直接上代码和实例。(若有简洁易懂的代码可发我,谢大佬!)

    正向最大匹配算法

    • 加载词典,形式为 “词”:概率

      >>>word_prob = {"北京":0.03,"的":0.08,"天":0.005,"气":0.005,"天    气":0.06,"真":0.04,"好":0.05,"真好":0.04,"啊":0.01,"真好啊":0.02, 
                      "今":0.01,"今天":0.07,"课程":0.06,"内容":0.06,"有":0.05,"很":0.03,"很有":0.04,"意思":0.06,"有意思":0.005,"课":0.01,
                      "程":0.005,"经常":0.08,"意见":0.08,"意":0.01,"见":0.005,"有意见":0.02,"分歧":0.04,"分":0.02, "歧":0.005}
      >>>print (sum(word_prob.values()))
      1.0000000000000002
      

      输出值为词典中所有词的概率和

    • 正向最大匹配,返回分词结果

      def Max_Matching_forward(input_str):
          max_len = max(len(w) for w in word_prob.keys())
          i = 0
          j = i+max_len
          segments = []
          while(1):
              if input_str[i:j] in word_prob.keys():
                  if j >= len(input_str):
                      segments.append(input_str[i:j])
                      break
                  segments.append(input_str[i:j])
                  i = j
                  j = i+max_len
              else:
                  j -= 1
          return segments
      
    • 例子:

      >>>print(Max_Matching_forward("北京的天气真好啊"))
      ['北京', '的', '天气', '真好啊']
      >>>print(Max_Matching_forward("今天的课程内容很有意思"))
      ['今天', '的', '课程', '内容', '很有', '意思']
      >>>print(Max_Matching_forward("经常有意见分歧"))
      ['经常', '有意见', '分歧']
      

    逆向最大匹配算法

    • 逆向最大匹配,返回分词结果(用正向中的词典)

      def Max_Matching_backward(input_str):
          max_len = max(len(w) for w in word_prob.keys())
          j = len(input_str)
          i = j-max_len
          segments = []
          while(1):
              if input_str[i:j] in word_prob.keys():
                  if i == 0:
                      segments.append(input_str[i:j])
                      break
                  segments.append(input_str[i:j])
                  j = i
                  i = max(i-max_len,0)
              else:
                  i += 1
          segments.reverse()
          return segments
      
    • 例子:

      >>>print(Max_Matching_backward("北京的天气真好啊"))
      ['北京', '的', '天气', '真好啊']
      >>>print(Max_Matching_backward("今天的课程内容很有意思"))
      ['今天', '的', '课程', '内容', '很', '有意思']
      >>>print(Max_Matching_backward("经常有意见分歧"))
      ['经常', '有意见', '分歧']
      

    全切分算法

    • 共三个函数,第一个返回DAG词表,第二个用来过渡(不用管),最后一个用来调用。调用函数需输入两个参数,一是待分词句子,二是词典中所有词组成的列表(见下面代码块中的di)。

      >>>word_prob = {"北京":0.03,"的":0.08,"天":0.005,"气":0.005,"天气":0.06,"真":0.04,"好":0.05,"真好":0.04,"啊":0.01,"真好啊":0.02, 
                   "今":0.01,"今天":0.07,"课程":0.06,"内容":0.06,"有":0.05,"很":0.03,"很有":0.04,"意思":0.06,"有意思":0.005,"课":0.01,
                   "程":0.005,"经常":0.08,"意见":0.08,"意":0.01,"见":0.005,"有意见":0.02,"分歧":0.04,"分":0.02, "歧":0.005}
      >>>di = list(word_prob.keys())
      >>>di
      ['北京','的', '天','气', '天气', '真', '好', '真好','啊','真好啊', '今', '今天', '课程', '内容','有',
       '很','很有','意思','有意思','课','程','经常','意见','意','见','有意见','分歧','分','歧']
      
      # 生成DAG词表
      def single_word(sentence,dictionary):
          DAG_list = []
          for i in range(len(sentence)):
              DAG = []
              for j in range(i,len(sentence)+1):
                  if sentence[i:j] in dictionary:
                      DAG.append(sentence[i:j])
              DAG_list.append(DAG)
          return DAG_list
      
      # 以上一个list为基础生成下个list
      def ioi(nl):#为什么叫ioi?瞎起的!
          new22_list = []
          for i in range(len(nl)):
              s = ''
              for j in range(len(nl[i])):
                  s += nl[i][j]
              len2 = len(s)
              new22 = []
              if len2>=len(DAG_list):
                  new22.append(nl[i])
              else:
                  for k in range(len(DAG_list[len2])):#词组长度对应的 下个字 组成词列表中
                      new22.append(nl[i]+[DAG_list[len2][k]])
              new22_list.extend(new22)
          return new22_list
      
      #最后所需调用的函数;这个函数调用了前两个函数
      def seg_list(sentence,dictionary):
          global DAG_list
          DAG_list = single_word(sentence,dictionary)# DAG词表,调用了single_word函数
          #生成最初的list
          new_list = []
          for i in range(len(DAG_list[0])):#第一个字 组成词列表中
              len0 = len(DAG_list[0][i])
              new = []
              if len0>=len(DAG_list):
                  new.append([DAG_list[0][i]])
              else:
                  for j in range(len(DAG_list[len0])):#词组长度对应的 下个字 组成词列表中
                      new.append([DAG_list[0][i]]+[DAG_list[len0][j]])
              new_list.extend(new)
      
          #以第一个list为基础循环生成最终list
          for i in range(len(DAG_list)):
              new_list = ioi(new_list)#调用了ioi函数
          return new_list
      
    • 例子:

      >>>a = '今天的课程内容很有意思'
      >>>di = list(word_prob.keys())
      >>>seg_list(a,di)
      [['今', '天', '的', '课', '程', '内容', '很', '有', '意思'],
       ['今', '天', '的', '课', '程', '内容', '很', '有意思'],
       ['今', '天', '的', '课', '程', '内容', '很有', '意思'],
       ['今', '天', '的', '课程', '内容', '很', '有', '意思'],
       ['今', '天', '的', '课程', '内容', '很', '有意思'],
       ['今', '天', '的', '课程', '内容', '很有', '意思'],
       ['今天', '的', '课', '程', '内容', '很', '有', '意思'],
       ['今天', '的', '课', '程', '内容', '很', '有意思'],
       ['今天', '的', '课', '程', '内容', '很有', '意思'],
       ['今天', '的', '课程', '内容', '很', '有', '意思'],
       ['今天', '的', '课程', '内容', '很', '有意思'],
       ['今天', '的', '课程', '内容', '很有', '意思']
       ]
      
    • 查看DAG词表

      >>>DAG_list#查看DAG词表
      [['今', '今天'],
       ['天'],
       ['的'],
       ['课', '课程'],
       ['程'],
       ['内容'],
       [],
       ['很', '很有'],
       ['有', '有意思'],
       ['意', '意思'],
       []]
      
    • 得到最大概率分词句,对概率采用-ln(),即概率最大---->分值最小。如:‘经常’概率为0.08,转化后分数为-ln(0.08),即2.52…。
      best_segment函数返回两个值,一是最大概率分词句,二是所有分词句的分值。

      #计算所有分词可能的分数,返回概率最大的分词可能(分数最小值,-log())
      def best_segment(segments):
          segments = seg_list(a,di)
          score_list = []
          for i in segments:
              s = 0
              for j in i:
                  s += -math.log(word_prob[j])
              score_list.append(s)
          return segments[score_list.index(min(score_list))],score_list
         
      >>>import math
      >>>best_segment(seg_list(a,di))
      (['今天', '的', '课程', '内容', '很有', '意思'],
       [34.461815353774554,
        33.950989730008565,
        31.17840100776878,
        27.371738517998462,
        26.860912894232474,
        24.08832417199269,
        27.217587838171205,
        26.706762214405217,
        23.93417349216543,
        20.127511002395114,
        19.616685378629125,
        16.844096656389343])
      

    维特比算法

    • 加载词典

      >>>Dict = {"北京":0.03,"的":0.08,"天":0.005,"气":0.005,"天气":0.06,"真":0.04,"好":0.05,"真好":0.04,"啊":0.01,"真好啊":0.02, 
                   "今":0.01,"今天":0.07,"课程":0.06,"内容":0.06,"有":0.05,"很":0.03,"很有":0.04,"意思":0.06,"有意思":0.005,"课":0.01,
                   "程":0.005,"经常":0.08,"意见":0.08,"意":0.01,"见":0.005,"有意见":0.02,"分歧":0.04,"分":0.02, "歧":0.005}
      >>>di = list(Dict.keys())
      >>>di
      ['北京','的', '天','气', '天气', '真', '好', '真好','啊','真好啊', '今', '今天', '课程', '内容','有',
       '很','很有','意思','有意思','课','程','经常','意见','意','见','有意见','分歧','分','歧']
      >>>sentence = '经常有意见分歧'
      # '今天的课程内容很有意思'
      # '北京的天气真好啊'
      # '经常有意见分歧'
      
    • 逆序得到路径

      # 生成DAG,dictionary为词组列表
      def F_DAG(sentence,dictionary):
          DAG_list = {}
          for i in range(len(sentence)):
              DAG = []
              for j in range(i,len(sentence)+1):
                  if sentence[i:j] in dictionary:
                      DAG.append(j-1)
              DAG_list[i] = DAG
          return DAG_list
      
      import math
      N=len(sentence)
      route={}
      route[N] = (0, 0)
      DAG = F_DAG(sentence,di)
      # DAG={0: [1], 1: [], 2: [2, 4], 3: [3, 4], 4: [4], 5: [5, 6], 6: [6]}
      # 从最后一个字开始,寻找从当前字开始至最后一个字的分词方法中概率最大的,并记录。
      # 记录方法为:当前字的下标: (当前字到最后一个字分词方法中最大概率,当前字所组成的最大概率词的最后一个字的下标)
      for idx in range(N - 1, -1, -1):
          distance = list((((-math.log(Dict.get(sentence[idx:x + 1])) or 0) + (0 if route.get(x + 1)==None else route.get(x + 1)[0]), x) for x in DAG[idx]))
          if len(list(distance))>0:
              route[idx] = min(distance)
          else:
              route[idx] = (0,0)
      >>>print(route)
      {7: (0, 0), 6: (5.298317366548036, 6), 5: (3.2188758248682006, 6), 4: (8.517193191416236, 4), 3: (5.744604469176457, 4), 2: (7.1308988302963465, 4), 1: (0, 0), 0: (9.656627474604601, 1)}
      
    • 根据route打印结果

      x = 0
      segs = []
      while x < N:
          y = route[x][1] + 1
          word = sentence[x:y]
          segs.append(word)
          x = y
      >>>print(segs)
      ['经常', '有意见', '分歧']
      

    参考

    维特比算法 实现中文分词 python实现

    展开全文
  • java 实现的中文分词算法代码

    热门讨论 2011-04-14 20:10:38
    java 实现的基于FMM BMM算法的,中文分词算法代码
  • PHP中文分词算法代码实现

    千次阅读 2012-02-27 23:54:12
    简单的中文分词算法,二元分词的PHP代码: $str = '苏杭,人间的天堂paradise!'; //$str = iconv('GB2312','UTF-8',$str); $result = spStr($str); print_r($result); /** * UTF-8版 中文二元分词 */ function ...

    简单的中文分词算法,二元分词的PHP代码:

    $str = '苏杭,人间的天堂paradise!';
    //$str = iconv('GB2312','UTF-8',$str);
    $result = spStr($str);
    print_r($result);
    
    /**
     * UTF-8版 中文二元分词
     */
    function spStr($str)
    {
        $cstr = array();
    
        $search = array(",", "/", "\\", ".", ";", ":", "\"", "!", "~", "`", "^", "(", ")", "?", "-", "\t", "\n", "'", "<", ">", "\r", "\r\n", "{1}quot;", "&", "%", "#", "@", "+", "=", "{", "}", "[", "]", ":", ")", "(", ".", "。", ",", "!", ";", "“", "”", "‘", "’", "[", "]", "、", "—", " ", "《", "》", "-", "…", "【", "】",);
    
        $str = str_replace($search, " ", $str);
        preg_match_all("/[a-zA-Z]+/", $str, $estr);
        preg_match_all("/[0-9]+/", $str, $nstr);
    
        $str = preg_replace("/[0-9a-zA-Z]+/", " ", $str);
        $str = preg_replace("/\s{2,}/", " ", $str);
    
        $str = explode(" ", trim($str));
    
        foreach ($str as $s) {
            $l = strlen($s);
    
            $bf = null;
            for ($i= 0; $i< $l; $i=$i+3) {
                $ns1 = $s{$i}.$s{$i+1}.$s{$i+2};
                if (isset($s{$i+3})) {
                    $ns2 = $s{$i+3}.$s{$i+4}.$s{$i+5};
                    if (preg_match("/[\x80-\xff]{3}/",$ns2)) $cstr[] = $ns1.$ns2;
                } else if ($i == 0) {
                    $cstr[] = $ns1;
                }
            }
        }
    
        $estr = isset($estr[0])?$estr[0]:array();
        $nstr = isset($nstr[0])?$nstr[0]:array();
    
        return array_merge($nstr,$estr,$cstr);
    }

    "苏杭,人间的天堂paradise“经过二元分词之后,转变为:

    Array ( [0] => paradise [1] => 苏杭 [2] => 人间 [3] => 间的 [4] => 的天 [5] => 天堂 ) 
    接下来,是将以上结果转换为单字节的,可以用md5,base64,sha1等,但是用这些转换后的字符都太长,占用太多的存储空间,我们可以用区位码来表示汉字,汉字转区位码的PHP代码:

    foreach ($result as $s) {
        $s = iconv('UTF-8','GB2312',$s);
        $code[] = gbCode($s);
    }
    $code = implode(" ", $code);
    echo $code;
    
    function gbCode($str) {
        $return = null;
    
        if (!preg_match("/^[\x80-\xff]{2,}$/",$str)) return $str;
    
        $len = strlen($str);
        for ($i= 0; $i< $len; $i=$i+2) {
            $return .= sprintf("%02d%02d",ord($str{$i})-160,ord($str{$i+1})-160);
        }
    
        return $return;
    }

    转换后的结果为:

    paradise 43532628 40432868 28682136 21364476 44764435

    最后将得到的结果入库,插入全文索引表,结果应该插入索引表的fulltext索引字段。



    展开全文
  • 用mysql数据库写的分词算法代码

    千次阅读 2014-03-04 13:53:49
     /// <param name="strcon">article表里要分词标题和内容的数据  /// <param name="artsrt">article表里数据id编号  /// <returns></returns>  public string fencistr(string strcon, string artsrt) ...

    我辛苦的整了几天才整好的 拿来给大家分享一下 希望可以帮助大家 以下分为四步:每步都有注释说明的

    #region  一.先从article表里查询数据
        /// <summary>
        /// 一.先从article表里查询数据
        /// </summary>
        public void fenciBind()
        {
            string sql = "select * from article;";
            string str = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
            MySqlConnection con = new MySqlConnection(str);
            con.Open();
            MySqlDataAdapter msda = new MySqlDataAdapter(sql, con);
            DataTable dt = new DataTable();
            msda.Fill(dt);
            for (int i = 0; i < dt.Rows.Count; i++)//循环数据库里的数据
            {
                string strcon = dt.Rows[i][1].ToString();//标题
                strcon += dt.Rows[i][3].ToString();//内容
                DateTime strtime = Convert.ToDateTime(dt.Rows[i][4]);//时间

           //判断时间 在一天内容不让他进行分词
                if (strtime < DateTime.Now.AddDays(-1))
                {
                    string artsrt = dt.Rows[i]["id"].ToString();
                    fencistr(strcon, artsrt);
                    con.Close();
                }
            }
        }
        #endregion

    #region  二.article表里的数据进行分词
        /// <summary>
        /// 二.article表里的数据进行分词
        /// </summary>
        /// <param name="strcon">article表里要分词标题和内容的数据</param>
        /// <param name="artsrt">article表里数据id编号</param>
        /// <returns></returns>
        public string fencistr(string strcon, string artsrt)
        {
            StringBuilder sb = new StringBuilder();
            sb.Remove(0, sb.Length);
            string t1 = "";
            Analyzer analyzer = new Lucene.China.ChineseAnalyzer();
            StringReader sr = new StringReader(strcon);
            TokenStream stream = analyzer.TokenStream(null, sr);
            Token t = stream.Next();
            while (t != null)
            {
                t1 = t.ToString();   //显示格式: (关键词,0,2) ,需要处理
                t1 = t1.Replace("(", "");
                char[] separator = { ',' };
                t1 = t1.Split(separator)[0];
                sb.Append("," + t1);
                t = stream.Next();
            }
            //三.汉字转换拼音
            pinyinstr(sb.ToString(), sb.ToString(), artsrt);
            return strcon;
        }
        #endregion

    #region 三.汉字转换拼音
        /// <summary>
        ///三.汉字转换拼音
        /// </summary>
        /// <param name="sb">用于转化为pingyin的汉字</param>
        /// <param name="sbstr">用于往keywords表里添加的汉字</param>
        /// <param name="artsrt">article表里数据id编号</param>
        /// <returns></returns>
        public string pinyinstr(string sb, string sbstr, string artsrt)
        {
            string pystr = null;//pinyin表用逗号隔开的集合
            string s = sb.ToString();
            for (int i = 0; i < s.Length; i++)
            {
                if (ChineseChar.IsValidChar(s[i]))
                {
                    ChineseChar CString = new ChineseChar(s[i]);
                    for (int ii = 0; ii < CString.PinyinCount; ii++)
                    {
                        string PinYins = CString.Pinyins[ii].ToString().ToLower();
                        if (PinYins[PinYins.Length - 1].CompareTo('5') < 0)
                        {
                            pystr += PinYins;
                        }
                    }
                    pystr += "|";
                }
                pystr += ",";
            }
            pystr = pystr.Replace("|,", "").TrimEnd(',');
            Opestr(pystr, sbstr, artsrt);//四.创建拼音数据表并添加数据
            return pystr;
        }
        #endregion

    #region 四.创建拼音数据表并添加数据 同时往keywords表里添加数据
        /// <summary>
        /// 创建拼音数据表并添加数据 同时往keywords表里添加数据
        /// </summary>
        /// <param name="pystr">要创建的每个pinyin表</param>
        /// <param name="sbstr">article表里的数据分词后逗号隔开的字符串</param>
        /// <param name="artsrt">article表里数据id编号</param>
        public void Opestr(string pystr, string sbstr, string artsrt)
        {
            string[] PinYins = pystr.Trim().Split(',');
            for (int i = 1; i < PinYins.Length; i++)
            {
                //四.创建拼音数据表并添加数据
                //*************************1.往keywords表里添加数***********************
                //(1).查询keywords表,并判断keywords表里pinyin是否存在相同的
                string str = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
                MySqlConnection con = new MySqlConnection(str);
                con.Open();
                string kwssql = "select * from `hww_article_search`.`keywords`";
                MySqlDataAdapter kwsmda = new MySqlDataAdapter(kwssql, con);
                DataTable kwdt = new DataTable();
                kwsmda.Fill(kwdt);
                string[] hzstr = sbstr.Trim().Split(',');//汉字用逗号分割的数据
                for (int ii = 1; ii < hzstr.Length; ii++)
                {
                    if (kwdt.Rows.Count != 0) //(2).如果pinyin表里有数据,则先进行判断是否有相同的pinyin值
                    {
                        string kwstr = null;
                        for (int ll = 0; ll < kwdt.Rows.Count; ll++)
                        {
                            kwstr += "," + kwdt.Rows[ll]["pinyin"].ToString();
                        }
                        string kwpy = PinYins[i];
                        if (!kwstr.Contains(kwpy))
                        {
                            //(3).不存在相同的pinyin则添加
                            string kwsql = "INSERT INTO `hww_article_search`.`keywords` (`keyword`, `pinyin`) VALUES ('" + hzstr[ii] + "', '" + PinYins[ii] + "');";
                            MySqlCommand kwcom = new MySqlCommand(kwsql, con);
                            kwcom.ExecuteNonQuery();//添加
                        }
                    }
                    else//如果没有数据则添加
                    {
                        string kwsql = "INSERT INTO `hww_article_search`.`keywords` (`keyword`, `pinyin`) VALUES ('" + hzstr[ii] + "', '" + PinYins[ii] + "');";
                        MySqlCommand kwcom = new MySqlCommand(kwsql, con);
                        kwcom.ExecuteNonQuery();//添加
                    }
                }

            //*******************************2.建库建表*****************************
                //(1).先建库
                string sqlcre = "create table if not exists `hww_article_search`.`" + PinYins[i] + "` ( `id` int(10) not null auto_increment, `article_id` int(10) unsigned not null,primary key(`id`));";
                MySqlCommand com = new MySqlCommand(sqlcre, con);
                com.ExecuteNonQuery();
                //(2).查询pinyin表,并判断yinpin表里article_id是否存在此相同的id
                string sqlif = "select * from `hww_article_search`.`" + PinYins[i] + "`";
                MySqlDataAdapter msdaif = new MySqlDataAdapter(sqlif, con);
                DataTable dtif = new DataTable();
                msdaif.Fill(dtif);
                //(3).往pinyin表里添加数据sql语句
                string sqladd = " insert into `hww_article_search`.`" + PinYins[i] + "`(`article_id`) values(" + artsrt + ");";
                MySqlCommand comadd = new MySqlCommand(sqladd, con);
                //(4).添加成功后修改article表里的时间为当前时间sql语句
                string uptimesql = "update `hww_article_search`.`article` set `update_time`='" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "' where `id`=" + artsrt + ";";
                MySqlCommand comtime = new MySqlCommand(uptimesql, con);
                //如果pinyin表里有数据,则先进行判断是否有相同的id值
                if (dtif.Rows.Count != 0)
                {
                    string sdi = null;
                    for (int j = 0; j < dtif.Rows.Count; j++)
                    {
                        sdi += dtif.Rows[j]["article_id"].ToString() + ",";
                    }
                    string sad = artsrt;
                    if (!sdi.Contains(sad))
                    {
                        //3.不存在相同的id号则添加
                        comadd.ExecuteNonQuery();//添加
                        comtime.ExecuteNonQuery();//修改
                    }
                }
                else//如果没有数据则添加
                {
                    comadd.ExecuteNonQuery();//添加
                    comtime.ExecuteNonQuery();//修改
                }
            }
        }
        #endregion

    运行结果如下图:




     

    展开全文
  • 中文分词算法程序

    2013-01-15 21:26:34
    用C++写的一个中文分词算法程序,主要对文章语句进行分词处理。
  • 中文分词算法是指将一个汉字序列切分成一个一个单独的词,与英文以空格作为天然的分隔符不同,中文字符在语义识别时,需要把数个字符组合成词,才能表达出真正的含义。分词算法是文本挖掘的基础,通常应用于自然...

    1、中文分词算法介绍

            中文分词算法是指将一个汉字序列切分成一个一个单独的词,与英文以空格作为天然的分隔符不同,中文字符在语义识别时,需要把数个字符组合成词,才能表达出真正的含义。分词算法是文本挖掘的基础,通常应用于自然语言处理、搜索引擎、智能推荐等领域。

            分类:

    • 第一类是基于字符串匹配,即扫描字符串,如果发现字符串的子串和词典中的词相同,就算匹配,比如机械分词方法。这类分词通常会加入一些启发式规则,比如“正向/反向最大匹配”,“长词优先”等
    • 第二类是基于统计以及机器学习的分词方法,它们基于人工标注的词性和统计特征,对中文进行建模,即根据观测到的数据(标注好的语料)对模型参数进行训练,在分词阶段再通过模型计算各种分词出现的概率,将概率最大的分词结果作为最终结果。常见的序列标注模型有HMM和CRF。这类分词算法能很好处理歧义和未登录词问题,效果比前一类效果好,但是需要大量的人工标注数据,以及较慢的分词速度。
    • 第三类是通过让计算机模拟人对句子的理解,达到识别词的效果,由于汉语语义的复杂性,难以将各种语言信息组织成机器能够识别的形式,目前这种分词系统还处于试验阶段,这里不讲解和实现

    2、机械分词

             机械分词又称基于字符串匹配的分词方法、按照一定的策略将待分析的字符串与一个“充分大的”机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功(识别出一个词)。这是最简单的分词方法,但非常高效和常见。

            1、最大匹配方法----分为正向匹配和逆向匹配

            正向匹配算法:

                    待分词文本: text = '计算机语言学课程有意思'

                    词表: dict[]={"计算", "计算语言学", "课程", "有", "意思"} 

    •        从ste[0:***]开始,当扫描到ste[0:2]的时候,发现"计算"已经在词表dict[]中了。但还不能切分出来,因为我们不知道后面的词语能不能组成更长的词(最大匹配)。
    •     继续扫描ste[0:3],发现"计算语"并不是dict[]中的词。但是我们还不能确定是否前面找到的"计算语"已经是最大的词了。因为"计算语"是dict[2]的前缀。
    •     扫描ste[0:4],发现"计算语言"并不是dict[]中的词。但是是dict[2]的前缀。继续扫描:
    •     扫描ste[0:5],发现"计算语言学"是dict[]中的词。继续扫描下去:
    •     当扫描ste[0:6]的时候,发现"计算语言学课"并不是词表中的词,也不是词的前缀。则切分出"计算语言学"为最大词汇
    
    # 文本
    text = '我们的计算语言学课程有意思'
    textlen = len([i for i in text])
    print([i for i in text], '\n', len([i for i in text]), '\n'*2)
    """ """
    # sentence=["计", "算", "语", "言", "学", "课", "程", "有", "意", "思"]
    # 词库
    dict_1 = ["计算", "计算语言学", "课程", "有", "意思", "我们", "的", "我们的"]
    len_dict = [len(i) for i in dict_1]
    print(len_dict, '\n', max(len_dict), '\n'*2)
    
    # 当前匹配起始位置 和 结束位置
    start_loc = 0
    end_loc = 0
    
    # 匹配结果存储
    word_split = []
    i = 0
    for _ in range(textlen):
    	if i < textlen:
    		# 每一次匹配结果存储
    		word = []
    		for j in range(max(len_dict)+1):
    			word_try = text[i:(i+j)]
    			print(text[i:(i+j)])
    			if word_try in dict_1:
    				word.append(word_try)
    
    		# 取出最大匹配结果
    		word_split.append(word[-1:])
    		print(len(word))
    		print(len(word[len(word)-1]), word, '\n')
    		i = i + len(word[len(word)-1])
    	else:
    		break
    
    print(word_split)
    
    """
    [['我们的'], ['计算语言学'], ['课程'], ['有'], ['意思']]
    """

             负向匹配算法:

            首先我们定义一个最大分割长度5,从右往左开始分割:

    •   (1) 首先取出来的候选词W是 “课程有意思”。
    •   (2) 查词表,W不在词表中,将W最左边的第一个字去掉,得到W“程有意思”;
    •   (3) 查词表,W也不在词表中,将W最左边的第一个字去掉,得到W“有意思”;
    •   (4) 查词表,W也不在词表中,将W最左边的第一个字再去掉,得到W“意思”;
    •   (5) 查词表,W在词表中,就将W从整个句子中拆分出来,此时原句子为“计算语言学课程有”
    •   (6) 根据分割长度5,截取句子内容,得到候选句W是“言学课程有”;
    •   (7) 查词表,W不在词表中,将W最左边的第一个字去掉,得到W“学课程有”;
    •   (8) 查词表,W也不在词表中,将W最左边的第一个字去掉,得到W“课程有”;
    •   (9) 依次类推,直到W为“有”一个词的时候,这时候将W从整个句子中拆分出来,此时句子为“计算语言学课程”
    •   (10) 根据分割长度5,截取句子内容,得到候选句W是“算语言学课程”;
    •   (11) 查词表,W不在词表中,将W最左边的第一个字去掉,得到W“语言学课程”;
    •   (12) 依次类推,直到W为“课程”的时候,这时候将W从整个句子中拆分出来,此时句子为“计算语言学”
    •   (13) 根据分割长度5,截取句子内容,得到候选句W是“计算语言学”;
    •   (14)  查词表,W在词表,分割结束。

     

    """ 2、负向匹配
    # 文本
    text = '我们的计算语言学课程有意思'
    textlen = len([i for i in text])
    print([i for i in text], '\n', len([i for i in text]), '\n'*2)
    
    # sentence=["计", "算", "语", "言", "学", "课", "程", "有", "意", "思"]
    # 词库
    dict_1 = ["计算", "计算语言学", "课程", "有", "意思", "我们", "的", "我们的"]
    len_dict = [len(i) for i in dict_1]
    print(len_dict, '\n', max(len_dict), '\n'*2)
    
    # 匹配结果存储
    word_split = []
    
    # 定义负向匹配最大长度,一般为词库中最大长度的词的长度
    nega_len = max(len_dict)
    i = 0
    
    for _ in range(textlen):
    	for j in range(nega_len):
    		# print(text[(textlen-i-nega_len+j):(textlen-i)])
    		if text[(textlen-i-nega_len+j):(textlen-i)] in dict_1:
    			word_split.append(text[(textlen-i-nega_len+j):(textlen-i)])
    			i = i + len([ia for ia in text[(textlen-i-nega_len+j):(textlen-i)] ])
    
    print(word_split)
    """
    
    """
    ['我', '们', '的', '计', '算', '语', '言', '学', '课', '程', '有', '意', '思'] 
     13 
    
    
    [2, 5, 2, 1, 2, 2, 1, 3] 
     5 
    
    
    ['意思', '有', '课程', '计算语言学', '我们的']
    
    """

     

    展开全文
  • 中文分词算法

    2013-04-15 19:10:28
    包括基于统计的贝叶斯算法,和ChineseAnalysis和IKAnalysis开源算法
  • 本文档是技术分享的PPT,详解深入讲解了三种中文分词算法,包知ik、mmseg、hanlp。文档中还分析了ik的岐义消除规则相关代码,以及hanlp最短路径算法原理及代码实现。
  • 提供了最大逆向分词算法的伪代码,根据伪代码可以写各种语言下的分词程序
  • 1、原理介绍  MMSEG消除歧义的规则有四个,它在使用中依次用这四个规则进行过滤,直到只有一种结果或者第四个规则使用... 这里先不实现,主要是想先学基于统计的和机器学习的分词算法,先留个彩蛋,过几天再实现
  • 中文分词算法讲解非常好的一篇paper
  • 中文分词算法

    2009-06-22 09:57:00
    这里主要介绍了我自己的中文分词算法,我觉得它比现在开源代码比较多的中文匹配法要好多了。这里的内容没有任何背景知识啥的,毕竟论文里的背景知道我也是从网上粘贴的,呵呵!因此这篇文章的内容可能适合做搜索引擎...
  • 中文分词算法总结

    万次阅读 2019-07-24 10:10:25
    中文分词基本算法主要分类 基于词典的方法、基于统计的方法、基于规则的方法、(传说中还有基于理解的-神经网络-专家系统,按下不表) 1、基于词典的方法(字符串匹配,机械分词方法) 定义:按照一定策略将待分析...
  • 中文分词算法—最大匹配法1 正向最大匹配法FMM2 反向最大匹配法BMM3 双向最大匹配法4 python实现代码5 参考文献 1 正向最大匹配法FMM 2 反向最大匹配法BMM 3 双向最大匹配法 4 python实现代码 5 参考文献 user_dict ...
  • 中文分词 java 代码

    2017-04-13 22:01:28
    中文分词 java 代码
  • 中文分词算法经典

    千次阅读 2011-11-23 20:49:16
    这一篇关于搜索引擎中中文分词算法经典的文章,不敢独享。仅就对小几处的别字做了修改。 中文分词算法 1.1.1 最大匹配法分词的缺陷 尽管最大匹配法分词是常用的解决的方案,但是无疑它存在很多明显的缺陷,这些...
  • 大神求帮忙 想找基于词典机制的中文分词算法的源代码,3-4种,用于毕设的研究,请大神帮忙 QQ:307729948 请注明 中文分词算法,,,谢谢了

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,878
精华内容 6,351
关键字:

中文分词算法代码