一、NLP的概念
1.什么是NLP
自然语言处理(Natural Language Processing)旨在让计算机能够理解和生成人类语言。
2.NLP的发展简史
| 阶段 | 时间 | 特征 |
|---|---|---|
| 萌芽期 | 1950年 | Turing测试:"Can machines think?" |
| 规则派 vs 统计学派 | 后期 | 两大对立阵营 |
| 概率方法引入 | 后期 | 统计学方法兴起 |
| 机器学习占领主流 | 2013年前 | 传统ML算法主导 |
| 深度学习时代 | 2013年后 | Word2Vec(2013)、Transformer(2017) |
关键里程碑:
- 2013年:Google发布Word2Vec,词向量表示技术成熟
- 2017年:Google发布Transformer框架,NLP进入大发展时代
3.NLP应用场景
- 语音助手:科大讯飞语音识别
- 机器翻译:CCTV机器翻译系统
- 搜索引擎:智能搜索优化
- 智能问答:问答系统、智能客服
二、文本预处理
1.文本预处理的概念
文本预处理是文本语料在输送给模型前必须进行的一系列处理工作,包括:
- 将文本转换成模型需要的张量格式
- 规范张量的尺寸
- 数据分析:标签的分布、样本长度分布等
主要环节:
文本预处理流程
1.文本语料的数据分析
2.文本特征处理
3.文本处理的基本方法(分词、NER、词性标注)
4.文本张量的表示方法(One-Hot、Word2Vec、Word Embedding)
5.数据增益方法
三、文本处理的基本方法
1.分词
1.1 为什么要分词?
- 词是语言语义理解的最小单元
- 是NLP高阶任务的重要基础
- 中文没有天然的分界符(英文天然以空格分隔)
1.2 jieba分词工具
jieba是Python中最流行的中文粉刺库,支持三种分词模式:
python
import jieba
sentence = "今天天气晴朗,风和日丽,适合学习人工智能"
# ==================== 精确模式(默认)====================
# 试图将句子最精确地切开,适合文本分析
data1 = jieba.lcut(sentence, cut_all=False)
print(f"精确模式:{data1}")
# 精确模式:['今天', '天气晴朗', ',', '风和日丽', ',', '适合', '学习', '人工智能']
# ==================== 全模式 ====================
# 把句子中所有的词语都扫描出来, 速度快,但有歧义
data2 = jieba.lcut(sentence, cut_all=True)
print(f"全模式:{data2}")
# 全模式:['今天', '今天天气', '天天', '天气', '天气晴朗', '晴朗', ',', '风和日丽', '日丽', ',', '适合', '学习', '人工', '人工智 能', '智能']
# ==================== 搜索引擎模式 ====================
# 在精确模式基础上,对长词再次切分,提高召回率
data3 = jieba.lcut_for_search(sentence)
print(f"搜索引擎模式:{data3}")
# 搜索引擎模式:['今天', '天气', '晴朗', '天气晴朗', ',', '日丽', '风和日丽', ',', '适合', '学习', '人工', '智能', '人工智能']
1.3 用户自定义词典
当默认分词效果不理想时,可以夹在用户自定义词典:
python
import jieba
"""
userdict.txt 内容如下:
哈基米南北绿 5 n
"""
sentence = "哈基米南北绿豆浆是九阳出的一款豆浆"
# CASE1:不使用自定义词典
data1 = jieba.lcut(sentence)
print(f"不使用自定义词典:{data1}")
# 不使用自定义词典:['哈基米', '南北', '绿豆', '浆', '是', '九阳', '出', '的', '一款', '豆浆']
# CASE2:使用自定义词典
# 加载词典
jieba.load_userdict("userdict.txt")
# 使用词典后分词
data2 = jieba.lcut(sentence)
print(f"使用自定义词典:{data2}")
# 使用自定义词典:['哈基米南北绿', '豆浆', '是', '九阳', '出', '的', '一款', '豆浆']
2.命名实体识别(NER)
命名实体 :人名、地名、机构名等专有名词,如"孔子学院"、"浙江绍兴"。
命名实体识别(Named Entity Recognition):识别文本中存在的命名实体。
python
# 示例句子
text = '鲁迅,浙江绍兴人,五四新文化运动的重要参与者,代表作朝花夕拾。'
# 识别结果:
# 鲁迅(人名) / 浙江绍兴(地名)人 / 五四新文化运动(专有名词) / 朝花夕拾(专有名词)
3.词性标注(POS)
词性 :语言中对词的一种分类方法,常见有14种。(感兴趣可以自己去查一下)
词性标注(Part-Of-Speech tagging):标注每个词的词性。
python
import jieba.posseg as pos
sentence = "鲁迅,浙江绍兴人,五四新文化运动的重要参与者,代表作朝花夕拾。"
# 返回pair元组列表,每个pair由(词汇,词性)组成
data = pos.lcut(sentence)
for word in data:
print(f"{word.word}:{word.flag}")
"""
打印结果:
鲁迅:nr
,:x
浙江:ns
绍兴人:nr
,:x
五四新文化运动:nz
的:uj
重要:a
参与者:n
,:x
代表作:n
朝花夕拾:i
。:x
"""
四、文本张量表示方法
1.为什么要文本张量化
将文本表示成张量(矩阵)形式,方便输入到计算机程序中进行处理。
2.One-Hot编码(稀疏词向量)
稀疏向量 :向量中绝大多数元素都是0,只有少数几个位置有非零值。
稠密向量 :向量中绝大多数元素都不是0。几乎所有维度上都有具体的数值。
One-Hot编码:一种稀疏词向量表示方法,每个词表示为一个n维向量,只有一个位置为1,其余为0
2.1 One-Hot编码的生成
python
from tensorflow.keras.preprocessing.text import Tokenizer
import joblib
def onehot_gen():
"""生成One-Hot编码并保存Tokenizer"""
# 1 准备数据
vocabs = ["张三", "李四", "王五"]
# 2 实例化词汇映射器Tokenizer,使用映射器拟合现有文本数据
# 内部会生成 index_word 和 word_index 两张表
my_tokenizer = Tokenizer()
my_tokenizer.fit_on_texts(vocabs)
# 3 查询单词idx,生成onehot编码
for vocab in vocabs:
# 创建全0列表
zero_list = [0] * len(vocabs)
idx = my_tokenizer.word_index[vocab] - 1 # 注意:idx从1开始,所以要-1
# 把全0列表对应位置的值设置为1
zero_list[idx] = 1
print(f"{vocab}的One-Hot编码是{zero_list}")
# 4 保存映射器
joblib.dump(my_tokenizer, "my_tokenizer")
# 5 查看映射器内容
print("word_index:", my_tokenizer.word_index)
print("index_word:", my_tokenizer.index_word)
if __name__ == "__main__":
onehot_gen()
"""
打印结果:
张三的One-Hot编码是[1, 0, 0]
李四的One-Hot编码是[0, 1, 0]
王五的One-Hot编码是[0, 0, 1]
word_index: {'张三': 1, '李四': 2, '王五': 3}
index_word: {1: '张三', 2: '李四', 3: '王五'}
"""
2.2 One-Hot编码的使用
python
import joblib
def onehot_use():
"""加载保存的Tokenizer并使用"""
vocabs = ["张三", "李四", "王五"]
# 1 加载已经保存的映射器
tokenizer = joblib.load("my_tokenizer")
# 2 对李四进行编码
token = "李四"
zero_list = [0] * len(vocabs)
idx = tokenizer.word_index[token] - 1
zero_list[idx] = 1
print(f"{token}的One-Hot编码是{zero_list}")
if __name__ == "__main__":
onehot_use()
"""
打印结果:
李四的One-Hot编码是[0, 1, 0]
"""
2.3 One-Hot编码的优缺点
优点:
- 操作简单,容易理解
缺点:
- 完全割裂了词与词之间的联系
- 大语料集下,向量长度过大,占内存
- 属于稀疏词向量表示
3.Word2Vec模型
Word2Vec:将单词转换为词向量的技术,利用深度学习网络探索单词之间的语义关系。
两种训练方式对比:
| 方式 | 原理 | 适用场景 |
|---|---|---|
| CBOW | 两侧预测中间(根据上下文预测当前词) | 小规模语料,效率高 |
| Skip-gram | 中间预测两侧(根据当前词预测上下文) | 大规模语料,效果好 |
4.Word Embedding(词嵌入)
4.1 概念
| 术语 | 解释 |
|---|---|
| 广义Word Embedding | 所有密集词向量表示方法的总称,Word2Vec可认为是其中一种 |
| 狭义Word Embedding | 深度神经网络中的嵌入层(Embedding Layer) |
4.2 Word2Vec vs Word Embedding
| 对比项 | Word2Vec | Word Embedding |
|---|---|---|
| 向量性质 | 静态的,训练后固定 | 动态的,参与网络训练更新 |
| 使用方式 | 两步:1)获取词向量 2)送入网络 | 一步:直接嵌入神经网络 |
| 灵活性 | 预训练后使用 | 与网络共同训练 |
五、总结
┌─────────────────────────────────────────────────────────────┐
│ NLP与文本预处理知识图谱 │
├─────────────────────────────────────────────────────────────┤
│ NLP发展历程: 规则派 → 统计学派 → 机器学习 → 深度学习 │
├─────────────────────────────────────────────────────────────┤
│ 文本预处理流程: │
│ 数据分析 → 特征处理 → 分词/NER/POS → 张量表示 → 数据增强 │
├─────────────────────────────────────────────────────────────┤
│ 分词: jieba (精确/全模式/搜索引擎模式) │
│ NER: 识别人名/地名/机构名等专有名词 │
│ POS: 标注词性(名词/动词/形容词等) │
├─────────────────────────────────────────────────────────────┤
│ 文本张量表示: │
│ One-Hot (稀疏) → Word2Vec (CBOW/Skip-gram) → Word Embedding │
└─────────────────────────────────────────────────────────────┘