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

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

作者: IT小叮当 | 来源:发表于2023-03-13 10:48 被阅读0次

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

    分词(Tokenize)

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

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

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

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

    具体代码如下:

    #!/usr/bin/env python

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

    __author__ = 'IT小叮当'

    date: 2018 / 10 / 18

    import nltk

    nltk.download('punkt')

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

    具体代码如下:

    #!/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)

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

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

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

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

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

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

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

  1. 启发式(Heuristic):

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

  3. 深度学习:

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

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

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

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

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

    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仍然能够正确的划分为“小明/来到/了/网易/杭研/大厦”

  5. 社交网络上的文本分词

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

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

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

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

    代码如下:

    #!/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))

    处理后的结果如下:

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

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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/oelcrdtx.html