自然语言处理中的词与文档嵌入技术详解
立即解锁
发布时间: 2025-09-03 01:50:08 阅读量: 11 订阅数: 16 AIGC 


实战自然语言处理精要
### 自然语言处理中的词与文档嵌入技术详解
#### 1. n-gram的概念
在自然语言处理(NLP)中,n-gram是一个重要的概念。它可以分为词n-gram和字符n-gram。
- **词n-gram**:由多个词组成,例如“quick brown”(两个词)、“brown fox jumps”(三个词)。当n = 1时,称为一元语法(unigram);n = 2时,称为二元语法(bigram);n = 3时,称为三元语法(trigram)。词n-gram常被用作短语的代理,因为列举句子的所有n-gram时,往往会包含像“Los Angeles”和“take off”这样有语言学意义的短语。
- **字符n-gram**:由字符组成,比如从“brown”可以得到“b”(一个字符)、“br”(两个字符)、“row”(三个字符)等。当我们想要捕捉大致对应词素的子词单元时,会使用字符n-gram。在NLP中,如果没有特别说明,“n-gram”通常指的是词n-gram。不过在搜索和信息检索领域,n-gram常指用于文档索引的字符n-gram,阅读相关论文时需根据上下文判断其类型。
#### 2. 分词、词干提取和词形还原
在典型的NLP流程中,会对语言单元进行一系列处理,主要包括分词、词干提取和词形还原。
##### 2.1 分词(Tokenization)
分词是将输入文本拆分为更小单元的过程,主要有词分词和句子分词两种类型。
- **词分词**:将句子拆分为标记(大致相当于单词和标点符号)。
- **句子分词**:将可能包含多个句子的文本拆分为单个句子。在NLP中,提到“分词”通常指的是词分词。
许多NLP库和框架都支持分词功能,下面介绍如何使用两个流行的NLP库——NLTK和spaCy进行分词。
- **安装和准备工作**:
- 在典型的Python环境中,通过运行`pip install nltk`和`pip install spacy`安装这两个库。
- 安装完成后,对于NLTK,运行`python -c "import nltk; nltk.download('punkt')"`下载必要的数据和模型;对于spaCy,运行`python -m spacy download en`。也可以通过Google Colab(http://realworldnlpbook.com/ch3.html#tokenization)运行示例代码,无需安装Python环境和依赖项。
- **使用NLTK进行分词**:
```python
import nltk
from nltk.tokenize import word_tokenize, sent_tokenize
s = '''Good muffins cost $3.88\nin New York. Please buy me two of
them.\n\nThanks.'''
print(word_tokenize(s))
print(sent_tokenize(s))
```
运行结果如下:
```
['Good', 'muffins', 'cost', '$', '3.88', 'in', 'New', 'York', '.', 'Please', 'buy', 'me', 'two', 'of', 'them', '.', 'Thanks', '.']
['Good muffins cost $3.88\nin New York.', 'Please buy me two of them.', 'Thanks.']
```
NLTK除了默认的分词器外,还实现了多种分词器,其文档页面(https://www.nltk.org/api/nltk.tokenize.html)是探索更多选项的好起点。
- **使用spaCy进行分词**:
```python
import spacy
nlp = spacy.load('en_core_web_sm')
doc = nlp(s)
print([token.text for token in doc])
print([sent.string.strip() for sent in doc.sents])
```
运行结果如下:
```
['Good', 'muffins', 'cost', '$', '3.88', '\n', 'in', 'New', 'York', '.', ' ', 'Please', 'buy', 'me', 'two', 'of', 'them', '.', '\n\n', 'Thanks', '.']
['Good muffins cost $3.88\nin New York.', 'Please buy me two of them.', 'Thanks.']
```
可以看到,NLTK和spaCy的分词结果略有不同,例如spaCy的词分词器会保留换行符(`\n`)。不同的分词器实现方式不同,没有一种标准解决方案能得到所有NLP从业者的认可。对于非英语语言,分词选项可能会有所不同,甚至可能非常有限。如果你熟悉Java生态系统,Stanford CoreNLP(https://stanfordnlp.github.io/CoreNLP/)也是一个值得尝试的NLP框架。
此外,基于神经网络的NLP模型中,字节对编码(Byte-pair encoding,BPE)是一种越来越流行且重要的分词方法。它是一种纯统计技术,不依赖启发式规则(如空格和标点符号),仅根据数据集中的字符统计信息将文本拆分为字符序列。
##### 2.2 词干提取(Stemming)
词干提取是识别词干的过程。词干是去除词的词缀(前缀和后缀)后剩下的主要部分,例如“apples”的词干是“apple”,“meets”的词干是“meet”,“unbelievable”的词干是“believe”。词干通常是词在词形变化后保持不变的部分。
词干提取在许多NLP应用中具有很大的好处。在搜索中,使用词干而不是单词对文档进行索引可以提高检索相关文档的概率;在许多基于特征的NLP流程中,处理词干可以缓解词汇外(OOV)问题。
最流行的英语词干提取算法是Porter词干提取算法,由Martin Porter编写。NLTK实现了该算法的一个版本,以下是使用示例:
```python
from nltk.stem.porter import PorterStemmer
stemmer = PorterStemmer()
words = ['caresses', 'flies', 'dies', 'mules', 'denied',
'died', 'agreed', 'owned', 'humbled', 'sized',
'meetings', 'stating', 'siezing', 'itemization',
'sensational', 'traditional', 'reference', 'colonizer',
'plotted']
print([stemmer.stem(word) for word in words])
```
运行结果如下:
```
['caress', 'fli', 'die', 'mule', 'deni',
'die', 'agre', 'own', 'humbl', 'size',
'meet', 'state', 'siez', 'item',
'sensat', 'tradit', 'refer', 'colon',
'plot']
```
不过,词干提取也有局限性。很多情况下,它可能过于激进,例如Porter词干提取算法会将“colonizer”和“colonize”都转换为“colon”,很少有应用会希望将这三个词视为相同的条目。而且,许多词干提取算法不考虑上下文甚至词性,如“meetings”被转换为“meet”,但作为复数名词,它的词干应该是“meeting”。因此,目前很少有NLP应用使用词干提取。
##### 2.3 词形还原(Lemmatization)
词形是在字典中常作为词条出现的单词的原始形式,也是词在词形变化前的基本形式。例如,“meetings”(复数名词)的词形是“meeting”,“met”(动词过去式)的词形是“meet”。词形还原与词干提取不同,词干提取只是简单地去除词缀,无法处理不规则动词和
0
0
复制全文
相关推荐










