图机器学习(16)------图数据与自然语言处理
-
- [0. 前言](#0. 前言)
- [1. 数据集分析](#1. 数据集分析)
- [2. NLP 主要概念和工具](#2. NLP 主要概念和工具)
0. 前言
当今时代,海量信息以自然语言的形式存在。晨间浏览的新闻、发送/阅读的推文、课业报告、往来邮件,这些通过文本文档交换的信息构成了人类最主要的间接互动形式(相较于对话、手势等直接互动方式)。无疑,这是最常见的间接互动方式,与直接互动(如谈话或手势)不同。因此,如何有效利用文本信息并从中提取重要信息,已成为至关重要的技术能力。正是文本数据的爆炸性增长,直接推动了自然语言处理 (Natural Language Processing
, NLP
) 领域的快速发展。
本节将系统讲解自然语言文本的处理方法,并回顾一些基本模型用于对文本信息进行结构化。
1. 数据集分析
为介绍如何通过处理文档集来提取关键信息,我们将使用一个 NLP
领域著名基准的数据集,Reuters-21578
。原始数据集包含 21,578
篇新闻文章,这些文章经过分类整理并标注了类别标签。由于原始数据集的类别分布极不均衡(某些类别仅出现在训练集或测试集中),我们将采用经过调整的 ApteMod
版本(亦称 Reuters-21578 Distribution 1.0
),该版本具有更均衡的分布且训练集与测试集的标签保持一致。
Reuters-21578
数据集的每篇文档都附带反映其内容特征的标签集合,这使其成为测试监督式与非监督式算法的理想基准。可以通过 nltk
库下载 Reuters-21578
数据集:
python
from nltk.corpus import reuters
corpus = pd.DataFrame([
{"id": _id, "clean_text": reuters.raw(_id).replace("\n", ""), "label": reuters.categories(_id)}
for _id in reuters.fileids()
]).set_index("id")
通过查看语料库 DataFrame
可以看到,文档 ID
均以 training/{ID}
和 test/{ID}
格式呈现,这清晰界定了训练集与测试集的划分范围。首先,列出所有的主题类别,并统计每个类别下的文档数量:
python
from collections import Counter
Counter([label for document_labels in corpus["label"] for label in document_labels]).most_common()
Reuters-21578
数据集包含 90
个不同主题,但类别分布存在显著不均衡------最常见类别的文档占比高达 37%
,而五个最稀有类别的文档各自仅占 0.01%
。文本检查时会发现部分文档包含换行符,这些字符可在初始文本清洗阶段轻松去除:
corpus = pd.DataFrame([
{"id": _id, "clean_text": reuters.raw(_id).replace("\n", ""), "label": reuters.categories(_id)}
for _id in reuters.fileids()
]).set_index("id")
完成数据加载后,开始进行分析。下一小节将介绍处理非结构化文本数据的主要工具,用于有效提取结构化信息以便后续使用。
2. NLP 主要概念和工具
在处理文档时,首要分析步骤必然是识别文档语言。多数自然语言处理引擎都针对特定语言训练,仅适用于对应语种。因此,常规做法是先确定语言类型,再选用对应的下游 NLP
分析管道。
语言检测可采用多种方法。一种简单有效的方式是通过统计目标语言高频词(即停用词,如英语中的 the/and/be/to/of
等)的出现频率来构建评分体系,但该方法对短文本的识别精度有限,且无法利用词语位置和上下文信息。Python
有许多库可以使用更复杂的逻辑,能够更精确地推断语言,例如,fasttext
、polyglot
和 langdetect
等库。
本节中使用 langdetect
实现语言识别,批量检测所有文档的语言类型:
python
import langdetect
import numpy as np
def getLanguage(text: str):
try:
return langdetect.detect(text)
except:
return np.nan
从输出结果可见,部分文档似乎包含非英语内容。这些文档通常篇幅极短或结构异常,表明其并非真正的新闻稿件。当文档内容符合人类可读的新闻标准时,模型的识别精度通常较高。
完成语言识别后,我们便可继续执行依赖语言特性的分析流程。后续任务将使用 spaCy
,仅需少量代码即可集成 NLP
模型。通过 pip install spaCy
安装后,只需使用 spaCy
下载工具安装特定语言模型即可。例如,下载英语模型:
shell
python -m spacy download en_core_web_sm
安装完成后,即可调用英语模型进行文本分析。spaCy
操作极其简便,一行代码便能生成丰富的文本结构化信息。接下来,以路透社语料库中的一篇文档为例:
shell
SUBROTO SAYS INDONESIA SUPPORTS TIN PACT EXTENSION
Mines and Energy Minister Subroto confirmed Indonesian support for an extension of the sixth International Tin Agreement (ITA), but said a new pact was not necessary. Asked by Reuters to clarify his statement on Monday in which he said the pact should be allowed to lapse, Subroto said Indonesia was ready to back extension of the ITA. "We can support extension of the sixth agreement," he said. "But a seventh accord we believe to be unnecessary." The sixth ITA will expire at the end of June unless a two-thirds majority of members vote for an extension.
加载模型并解析文本:
python
nlp = spacy.load('en_core_web_md')
parsed = nlp(text)
spaCy
返回的 parsed
对象融合了多模型流程的分析结果,提供不同层级的文本结构化信息。我们将逐项解析这些功能:
-
文本分割和分词:该流程旨在将文档拆分为段落、句子和单词(或词元)。此步骤对所有后续分析至关重要,通常利用标点符号、空格和换行符推断分割方式。
spaCy
提供的分割引擎总体表现良好,但需注意:针对包含表情符号、链接和话题标签的短文本(如社交媒体内容),使用nltk
库中的TweetTokenizer
可能更合适。可以根据场景探索其他分割方案。通过spaCy
解析后的文档,句子分割结果存储于parsed.sents
属性。遍历句子及词元:pythonfor sent in parsed.sents: for token in sent: print(token)
每个词元均为
spaCy
的Span
对象,其属性包含词元类型及其他模型赋予的特征信息。 -
词性标注 (
Part-of-Speech Tagger
):当文本被分割成单个词语(亦称"词元")后,下一步即为每个词元标注词性 (PoS
) 标签------即其语法类别。常见的推断标签包括名词、动词、助动词、形容词等。用于词性标注的引擎通常是基于大型标注语料库训练的分类模型,其中每个词元都有对应的词性标签。通过真实数据训练,这些模型能识别语言中的常见模式;例如冠词 "the" (限定词DET
)后通常接名词等。在使用spaCy
时,词性标注信息通常存储在Span
对象的label_
属性中。此外,通过spacy.explain
函数可获取标签类型的人类可读解释。 -
命名实体识别 (
Named Entity Recognition
,NER
):该分析步骤通常采用统计模型,经训练后可识别文本中出现的名词类型。常见实体类型包括组织机构、人物、地理区位与地址、产品、数字及货币等。模型根据上下文词汇及所用介词,推断出最可能的实体类型(若存在)。与自然语言处理流程的其他环节类似,这些模型同样通过大型标注数据集进行训练,从中学习常见模式与结构。在spaCy
中,文档实体信息通常存储于解析对象的ents
属性中,并可通过displacy
模块实现文本实体的可视化呈现。输出结果如下所示: -
依存句法分析 (
Dependency Parser
):该分析引擎能极其精准地推断句子中词元间的语法关系,本质上可构建呈现词语关联的句法树。根词元(其他词元依存的核心)通常是句子的主动词,连接主语与宾语。主语和宾语又可关联其他句法成分,如物主代词、形容词及冠词等。此外,动词除关联主宾语外,还可支配介词短语及从属谓语结构。以句子 "Autonomous cars shift insurance liability towards manufacturers" 为例:如图所示依存树中,主动词(根节点) "shift" 通过主谓宾关系分别连接 "cars" (主语) 和 "liability" (宾语),同时支配 "towards" 介词。同理,其余名词/形容词 ("Autonomous"、"insurance"及"manufacturers") 则分别与主语、宾语或介词形成依存关系。因此,
spaCy
可构建可遍历的句法树以识别词元间关联,这种能力在构建知识图谱时至关重要。 -
词形还原 (
Lemmatizer
):作为分析流程的最后环节,该组件能将词语还原为共同词根,从而提供更纯净的词汇形态,有效减少词形变化带来的变异。以动词 "to be" 为例,其形态变化包括 "is"、"are"、"was" 等多种有效形式;又如 "car" 与 "cars" 的区别。多数场景下,我们并不关注这类词法差异。词形还原器通过将词元归约为稳定基础形态,极大简化后续处理流程。传统实现基于规则库,将特定词汇(含变位、复数、屈折变化等形式)映射至共同词根,更复杂的实现则会利用上下文和词性标注信息,以提高对同义词的鲁棒性。部分系统会采用词干提取器 (Stemmer
) 作为替代方案------这类工具通过截除词尾来处理词形和派生的变化,而不是将单词与共同的词根形式关联。词干提取器通常较为简单,一般基于一组去除特定模式的规则,而不是考虑词汇和句法信息。在spaCy
中,可通过Span
对象的lemma_
属性获取词元还原结果。
spaCy
处理管道可轻松集成至语料处理流程,并将结果存储于语料 DataFrame
:
python
nlp = spacy.load('en_core_web_md')
sample_corpus["parsed"] = sample_corpus["clean_text"].apply(nlp)
该 DataFrame
构成了文档的结构化信息基础,将成为后续所有分析的起点。