ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

NLP基础到高级01:文本处理 — 分词、词干提取、词形还原

NLP基础到高级01:文本处理 — 分词、词干提取、词形还原 文本处理 — 分词、词干提取、词形还原语言是连续的模型是离散的。预处理是连接两者的桥梁。类型构建语言Python前置条件Phase 2 · 14 (朴素贝叶斯)用时~45 分钟问题所在模型无法直接读取 “The cats were running.”它读取的是整数。每个 NLP 系统都面临同样的三个问题一个词从哪里开始词的词根是什么什么时候应该把 “run”、“running”、“ran” 当作同一个东西什么时候又应该区分对待分词做错了模型就从垃圾数据中学习。如果你的分词器把dont当作一个 token却把do nt当作两个训练分布就会出现分裂。如果你的词干提取器把organization和organ归结为相同的词干主题建模就会失效。如果你的词形还原器需要词性上下文信息但你没有传入动词就会被当作名词处理。本课从头构建三个预处理原语然后展示 NLTK 和 spaCy 如何完成同样的工作让你看清各自的权衡取舍。核心概念三个操作。每个都有自己的职责和失败模式。分词 (Tokenization)将字符串拆分为 token。“Token” 这个词是刻意模糊的因为合适的粒度取决于具体任务。经典 NLP 用词级别Transformer 用子词级别没有空格的语言用字符级别。词干提取 (Stemming)用规则截断后缀。快速、激进、粗暴。running - run。organization - organ。第二个例子就是它的失败模式。词形还原 (Lemmatization)利用语法知识将单词还原为其词典形式。较慢、准确、需要查找表或形态分析器。ran - run需要知道 “ran” 是 “run” 的过去式。better - good需要知道比较级形式。经验法则当速度重要且能容忍噪声时用词干提取搜索索引、粗略分类。当语义重要时用词形还原问答系统、语义搜索、任何用户会阅读的场景。动手构建步骤 1一个基于正则表达式的分词器最简单且实用的分词器在非字母数字字符处拆分同时将标点符号保留为独立的 token。不完美也不是最终方案但一行代码就能运行。importredeftokenize(text):returnre.findall(r[A-Za-z](?:[A-Za-z])?|[0-9]|[^\sA-Za-z0-9],text)三个按优先级排列的模式。带可选内部撇号的单词dont、its。纯数字。任何单个非空白非字母数字字符作为独立 token标点符号。tokenize(The cats werent running at 3pm.)[The,cats,werent,running,at,3,pm,.]需要注意的失败模式。3pm被拆分为[3, pm]因为我们在字母序列和数字序列之间做了交替。对大多数任务来说够用了。URL、邮箱、话题标签都会出问题。生产环境中需要在通用模式之前添加特定的匹配模式。步骤 2Porter 词干提取器仅步骤 1a完整的 Porter 算法有五个阶段的规则。仅步骤 1a 就覆盖了最常见的英语后缀并展示了核心模式。defstem_step_1a(word):ifword.endswith(sses):returnword[:-2]ifword.endswith(ies):returnword[:-2]ifword.endswith(ss):returnwordifword.endswith(s)andlen(word)1:returnword[:-1]returnword[stem_step_1a(w)forwin[caresses,ponies,caress,cats]][caress,poni,caress,cat]从上往下读规则。ies - i规则导致了ponies - poni而非pony。完整的 Porter 算法有步骤 1b 会修正这个问题。规则之间存在竞争排在前面的规则优先。顺序比任何单条规则都重要。步骤 3基于查找表的词形还原器真正的词形还原需要形态学知识。一个可教学用的简化版本使用小型词元表加回退策略。LEMMA_TABLE{(running,VERB):run,(ran,VERB):run,(runs,VERB):run,(better,ADJ):good,(best,ADJ):good,(cats,NOUN):cat,(cat,NOUN):cat,(were,VERB):be,(was,VERB):be,(is,VERB):be,}deflemmatize(word,pos):key(word.lower(),pos)ifkeyinLEMMA_TABLE:returnLEMMA_TABLE[key]ifposVERBandword.endswith(ing):returnword[:-3]ifposNOUNandword.endswith(s):returnword[:-1]returnword.lower()lemmatize(running,VERB)runlemmatize(cats,NOUN)catlemmatize(better,ADJ)goodlemmatize(watched,VERB)watched最后一个案例是关键的教学时刻。watched不在我们的表中而我们的回退策略只处理ing结尾的情况。真正的词形还原需要覆盖ed结尾、不规则动词、形容词比较级、语音变化的复数形式children - child。这就是为什么生产系统使用 WordNet、spaCy 的形态分析器或完整的形态分析器。步骤 4将它们串联起来defpreprocess(text,pos_taggerNone):tokenstokenize(text)stems[stem_step_1a(t.lower())fortintokens]tagspos_tagger(tokens)ifpos_taggerelse[(t,NOUN)fortintokens]lemmas[lemmatize(word,pos)forword,posintags]return{tokens:tokens,stems:stems,lemmas:lemmas}缺失的部分是词性标注器。Phase 5 · 07词性标注会构建一个。目前默认所有词为NOUN并承认这个局限性。实际应用NLTK 和 spaCy 提供了生产级版本。各只需几行代码。NLTKimportnltk nltk.download(punkt_tab)nltk.download(wordnet)nltk.download(averaged_perceptron_tagger_eng)fromnltk.tokenizeimportword_tokenizefromnltk.stemimportPorterStemmer,WordNetLemmatizerfromnltkimportpos_tag textThe cats were running.tokensword_tokenize(text)stems[PorterStemmer().stem(t)fortintokens]lemmatizerWordNetLemmatizer()taggedpos_tag(tokens)defnltk_pos_to_wordnet(tag):iftag.startswith(V):returnviftag.startswith(J):returnaiftag.startswith(R):returnrreturnnlemmas[lemmatizer.lemmatize(t,nltk_pos_to_wordnet(tag))fort,tagintagged]word_tokenize处理缩写、Unicode 以及你的正则表达式会遗漏的边缘情况。PorterStemmer运行所有五个阶段。WordNetLemmatizer需要将词性标注从 NLTK 的 Penn Treebank 标注体系转换为 WordNet 的缩写集。上面的转换代码是大多数教程会跳过的关键部分。spaCyimportspacy nlpspacy.load(en_core_web_sm)docnlp(The cats were running.)fortokenindoc:print(token.text,token.lemma_,token.pos_)The the DET cats cat NOUN were be AUX running run VERB . . PUNCTspaCy 将整个管道隐藏在nlp(text)背后。分词、词性标注和词形还原全部自动执行。大规模处理时比 NLTK 更快开箱即用更准确。代价是你无法轻松替换单个组件。如何选择场景选择教学、研究、需要替换组件NLTK生产环境、多语言、速度要求高spaCyTransformer 管道你反正会用模型的分词器使用tokenizers/transformers跳过经典预处理没人会警告你的两种失败模式大多数教程教完算法就停了。有两种情况会在真正的预处理管道中给你带来麻烦而它们几乎从未被提及。可复现性漂移。NLTK 和 spaCy 在不同版本间会改变分词和词形还原的行为。在 spaCy 2.x 中产生[do, nt]的结果在 3.x 中可能产生[dont]。你的模型在一个分布上训练推理时却运行在另一个分布上。准确率悄悄下降却没人知道原因。在requirements.txt中锁定库版本。编写一个预处理回归测试固化 20 个样例句子的预期分词结果。每次升级时运行它。训练/推理不匹配。训练时用了激进的预处理小写化、停用词移除、词干提取部署时直接处理原始用户输入性能直线下降。这是生产环境 NLP 中最常见的失败。如果在训练时做了预处理推理时必须运行完全相同的函数。将预处理作为模型包内的函数交付而不是让服务团队重写一个 notebook 单元格。交付一个可复用的 prompt帮助工程师选择预处理策略而不用啃三本教科书。保存为outputs/prompt-preprocessing-advisor.md--- name: preprocessing-advisor description: Recommends a tokenization, stemming, and lemmatization setup for an NLP task. phase: 5 lesson: 01 --- You advise on classical NLP preprocessing. Given a task description, you output: 1. Tokenization choice (regex, NLTK word_tokenize, spaCy, or transformer tokenizer). Explain why. 2. Whether to stem, lemmatize, both, or neither. Explain why. 3. Specific library calls. Name the functions. Quote the POS-tag translation if NLTK is involved. 4. One failure mode the user should test for. Refuse to recommend stemming for user-visible text. Refuse to recommend lemmatization without POS tags. Flag non-English input as needing a different pipeline.练习简单。扩展tokenize以将 URL 保留为单个 token。测试tokenize(Visit https://example.com today.)应产生一个 URL token。中等。实现 Porter 步骤 1b。如果单词包含元音且以ed或ing结尾则移除后缀。处理双辅音规则hopping - hop而非hopp。困难。构建一个词形还原器使用 WordNet 作为查找表当 WordNet 没有条目时回退到你的 Porter 词干提取器。在标注语料库上测量准确率与纯 WordNet 和纯 Porter 进行对比。关键术语术语人们的说法实际含义Token一个词模型消耗的任何单位。可以是词、子词、字符或字节。Stem词的词根基于规则的后缀截断结果。不一定是真正的词。Lemma词典形式你会去词典中查找的形式。需要语法上下文才能正确计算。POS tag词性如 NOUN、VERB、ADJ 等类别。准确词形还原所必需的。Morphology词形变化规则词如何根据时态、数、格变化形式。词形还原依赖于它。
返回列表