标准化、分词、停用词去除和词形还原这些用于清洗和组织原始文本的单独技术,被整合以构建一套完整的文本预处理流程。构建这样的流程是许多NLP应用中的一个常见首要步骤,它能确保文本数据的一致性,并为后续分析或模型训练做好准备。我们将使用Python以及NLTK或spaCy等常用库。请确保您已安装这些库并下载了所需的资源(如停用词列表和词形还原模型)。# NLTK 示例设置(如果需要,请在您的 Python 环境中运行这些命令) # import nltk # nltk.download('punkt') # 用于分词 # nltk.download('wordnet') # 用于词形还原 # nltk.download('stopwords') # 用于停用词定义示例数据我们从一些包含需要处理的常见文本变体的示例句子开始:sample_texts = [ "The QUICK brown fox Jumped over the LAZY dog!!", "Preprocessing text data is an important first step.", "We'll be removing punctuation, numbers (like 123), and applying lemmatization.", "Stop words such as 'the', 'is', 'and' will be filtered out." ]我们的目标是将这些原始句子转换为清洗后有意义的词元列表。逐步构建流程一个预处理流程通常执行一系列操作。顺序有时很重要,因此有必要考虑每一步对后续步骤的影响。步骤1:文本标准化(转为小写)将文本转为小写是一种简单但有效的标准化方法,它能确保像“The”和“the”这样的词被视为相同。import re def normalize_text(text): """将文本转为小写并去除所有非字母数字字符。""" text = text.lower() # 使用正则表达式去除标点和数字 text = re.sub(r'[^a-z\s]', '', text) # 去除多余空格 text = re.sub(r'\s+', ' ', text).strip() return text normalized_texts = [normalize_text(text) for text in sample_texts] print("标准化后的文本:") for text in normalized_texts: print(f"- {text}")Output:Normalized Texts: - the quick brown fox jumped over the lazy dog - preprocessing text data is an important first step - well be removing punctuation numbers like and applying lemmatization - stop words such as the is and will be filtered out在这里,我们将转为小写与去除标点和数字结合起来,使用了正则表达式[^a-z\s],它只保留小写字母和空格。步骤2:分词接下来,我们将标准化后的文本分成单独的单词或词元。我们将使用NLTK的word_tokenize函数。from nltk.tokenize import word_tokenize tokenized_texts = [word_tokenize(text) for text in normalized_texts] print("\n分词后的文本:") for tokens in tokenized_texts: print(f"- {tokens}")Output:Tokenized Texts: - ['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog'] - ['preprocessing', 'text', 'data', 'is', 'an', 'important', 'first', 'step'] - ['well', 'be', 'removing', 'punctuation', 'numbers', 'like', 'and', 'applying', 'lemmatization'] - ['stop', 'words', 'such', 'as', 'the', 'is', 'and', 'will', 'be', 'filtered', 'out']步骤3:停用词去除现在,我们过滤掉对分析通常没有太多语义价值的常见词(停用词)。我们将使用NLTK的标准英语停用词列表,并演示如何添加自定义停用词。from nltk.corpus import stopwords # 获取标准英语停用词 stop_words = set(stopwords.words('english')) # 示例:如果需要,添加特定领域停用词 # stop_words.add('data') # 取消注释以将“data”添加为停用词 def remove_stopwords(tokens): """从词元列表中去除停用词。""" return [token for token in tokens if token not in stop_words] filtered_texts = [remove_stopwords(tokens) for tokens in tokenized_texts] print("\n去除停用词后的文本:") for tokens in filtered_texts: print(f"- {tokens}")Output:Texts after Stop Word Removal: - ['quick', 'brown', 'fox', 'jumped', 'lazy', 'dog'] - ['preprocessing', 'text', 'data', 'important', 'first', 'step'] - ['well', 'removing', 'punctuation', 'numbers', 'like', 'applying', 'lemmatization'] - ['stop', 'words', 'filtered']请注意,像“the”、“is”、“an”、“be”、“and”、“will”、“out”、“such”、“as”这些词已被去除。如果取消注释stop_words.add('data'),单词“data”也会从第二个句子中被去除。根据具体任务或范围自定义停用词列表通常很有用。步骤4:词形还原最后,我们使用词形还原将单词还原为它们的原始或字典形式(词元)。这有助于将一个词的不同变体归为一类。我们将使用NLTK的WordNetLemmatizer。from nltk.stem import WordNetLemmatizer lemmatizer = WordNetLemmatizer() def lemmatize_tokens(tokens): """对词元列表进行词形还原。""" # 注意:通过提供词性标签可以改进词形还原效果, # 但为简单起见,这里我们使用默认(名词)处理。 return [lemmatizer.lemmatize(token) for token in tokens] lemmatized_texts = [lemmatize_tokens(tokens) for tokens in filtered_texts] print("\n词形还原后的文本:") for tokens in lemmatized_texts: print(f"- {tokens}")Output:Lemmatized Texts: - ['quick', 'brown', 'fox', 'jumped', 'lazy', 'dog'] - ['preprocessing', 'text', 'data', 'important', 'first', 'step'] - ['well', 'removing', 'punctuation', 'number', 'like', 'applying', 'lemmatization'] - ['stop', 'word', 'filtered']可以看到,“jumped”保持不变(因为默认的词形还原POS标签是名词),“numbers”变为“number”,“words”变为“word”。更复杂的词形还原会在词形还原之前进行词性(POS)标注,以获得更准确的基本形式(例如,如果被标注为动词,则将“jumped”正确地还原为“jump”)。整合为一个可复用函数让我们将这些步骤整合到一个单一的函数中,以便于复用。import re from nltk.tokenize import word_tokenize from nltk.corpus import stopwords from nltk.stem import WordNetLemmatizer # 一次性初始化资源 stop_words = set(stopwords.words('english')) lemmatizer = WordNetLemmatizer() def preprocess_text(text): """将完整的预处理流程应用于单个文本字符串。""" # 1. 标准化(小写,去除标点/数字) text = text.lower() text = re.sub(r'[^a-z\s]', '', text) text = re.sub(r'\s+', ' ', text).strip() # 2. 分词 tokens = word_tokenize(text) # 3. 去除停用词 filtered_tokens = [token for token in tokens if token not in stop_words] # 4. 词形还原 lemmatized_tokens = [lemmatizer.lemmatize(token) for token in filtered_tokens] return lemmatized_tokens # 将流程应用于我们的原始示例 processed_texts = [preprocess_text(text) for text in sample_texts] print("\n完全处理后的文本:") for tokens in processed_texts: print(f"- {tokens}")Output:Fully Processed Texts: - ['quick', 'brown', 'fox', 'jumped', 'lazy', 'dog'] - ['preprocessing', 'text', 'data', 'important', 'first', 'step'] - ['well', 'removing', 'punctuation', 'number', 'like', 'applying', 'lemmatization'] - ['stop', 'word', 'filtered']这个preprocess_text函数现在封装了我们整个流程。流程可视化我们可以使用一个简单的图表来呈现操作序列:digraph G { rankdir=LR; node [shape=box, style=filled, color="#ced4da", fillcolor="#e9ecef"]; edge [color="#495057"]; "原始文本" -> "标准化" -> "分词" -> "去除停用词" -> "词形还原" -> "处理后的词元" [color="#1c7ed6", penwidth=1.5]; }一个图表,展示了文本预处理流程中的步骤顺序。注意事项操作顺序: 在分词之前去除标点与之后去除有何不同?通常,先去除标点可以简化分词。转为小写应该在去除停用词之前还是之后?如果停用词是小写,文本也必须先转为小写。设计流程时,请考虑这些相互影响。库的选择: 我们这里使用了NLTK,但spaCy提供了类似(通常更集成和高效)的预处理功能。例如,spaCy的处理能够一次性处理分词、词形还原和词性标注。定制: 这个流程只是一个模板。您可能需要根据您的具体文本数据和任务要求添加步骤(例如,处理缩写、拼写校正)或修改现有步骤(例如,使用词干提取代替词形还原、微调正则表达式以去除噪声、构建高度定制的停用词列表)。这个实践练习展示了如何将基本的文本预处理技术组合构建一个可用的流程。生成的清洗并还原词形的词元现在处于更好的状态,可用于后续的NLP任务,比如我们将在下一章介绍的特征工程方法。