
Python 自然语言处理入门指南
图片作者 | Canva 创建
学习自然语言处理可以为您的开发者工具包增添超有用的技能。从基础知识到构建由 LLM 驱动的应用程序,您可以在几周内逐步掌握自然语言处理。本文将帮助您入门。
在本文中,我们将学习使用 Python 进行自然语言处理的基础知识——我们采用代码优先的方法,使用 NLTK(自然语言工具包)。让我们开始吧!
▶️ 本教程的 Google Colab 笔记本链接
安装 NLTK
在深入了解 NLP 任务之前,我们需要安装 自然语言工具包 (NLTK)。NLTK 提供了一套文本处理工具——分词器、词形还原器、词性标注器和预加载数据集。它更像是一个 NLP 的瑞士军刀。设置它包括安装库和下载必要的数据集和模型。
安装 NLTK 库
在您的终端或命令提示符中运行以下命令来安装 NLTK
1 |
$ pip install nltk |
这将安装核心 NLTK 库,其中包含文本处理任务所需的主要模块。
下载 NLTK 资源
安装后,下载 NLTK 的预打包数据集和工具。其中包括停用词列表、分词器和 WordNet 等词典
1 2 3 4 5 6 7 8 9 10 |
import nltk # 下载基本数据集和模型 nltk.download('punkt') # 用于句子和词语分词的分词器 nltk.download('stopwords') # 常用停用词列表 nltk.download('wordnet') # 用于词形还原的 WordNet 词汇数据库 nltk.download('averaged_perceptron_tagger_eng') # 词性标注器 nltk.download('maxent_ne_chunker_tab') # 命名实体识别模型 nltk.download('words') # 用于 NER 的词语语料库 nltk.download('punkt_tab') |
文本预处理
文本预处理是 NLP 中必不可少的一步,它将原始文本转换为干净且结构化的格式,使其更易于分析。目标是专注于文本中有意义的组成部分,同时将文本分解为可处理的块。
在本节中,我们将介绍三个重要的预处理步骤:分词、停用词去除和词干提取。
分词
分词是常见的预处理任务之一。它涉及将文本拆分成更小的单元——标记。这些标记可以是单词、句子,甚至可以是子词单元,具体取决于任务。
- 句子分词将文本拆分成句子
- 词语分词将文本拆分成单词和标点符号
在下面的代码中,我们使用 NLTK 的 sent_tokenize 将输入文本拆分成句子,并使用 word_tokenize 将其拆分成单词。但我们也做了一个超级简单的预处理步骤,即从文本中删除所有标点符号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import string from nltk.tokenize import word_tokenize, sent_tokenize text = "Natural Language Processing (NLP) is cool! Let's explore it." # 使用 string.punctuation 删除标点符号 cleaned_text = ''.join(char for char in text if char not in string.punctuation) print("Text without punctuation:", cleaned_text) # 句子分词 sentences = sent_tokenize(cleaned_text) print("Sentences:", sentences) # 词语分词 words = word_tokenize(cleaned_text) print("Words:", words) |
这使我们能够从句子和单词层面分析文本结构。
在此示例中,sent_tokenize(text) 将输入字符串拆分为句子,返回一个句子字符串列表。此函数的输出是一个包含两个元素的列表:原始文本中的每个句子对应一个元素。
接下来,对同一文本应用 word_tokenize(text) 函数。它将文本分解为单个单词和标点符号,将括号和感叹号等视为单独的标记。但我们已经删除了所有标点符号,因此输出如下
1 2 3 |
Text without punctuation: Natural Language Processing NLP is cool Lets explore it Sentences: ['Natural Language Processing NLP is cool Lets explore it'] Words: ['Natural', 'Language', 'Processing', 'NLP', 'is', 'cool', 'Lets', 'explore', 'it'] |
停用词移除
停用词是常见的词语,例如“the”、“and”或“is”,它们出现频繁但在大多数分析中意义不大。删除这些词语有助于专注于文本中更有意义的词语。
本质上,您会过滤掉停用词以减少数据集中的噪音。我们可以使用 NLTK 的 stopwords 语料库来识别和删除分词后获得的标记列表中的停用词
1 2 3 4 5 6 7 8 |
from nltk.corpus import stopwords # 加载 NLTK 的停用词列表 stop_words = set(stopwords.words('english')) # 过滤掉停用词 filtered_words = [word for word in words if word.lower() not in stop_words] print("Filtered Words:", filtered_words) |
在这里,我们使用 NLTK 的 stopwords.words('english') 加载英语停用词集。然后,我们使用列表推导式遍历由 word_tokenize 生成的标记列表。通过检查每个标记(转换为小写)是否在停用词集中,我们删除了对文本意义没有贡献的常见词。
以下是过滤后的结果
1 |
Filtered Words: ['Natural', 'Language', 'Processing', 'NLP', 'cool', 'Lets', 'explore'] |
词干提取
词干提取是将单词还原为词根形式的过程,方法是去除词缀,如后缀和前缀。词根形式可能不总是词典中的有效单词,但它有助于标准化同一单词的变体。
Porter Stemmer 是一种常见的词干提取算法,通过去除后缀来工作。让我们使用 NLTK 的 PorterStemmer 来提取过滤后的单词列表的词干
1 2 3 4 5 6 7 8 |
from nltk.stem import PorterStemmer # 初始化 Porter Stemmer stemmer = PorterStemmer() # 对过滤后的单词应用词干提取 stemmed_words = [stemmer.stem(word) for word in filtered_words] print("Stemmed Words:", stemmed_words) |
在这里,我们初始化了 PorterStemmer 并使用它来处理 filtered_words 列表中的每个单词。
stemmer.stem() 函数从单词中去除常见的后缀,如“-ing”、“-ed”和“-ly”,以将它们还原为词根形式。虽然词干提取有助于减少单词的变体数量,但值得注意的是,结果可能不总是有效的词典单词。
1 |
Stemmed Words: ['natur', 'languag', 'process', 'nlp', 'cool', 'let', 'explor'] |
在继续之前,这里是文本预处理步骤的总结
- 分词将文本分解为更小的单元。
- 停用词移除过滤掉常见、无意义的词语,以便在分析中专注于更有意义的术语。
- 词干提取将单词还原为词根形式,简化变体并有助于标准化文本以进行分析。
完成这些预处理步骤后,您可以继续学习词形还原、词性标注和命名实体识别。
词形还原
词形还原与词干提取类似,因为它也将单词还原为基本形式。但与词干提取不同,词形还原返回有效的词典词。词形还原会考虑上下文(例如其词性 (POS))以将单词还原为词元。例如,单词“running”和“ran”将被还原为“run”。
词形还原通常比词干提取产生更准确的结果,因为它将单词保留在可识别的形式。NLTK 中最常用的词形还原工具是 WordNetLemmatizer,它使用 WordNet 词汇数据库。
- 词形还原通过考虑单词的含义和上下文将其还原为词元,而不仅仅是去除词缀。
- WordNetLemmatizer 是 NLTK 中常用于词形还原的工具。
在下面的代码片段中,我们使用 NLTK 的 WordNetLemmatizer 从之前过滤的列表中对单词进行词形还原
1 2 3 4 5 6 7 8 |
from nltk.stem import WordNetLemmatizer # 初始化词形还原器 lemmatizer = WordNetLemmatizer() # 对每个单词进行词形还原 lemmatized_words = [lemmatizer.lemmatize(word, pos='v') for word in filtered_words] print("Lemmatized Words:", lemmatized_words) |
在这里,我们初始化了 WordNetLemmatizer 并使用其 lemmatize() 方法处理 filtered_words 列表中的每个单词。我们指定 pos='v' 来告诉词形还原器我们希望将文本中的动词还原为词根形式。这有助于词形还原器理解词性并应用正确的词形还原规则。
1 |
Lemmatized Words: ['Natural', 'Language', 'Processing', 'NLP', 'cool', 'Lets', 'explore'] |
那么为什么词形还原有帮助呢?词形还原在您希望将单词还原为基本形式但仍保留其含义时特别有用。与词干提取相比,它是一种更准确、更具上下文敏感性的方法。这使得它非常适合需要高准确性的任务,例如文本分类或情感分析。
词性 (POS) 标注
词性 (POS) 标注涉及识别句子中每个单词的语法类别,例如名词、动词、形容词、副词等。词性标注还有助于理解句子的句法结构,从而更好地处理文本解析、信息提取和机器翻译等任务。
分配给单词的 POS 标签可以基于标准集,例如 Penn Treebank POS 标签。例如,在句子“The dog runs fast”中,“dog”将被标记为名词 (NN),“runs”为动词 (VBZ),“fast”为副词 (RB)。
- POS 标注为句子中的单词分配标签。
- 标注有助于分析句子语法并理解上下文中的单词功能。
使用 NLTK,您可以使用 pos_tag 函数执行 POS 标注,该函数用其词性标注标记列表中的每个单词。在以下示例中,我们首先对文本进行分词,然后使用 NLTK 的 pos_tag 函数为每个单词分配 POS 标签。
1 2 3 4 5 6 7 8 9 10 11 |
from nltk import pos_tag # 将文本分词为单词 text = "She enjoys playing soccer on weekends." # 分词 (单词) words = word_tokenize(text) # POS 标注 tagged_words = pos_tag(words) print("Tagged Words:", tagged_words) |
这应该会输出
1 |
Tagged Words: [('She','PRP'), ('enjoys','VBZ'), ('playing','VBG'), ('soccer','NN'), ('on','IN'), ('weekends','NNS'), ('.','.')] |
POS 标注对于理解句子结构以及涉及句法分析的任务至关重要,例如命名实体识别 (NER) 和机器翻译。
命名实体识别 (NER)
命名实体识别 (NER) 是一项 NLP 任务,用于识别和分类文本中的命名实体,例如人名、组织、地点和日期。这项技术对于理解和从文本中提取有用信息至关重要。
这里有一个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from nltk import ne_chunk, pos_tag, word_tokenize # 示例文本 text = "We shall visit the Eiffel Tower on our vacation to Paris." # 将文本分词为单词 words = word_tokenize(text) # 词性标注 tagged_words = pos_tag(words) # 命名实体识别 named_entities = ne_chunk(tagged_words) print("Named Entities:", named_entities) |
在这种情况下,NER 有助于提取地理参考,例如地标和城市。
1 2 3 4 5 6 7 8 9 10 11 12 |
Named Entities: (S We/PRP shall/MD visit/VB the/DT (ORGANIZATION Eiffel/NNP Tower/NNP) on/IN our/PRP$ vacation/NN to/TO (GPE Paris/NNP) ./.) |
这可以用于各种任务,例如文章摘要、知识图谱的信息提取等等。
总结与下一步
在本指南中,我们涵盖了使用 NLTK 进行自然语言处理的基本概念——从基本的文本预处理到稍微复杂一些的技术,如词形还原、词性标注和命名实体识别。
那么接下来您该怎么做呢?在继续您的 NLP 之旅时,这里有一些下一步要考虑的事项
- 使用逻辑回归、支持向量机和朴素贝叶斯等算法解决简单的文本分类问题。
- 使用 VADER 等工具或训练您自己的分类器进行情感分析。
- 深入研究主题建模或文本摘要任务。
- 探索其他 NLP 库,例如 spaCy 或 Hugging Face 的 Transformers,以获取最先进的模型。
您接下来想学习什么?请告诉我们!继续编程!
非常棒且信息丰富的文章。谢谢。
非常欢迎 Kiran!我们感谢您的支持和反馈!
嗨 James,
一篇很棒的文章,但我不知道像 NLTK 和 SpaCy 这样的工具在当今是否仍然必要,考虑到代理 AI、LLM 的最新进展等?
谢谢
你好 Damien,
您提出了一个有趣且及时的问题!随着大型语言模型 (LLM)(如 GPT、PaLM 和其他模型)的出现,自然语言处理 (NLP) 工具的格局确实正在发生变化。然而,NLTK 和 SpaCy 等工具在某些情况下仍然具有重要价值。
### NLTK 和 SpaCy 何时有用
1. **自定义模型的预处理**
– LLM 在文本生成和理解等任务中表现出色,但在构建较小的、特定领域的模型或管道时,NLTK 和 SpaCy 可以高效地处理分词、词形还原和命名实体识别等任务。
– 它们允许对预处理管道进行细粒度控制,这在 LLM 中可能不容易访问或自定义。
2. **轻量级和高效**
– 对于简单的任务(例如,关键词提取、词性标注),运行一个成熟的 LLM 在计算资源方面可能有点大材小用。像 SpaCy 这样的工具经过优化,可以高效地在有限的硬件上处理此类任务。
3. **透明度和可解释性**
– 与通常是“黑箱”的 LLM 不同,传统 NLP 工具可以更透明地查看所涉及的过程,使其非常适合学术工作、教学或需要可解释性的场景。
4. **边缘和本地解决方案**
– 在具有严格隐私或计算限制的环境中,部署 LLM 可能不可行。特别是 SpaCy,易于集成到边缘应用程序或需要本地部署的系统中。
### 它们过时了吗?
不完全是!虽然代理 AI 和 LLM 可以执行许多相同的任务,但它们
– **需要针对领域特异性进行微调**:开箱即用的 LLM 可能不总是与小众任务完美契合,而传统工具可以提供更量身定制的方法。
– **对于小型任务可能缺乏效率**:如果您只需要解析几个文档或从文本中提取实体,使用一个庞大的 LLM 可能有点大材小用。
### NLP 工作流的未来
我们正在走向混合工作流
– **LLM 用于高级理解**:将 LLM 用于上下文丰富的任务,如摘要、生成或回答问题。
– **传统工具用于特定子任务**:使用 NLTK、SpaCy 或类似工具进行精确、高效的预处理或特定任务(例如,依存分析、基于规则的处理)。
最终,像 NLTK 和 SpaCy 这样的工具是否“必要”取决于手头的任务、资源限制以及您所需的控制或可解释性水平。虽然 LLM 功能强大,但它们并没有完全取代这些传统工具的多功能性和轻量级实用性——至少目前还没有!