【自然语言处理系列】掌握NLP基础:去停用词、词性标注与命名实体识别实战教程

发布于:2024-06-29 ⋅ 阅读:(16) ⋅ 点赞:(0)

 摘要:本系列教程专注于自然语言处理(NLP)中的基础元素,包括去停用词、词性标注以及命名实体识别。这些步骤是文本预处理和分析不可或缺的组成部分。我们将通过具体的实例和技术演示,讲解如何使用Python及其相关库(如NLTK)进行有效的文本数据处理。从去除无关词汇到识别关键实体,提供详细的操作指导和实际应用案例,帮助读者提升在文本挖掘和数据分析领域的技能。

目录

一、查看停用词表

二、过滤停用词

三、词性标注

 四、基于NLTK的正则表达式分块与可视化

五、命名实体识别

六、数据清洗实例


停用词(Stop words)是指在文本预处理中被移除的常见单词,因为它们对于文本的分析和处理通常没有实际意义或贡献。这些词往往是语境中的功能性词汇,如介词(例如“在”,“对于”)、冠词(“一个”,“这个”)和连词(“和”,“但是”)。停用词的去除有助于减少数据的维度,从而提升文本挖掘算法的效率和准确性,尤其是在进行词频统计、关键词提取或构建词袋模型时。不同语言有不同的停用词列表,且根据应用场景的不同,停用词列表的内容也会有所调整。

一、查看停用词表

NLTK提供的停用词表涵盖了多种语言,可以用来移除不同语言文本中的停用词。

二、过滤停用词

首先,通过将单词转换为小写来创建列表 test_words,确保单词的大小写一致性。接着,将 test_words 转换为集合 test_words_set,以去除重复元素。然后,使用列表生成式从 test_words_set 中过滤掉英语停用词,生成新列表 filtered。最后,通过计算 test_words_set 和英语停用词集合的交集,确认哪些停用词被从 test_words_set 中移除,以优化文本分析结果。

 

三、词性标注

词性标注是自然语言处理中的一个重要步骤,它涉及将单词分配到相应的词类,如名词、动词、形容词等。下表总结了常见的词性标注符号(POS Tag)及其对应的指代,并对tokens中包含的词使用nltk中的pos_tag函数进行了词性标注。

 四、基于NLTK的正则表达式分块与可视化

使用NLTK库中的RegexpParser模块根据指定的语法规则对句子进行分块。在这个例子中,"the" (DT) - 限定词、"little" (JJ) - 形容词、"yellow" (JJ) - 形容词、"dog" (NN) - 名词、"died" (VBD) - 动词,过去式。语法规则表示名词短语(NP)可以由一个可选的限定词(DT)、零个或多个形容词(JJ)和一个名词(NN)组成。通过这个规则,代码将句子分成了名词短语和其他部分。最后,代码调用matplotlib库将分块结果可视化,以便更好地理解和分析句子的结构。

五、命名实体识别

在自然语言处理(NLP)的过程中,首先使用word_tokenize函数将句子分解成基本的语言单位,即单词列表。随后,pos_tag函数对这些单独的单词进行词性标注,为每个单词分配一个对应的词性缩写,从而形成单词及其词性的元组列表。这些准备工作完成后,ne_chunk函数进一步分析这个已标注的单词列表,专门识别并标记出文本中的命名实体,如人名、地点、组织名称等。

六、数据清洗实例

本部分进行了一个文本数据清洗的实例分析,对原始文本数据进行了彻底的数据清洗,以去除噪声并突出显示关键信息。首先是通过正则表达式去除HTML标签、特殊符号(如推特句柄和话题标签)以及货币符号。接下来,移除了文本中的超链接和一些常见的英文缩写形式。此外,还去除了多余的空格,并且删除了长度为1或2的单词,这通常包括了一些不太具有分析价值的词。进一步使用了NLTK库来实现自动分词,并将分词后的结果与英语停用词列表进行对比,从而剔除了诸如“is”、“and”和“the”这样的常见词汇。这些词汇虽然在文本中频繁出现,但对于理解文本的主题和结构通常帮助不大。最终,经过这些细致的清洗步骤,得到了一个清晰、整洁的文本数据集,这将为后续的分析工作提供坚实的基础。

 

import re
from nltk.corpus import stopwords
# 输入数据
s = '    RT @Amila #Test\nTom\'s newly listed Co  & Mary\'s unlisted     Group to supply tech for nlTK.\nh $TSLA $AAPL https:// t.co/x34afsfQsh'

#指定停用词
cache_english_stopwords = stopwords.words('english')

def text_clean(text):
    print('原始数据:', text, '\n')
    
    # 去掉HTML标签(e.g. &)
    text_no_special_entities = re.sub(r'\&\w*;|#\w*|@\w*', '', text)
    print('去掉特殊标签后的:', text_no_special_entities, '\n')
    
    # 去掉一些价值符号
    text_no_tickers = re.sub(r'\$\w*', '', text_no_special_entities) 
    print('去掉价值符号后的:', text_no_tickers, '\n')
    
    # 去掉超链接
    text_no_hyperlinks = re.sub(r'https?:\/\/.*\/\w*', '', text_no_tickers)
    print('去掉超链接后的:', text_no_hyperlinks, '\n')

    # 去掉一些专门名词缩写,简单来说就是字母比较少的词
    text_no_small_words = re.sub(r'\b\w{1,2}\b', '', text_no_hyperlinks) 
    print('去掉专门名词缩写后:', text_no_small_words, '\n')
    
    # 去掉多余的空格
    text_no_whitespace = re.sub(r'\s\s+', ' ', text_no_small_words)
    text_no_whitespace = text_no_whitespace.lstrip(' ') 
    print('去掉空格后的:', text_no_whitespace, '\n')
    
    # 分词
    tokens = word_tokenize(text_no_whitespace)
    print('分词结果:', tokens, '\n')    
          
    # 去停用词
    list_no_stopwords = [i for i in tokens if i not in cache_english_stopwords]
    print('去停用词后结果:', list_no_stopwords, '\n')
    # 过滤后结果
    text_filtered =' '.join(list_no_stopwords) # ''.join() would join without spaces between words.
    print('过滤后:', text_filtered)

text_clean(s)

结果如下: