zoukankan      html  css  js  c++  java
  • 关于文本处理之结巴分词

    中文文本最常用的就我而言应该就是结巴分词的分词工具。当然还有其他分词工具Hanlp、THULAC、LTP、NLPIR等。

    结巴分词安装:pip install jieba(全自动安装)

    or 下载结巴,然后解压运行python setup.py install(半自动)

    or python3.X 下的安装方式:

    Github 上 jieba 的 Python3.x 版本的路径是:https://github.com/fxsjy/jieba/tree/jieba3k

    通过 git clone https://github.com/fxsjy/jieba.git 命令下载到本地,然后解压,再通过命令行进入解压目录,执行 python setup.py install 命令,即可安装成功。

    jieba 的分词算法

     

    主要有以下三种:

     

    基于统计词典,构造前缀词典,基于前缀词典对句子进行切分,得到所有切分可能,根据切分位置,构造一个有向无环图(DAG);

     

    基于DAG图,采用动态规划计算最大概率路径(最有可能的分词结果),根据最大概率路径分词;

     

    对于新词(词库中没有的词),采用有汉字成词能力的 HMM 模型进行切分。

     

    jieba 分词

     

    下面我们进行 jieba 分词练习,第一步首先引入 jieba 和语料:

     

    import jieba content = "现如今,机器学习和深度学习带动人工智能飞速的发展,并在图片处理、语音识别领域取得巨大成功。"

     

    (1)精确分词

    精确分词:精确模式试图将句子最精确地切开,精确分词也是默认分词。

    segs_1 = jieba.cut(content, cut_all=False)print("/".join(segs_1))

    其结果为:

    现如今/,/机器/学习/和/深度/学习/带动/人工智能/飞速/的/发展/,/并/在/图片/处理/、/语音/识别/领域/取得/巨大成功/。

     

    (2)全模式

    全模式分词:把句子中所有的可能是词语的都扫描出来,速度非常快,但不能解决歧义。

    segs_3 = jieba.cut(content, cut_all=True) print("/".join(segs_3))

    结果为:

    现如今/如今///机器/学习/和/深度/学习/带动/动人/人工/人工智能/智能/飞速/的/发展///并/在/图片/处理///语音/识别/领域/取得/巨大/巨大成功/大成/成功/ 

    (3)搜索引擎模式

    搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

    segs_4 = jieba.cut_for_search(content) print("/".join(segs_4))

    结果为:

    如今/现如今/,/机器/学习/和/深度/学习/带动/人工/智能/人工智能/飞速/的/发展/,/并/在/图片/处理/、/语音/识别/领域/取得/巨大/大成/成功/巨大成功/。

     

    (4)用 lcut 生成 list

    jieba.cut 以及 jieba.cut_for_search 返回的结构都是一个可迭代的 Generator,可以使用 for 循环来获得分词后得到的每一个词语(Unicode)。jieba.lcut 对 cut 的结果做了封装,l 代表 list,即返回的结果是一个 list 集合。同样的,用 jieba.lcut_for_search 也直接返回 list 集合。

    segs_5 = jieba.lcut(content) print(segs_5)

    结果为:

    ['现如今', ',', '机器', '学习', '和', '深度', '学习', '带动', '人工智能', '飞速', '的', '发展', ',', '并', '在', '图片', '处理', '、', '语音', '识别', '领域', '取得', '巨大成功', '。']

     

    (5)获取词性

    jieba 可以很方便地获取中文词性,通过 jieba.posseg 模块实现词性标注。

    import jieba.posseg as psg print([(x.word,x.flag) for x in psg.lcut(content)])

    结果为:

    [('现如今', 't'), (',', 'x'), ('机器', 'n'), ('学习', 'v'), ('和', 'c'), ('深度', 'ns'), ('学习', 'v'), ('带动', 'v'), ('人工智能', 'n'), ('飞速', 'n'), ('的', 'uj'), ('发展', 'vn'), (',', 'x'), ('并', 'c'), ('在', 'p'), ('图片', 'n'), ('处理', 'v'), ('、', 'x'), ('语音', 'n'), ('识别', 'v'), ('领域', 'n'), ('取得', 'v'), ('巨大成功', 'nr'), ('。', 'x')]

     

    (6)并行分词

    并行分词原理为文本按行分隔后,分配到多个 Python 进程并行分词,最后归并结果。

    用法:

    jieba.enable_parallel(4) # 开启并行分词模式,参数为并行进程数 。jieba.disable_parallel() # 关闭并行分词模式 。

    注意: 并行分词仅支持默认分词器 jieba.dt 和 jieba.posseg.dt。目前暂不支持 Windows。

     

    (7)获取分词结果中词列表的 top n

    from collections import Counter top5= Counter(segs_5).most_common(5) print(top5)

    结果为:

    [(',', 2), ('学习', 2), ('现如今', 1), ('机器', 1), ('和', 1)]

     

    (8)自定义添加词和字典

    默认情况下,使用默认分词,是识别不出这句话中的“铁甲网”这个新词,这里使用用户字典提高分词准确性。

    txt = "铁甲网是中国最大的工程机械交易平台。" print(jieba.lcut(txt))

    结果为:

    ['铁甲', '网是', '中国', '最大', '的', '工程机械', '交易平台', '。']

    如果添加一个词到字典,看结果就不一样了。

    jieba.add_word("铁甲网") print(jieba.lcut(txt))

    结果为:

    ['铁甲网', '是', '中国', '最大', '的', '工程机械', '交易平台', '。']

    但是,如果要添加很多个词,一个个添加效率就不够高了,这时候可以定义一个文件,然后通过 load_userdict()函数,加载自定义词典,如下:

    jieba.load_userdict('user_dict.txt') print(jieba.lcut(txt))

    结果为:

    ['铁甲网', '是', '中国', '最大', '的', '工程机械', '交易平台', '。']

    注意事项:

    jieba.cut 方法接受三个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 HMM 模型。

    jieba.cut_for_search 方法接受两个参数:需要分词的字符串;是否使用 HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细。

    之前在学校文本智能处理的课程上,老师留过作业,就是基于自己的字典来做分词,贴上代码:

     1 # coding:utf-8
     2 import io
     3 import string
     4 import sys
     5 
     6 
     7 dict = {}
     8    
     9 def loadcorpusdict(dict_file='corpus.dict.txt'):       
    10     words = []
    11     for line in io.open(dict_file,encoding='utf-8'):
    12         words.append(line.strip())
    13     for word in words:
    14         first_char = word[0]
    15         dict.setdefault(first_char, [])
    16         dict[first_char].append(word)
    17         
    18     for first_char, words in dict.items():
    19         dict[first_char] = sorted(words, key=lambda x:len(x), reverse=True)
    20 
    21   
    22     
    23 def matchcode(i, input):
    24     result = ''
    25     for i in range(i, len(input)):
    26         if not input[i] in string.ascii_letters: break
    27         result += input[i]
    28     return result
    29    
    30    
    31 def matchword(first_char, i , input):       #和词语匹配
    32     if not first_char in dict:
    33         if first_char in string.ascii_letters:
    34             return matchcode(i, input)
    35         return first_char
    36    
    37     words = dict[first_char]
    38     for word in words:
    39         if input[i:i + len(word)] == word:
    40             return word
    41     return first_char
    42 
    43    
    44 def gettoken(input):      #将匹配的词存入token列表中
    45 
    46     if not input: return []
    47    
    48     tokens = []
    49     i = 0
    50     while i < len(input):
    51         first_char = input[i]
    52         matched_word = matchword(first_char, i, input)
    53         tokens.append(matched_word)
    54         i += len(matched_word)  
    55     return tokens
    56 
    57 
    58 def test(textname):      #测试函数
    59     loadcorpusdict()
    60     text = []
    61     for line in io.open(textname,encoding='utf-8'):
    62         text.append(line)
    63    
    64     f = io.open('20154432.answer.txt','wb+')
    65     for each in text:
    66         tokens = gettoken(each)
    67         for token in tokens:
    68             f.write(token)
    69             f.write(' ')    
    70    
    71    
    72 if __name__ == '__main__':
    73     
    74     reload(sys)
    75     sys.setdefaultencoding('utf-8')  #转码问题
    76     test('corpus.sentence.txt')
    77 
    78 
    79     

    corpus.sentence.txt为文章原文,corpus.dic.txt为自定义字典  输出结果到20154432.answer.txt。

    因为正在做毕设,用到了分词,特此来记录一下,若今后能帮助到其他人也是不错的。

    特此感谢:http://www.360doc.cn/mip/798383129.html  lanlantian123  以上很多均转载&总结于其文章 

  • 相关阅读:
    js中url跳转问题
    代码走查整理总结
    关于前后端分离跨域请求问题
    mysql大小写敏感问题
    初识react
    mysql测试
    关于使用Ajax请求json数据,@RequestMapping返回中文乱码的几种解决办法
    ssm实现分页查询
    js表单验证处理和childNodes 和children 的区别
    javaScript数组操作整理
  • 原文地址:https://www.cnblogs.com/baobaotql/p/10702463.html
Copyright © 2011-2022 走看看