当前位置: 首页>大数据>正文

自然语言处理(三)文本处理之分词专题

上次我们了解了文本处理的流程,已经了解了文本处理的大体轮廓。“光说不练假把式!”今天,我们就来实际演练一下文本处理。

自然语言处理(三)文本处理之分词专题,第1张

分词(Tokenize)

分词就是将句子拆分成一个个具有意义的“小部件”。仿佛就是传送带上的一个个小物品。

自然语言处理(三)文本处理之分词专题,第2张

例如“Hello,everyone!”这个句子,经过NLTK分词(还不了解NLTK的可以参考下小叮当深度学习:自然语言处理(一)布朗语料库),这个句子便以词为单位存储在了列表中(包括标点符号)。

自然语言处理(三)文本处理之分词专题,第3张

在使用NLTK执行分词之前,我们需要先安装“punkt”部件。“punkt”包含了许多预训练好的分词模型。如果没有安装“punkt”,我们在使用时系统将会报错,提示我们进行安装。

自然语言处理(三)文本处理之分词专题,第4张

我们执行“import nltk?”、“nltk.download('punkt')”安装“punkt”部件。等待运行完毕,即可。

自然语言处理(三)文本处理之分词专题,第5张

具体代码如下:

#!/usr/bin/env python

# -*- coding:utf-8 -*-

__author__ = 'IT小叮当'

date: 2018 / 10 / 18

import nltk

nltk.download('punkt')

在确认“punkt”已安装之后,我们便可以快乐地使用NLTK进行分词了。可以看到,“Hello ,eveyone!”的分词结果为一个列表,句子中的每个词和标点符号都是列表的一个元素。

自然语言处理(三)文本处理之分词专题,第6张

具体代码如下:

#!/usr/bin/env python

# -*- coding:utf-8 -*-

__author__ = 'IT小叮当'

date: 2018 / 10 / 18

import nltk

sentence = 'hello, everyone!'

tokens = nltk.word_tokenize(sentence)

print("分词后:")

print(tokens)

看到这儿,小伙伴们可能就有疑问了。英文单词之间自带空格,当然就可以直接分词了,那我泱泱华夏华五千年文明传承下来的汉语又该怎么进行分词呢?

自然语言处理(三)文本处理之分词专题,第7张

且不说沈腾的“红鲤鱼绿鲤鱼与驴”,光是断句就很不容易,一不小心就可能理解成别的意思了。

自然语言处理(三)文本处理之分词专题,第8张
自然语言处理(三)文本处理之分词专题,第9张

例如:”汽水不如果汁好喝。”别说计算机了,有的小学生看见也会懵,到底该怎么断句?是“不如”还是“如果”?

自然语言处理(三)文本处理之分词专题,第10张

“我家门前的小河很难过”是河很不好渡过,还是拟人修辞?这样的例子数不胜数~

那么,计算机该怎样应对中文分词呢?

我们以“今天/天气/不错/!"为例,来进行说明。对于英文“what a nice weather today!”计算机直接根据英文空格便可直接分词。

自然语言处理(三)文本处理之分词专题,第11张

对于中文,计算机分词一般有两大类方法:(1)启发式(Heuristic);(2)深度学习、机器学习、统计方法等,例如HMM(隐式马尔可夫)、CRF(条件随机场)等。

  • 启发式(Heuristic):

  • 简单来说,就是你拿着一本现代汉语词典,来对照你要处理的文本。对于”今天天气不错!",你将要判断“今天”、“今天天”、“今天天气”、“今天天气不”、“今天天气不错”等是否在字典里,如果在字典里就进行分词,例如“今天”在字典里,这句话就被分成“今天/天气不错”。之后,以同样的方法判断“天气不错”。最后便可以得到正确的分词“今天/天气/不错”。

    自然语言处理(三)文本处理之分词专题,第12张
  • 深度学习:

  • 另一种中文分词的方法就是深度学习,例如斯坦福大学的CoreNLP原生就支持中文分词。

    自然语言处理(三)文本处理之分词专题,第13张

    简单来说,我们可以发现,中英文分词的主要区别就是“维度不同”。在自然语言处理角度来看,我们的每个汉字对应的就是英文里的每个字母。例如“word”和“千言万语”,在分词时,一个英文单词字母就相当于我们的一个汉字:w--千,o--言,r--万,d--语。

    自然语言处理(三)文本处理之分词专题,第14张

    下面,我们就来看看常用的中文分词工具--Jieba

    在python里jieba十分好用,我们直接import就行,当然如果你没安装jieba的话,可以参考下小叮当python:借用清华更新源,让你的pip飞起来!快速安装jieba(pip install jieba)

    在jieba里我们直接利用cut即可分词。

    自然语言处理(三)文本处理之分词专题,第15张

    jieba分词还可以根据需求设定分词的模式,例如“小明在塞上清华大学”,我们可以有“全模式”、“精确模式”、“搜索引擎模式”。

    (1)全模式:jieba分词将根据最大的组词可能性来进行分词。我们设定“cut_all=True”,可以看到“小明在塞上清华大学”在全模式下的分词结果为:

    “小/明/在/塞上/上清/清华/清华大学/华大/大学”

    在这里可能的组词方式“塞上”、“上清”、“清华”、“华大”、“大学”全部都被罗列出来。

    (2)精确模式:默认情况(不设置“cut_all”)下就是精确模式(cut_all=False)。精确模式,将按最符合汉语习惯的断句来进行分词,往往是最精确的。例如“小明在塞上清华大学”在精确模式下的分词结果为:

    “小明/在/塞上/清华大学”

    (3)搜索引擎模式:将罗列出一句话在搜索引擎里的所有可搜关键字。例如"小明硕士毕业于塞上小清华,后在波士顿大学深造"通过搜索引擎模式后的分词结果为:

    “小明/硕士/毕业/于/塞上/小/清华/,/后/在/波士/大学/波士顿/波士顿大学/深造”

    具体代码如下:

    #!/usr/bin/env python

    # -*- coding:utf-8 -*-

    __author__ = 'IT小叮当'

    date: 2018 / 10 / 30

    import jieba

    sentence1=jieba.cut("小明在塞上清华大学",cut_all=True)

    sentence2=jieba.cut("小明在塞上清华大学",cut_all=False)

    sentence3=jieba.cut("小明在塞上清华大学")

    sentence4=jieba.cut_for_search("小明硕士毕业于塞上小清华,后在波士顿大学深造")

    print("全模式:")

    print("/".join(sentence1))

    print("---------------")

    print("精确模式:")

    print("/".join(sentence2))

    print("---------------")

    print("默认情况:")

    print("/".join(sentence3))

    print("---------------")

    print("搜索引擎模式:")

    print("/".join(sentence4))

    另外,由于Jieba分词的Viterbi算法,它还可以进行一些新词的识别。例如,“小明来到了网易杭研大厦”,“杭研”是一栋大厦的名字,属于新词,但是jieba仍然能够正确的划分为“小明/来到/了/网易/杭研/大厦”

    自然语言处理(三)文本处理之分词专题,第16张
  • 社交网络上的文本分词

  • 在社交网络上,一些乱七八糟、不合语法、不合正常逻辑的语法有很多:比如@某人,表情符号,URL , #话题符号等。

    自然语言处理(三)文本处理之分词专题,第17张

    我们以黄教主和baby某年的推特互动为例进行分析。

    自然语言处理(三)文本处理之分词专题,第18张

    某年,黄教主在推特上艾特了baby,说道“RT @angelababy: love you baby! :D http://ah.love #168.com”

    自然语言处理(三)文本处理之分词专题,第19张

    如果我们对这句话直接分词,将会得到大量的含有特殊符号的“噪声”信息。

    自然语言处理(三)文本处理之分词专题,第20张

    代码如下:

    #!/usr/bin/env python

    # -*- coding:utf-8 -*-

    __author__ = 'IT小叮当'

    date: 2018 / 10 / 31

    from nltk.tokenize import word_tokenize

    tweet = 'RT @angelababy: love you baby! :D http://ah.love #168cm'

    print(word_tokenize(tweet))

    为了去除这些噪声信息,高度还原句子本身所要表达的意思,我们可以使用正则化的方法来实现。

    #!/usr/bin/env?python
    #?-*-?coding:utf-8?-*-??
    __author__?=?'IT小叮当'
    __time__?=?'2019-03-20?16:03'
    from?nltk.tokenize?import?word_tokenize

    #对表情做正则
    import?re
    emoticons_str?=?r"""?
    ?(?:?[:=;]
    ?????[oO\-]??
    ????[D\)\]\(\]/\\OpP]????)"""
    regex_str?=?[
    ????emoticons_str,
    ????r'<[^>]+>',??#?HTML?tags
    ????r'(?:@[\w_]+)',??#?@某?人
    ????r"(?:\#+[\w_]+[\w\'_\-]*[\w_]+)",??#?话题标签
    ????r'http[s]?://(?:[a-z]|[0-9]|[$-_@.&amp;+]|[!*\(\),]|(?:%[0-9a-f][0-9a-f]))+',??#?URLs
    ????r'(?:(?:\d+,?)+(?:\.?\d+)?)',?#?数字
    ????r"(?:[a-z][a-z'\-_]+[a-z])",?#?含有?-?和?‘?的单词
    ????r'(?:[\w_]+)',?#?其他
    ????r'(?:\S)'??#?其他
    ]

    tokens_re?=?re.compile(?r'('+'|'.join(regex_str)+')',?re.VERBOSE?|?re.IGNORECASE?)
    emoticon_re?=?re.compile(?r'^'+emoticons_str+'$',?re.VERBOSE?|?re.IGNORECASE?)


    def?tokenize(s):
    ????return?tokens_re.findall(s)

    def?preprocess(s,?lowercase=False):
    ????tokens?=?tokenize(s)
    ????if?lowercase:
    ????????tokens?=?[token?if?emoticon_re.search(token)?else?token.lower()?for?token?in?tokens]
    ????return?tokens


    tweet?=?'RT?@angelababy:?love?you?baby!?:D?http://ah.love?#168cm'
    print('正则化处理前:')
    print(word_tokenize(tweet))
    print('正则化处理后:')
    print(preprocess(tweet))

    处理后的结果如下:

    自然语言处理(三)文本处理之分词专题,第21张

    可以看到,经过正则化处理的后的tweet社交文本,可以帮助我们识别出简单的符号表情、网址等信息。

    这对于语义的理解是十分重要的!


    https://www.xamrdz.com/bigdata/7g51903035.html

    相关文章: