一、什么是自然语言处理
自然语言处理(Natural Language Processing, 简称NLP)就是让计算机能够理解、处理并生成人类日常使用的语言,从而实现人机之间顺畅沟通的人工智能技术。主要的应用场景有:语音助手、机器翻译、搜索引擎、智能问答等
千问、GPT都属于自然语言处理范畴
学习路线: 线性回归和逻辑回归 -> 深度学习(ANN) -> RNN -> LSTM/GRU -> Transformer -> Bert/大模型
二、文本预处理的步骤
文本预处理,就像机器学习中的特征处理一样,是模型训练前必不可少的一环——原始文本只有经过处理,才能转换为算法模型能够接受的输入形式,最终再交给模型去学习。
- 机器学习流程:数据预处理 / 特征预处理 → 算法模型
- NLP 基础流程:数据预处理 / 特征预处理 → 算法模型(RNN / LSTM / GRU / Transformer)
张量中不能放非数字:例如字符串
- 文本预处理及作用
所处阶段:数据输入到模型之前
作用:数据清洗、指导超参数的确定
- 文本预处理的主要环节
1.文本处理的基本方法:分词、NER、POS
2.文本张量的表示方法:one-hot、word2vec、wordEmbedding
3.文本语料的数据分析:标签数量分析(类别不均衡问题)、句子长度分析、词频统计和关键词词云
4.文本特征处理:添加n-gram特征、文本长度规范
5.数据增强方法:回译数据增强
环境准备
安装 jieba 及相关依赖
安装jieba分词器
pip install jieba -i https://mirrors.aliyun.com/pypi/simple/
pip install torch -i https://mirrors.aliyun.com/pypi/simple/
pip install tensorflow -i https://mirrors.aliyun.com/pypi/simple/
pip install joblib -i https://mirrors.aliyun.com/pypi/simple/
pip install fasttext -i https://mirrors.aliyun.com/pypi/simple/
或者
pip install fasttext-wheel -i https://mirrors.aliyun.com/pypi/simple/
如果不管是安装fasttext还是fasttext-wheel都失败,那么原因是python版本过高。
操作步骤如下:
1- 先进入对应的虚拟环境
2- 安装低版本的python解释器
conda install python=3.10
3- 安装fasttext
pip install fasttext-wheel -i https://mirrors.aliyun.com/pypi/simple/
pip install seaborn -i https://mirrors.aliyun.com/pypi/simple/
pip install matplotlib==3.8.4 -i https://mirrors.aliyun.com/pypi/simple/
如果运行matplotlib代码报错,依次执行如下两行命令:
pip uninstall -y matplotlib
pip install matplotlib==3.8.4 -i https://mirrors.aliyun.com/pypi/simple/
pip install wordcloud -i https://mirrors.aliyun.com/pypi/simple/文本处理的基本方法 (结巴分词)(掌握)
jieba分词工具代码示例:
jieba 分词三种模式示例
import jieba
"""
推荐要求大家重点掌握jieba.lcut()方法即可
"""
content = "传智hello教育是一家上市公司,旗下有黑马程序员品牌。我是在黑马这里学习人工智能"
# 【推荐】全词模式 (工作中用的基本就是这个)
def demo01():
# Ctrl+Q:看方法解释
words = jieba.lcut(content)
print(words)
# 了解:不带l的cut返回结果是generator生成器
#result = jieba.cut(content)
#print(result)
#print(type(result))
#print(list(result))
# 精确模式
def demo02():
# cut_all默认是False。如果设置为True,那就是精确模式,分词更加细致
words = jieba.lcut(content,cut_all=True)
print(words)
# 搜索引擎模式
def demo03():
# 注意:没有cut_all参数
words = jieba.lcut_for_search(content)
print(words)
if __name__ == '__main__':
# 【推荐】全词模式
demo01()
# 精确模式
#demo02()
# 搜索引擎模式
#demo03()
展开查看更多
支持用户自定义词典和繁体字分词 (了解)
词典的意义
可以根据自定义词典,修改jieba分词方式,优先考虑词典里面的词来切分
格式:词语 词频(可省略) 词性(可省略)
自定义词典内容
# 格式:词 词频(可省略) 词性(可省略)
传智教育 10 n
黑马程序员 8
我是 1000000
旗下有
代码实现
import jieba
# 繁体字分词:正常分词即可
def demo1():
content = "煩惱即是菩提,我暫且不提"
print(jieba.lcut(content))
content = "煩恼即是菩提,我暫且不提"
print(jieba.lcut(content))
# 自定义字典
def demo2():
content = "传智教育是一家上市公司,旗下有黑马程序员品牌。我是在黑马这里学习人工智能"
# 默认不使用自定义指定的形式
result = jieba.lcut(content)
print(result)
# 加载自定义字典
# 字典中用来存放需要进行特殊关照的词。这些词会作为整体,不会被分词
jieba.load_userdict("data/my_dict.txt")
result = jieba.lcut(content)
print(result)
if __name__ == '__main__':
# 繁体字分词
# demo1()
# 用户自定义字典
demo2()命名实体识别 (了解)
- 定义
命名实体:通常指人名、地名、机构名等专有名词
NER:从一段文本中识别出上述描述的命名实体
常见的7类命名实体:人名、地名、机构名、时间、日期、货币、百分比
- 作用
同词汇一样,命名实体也是人类理解文本的基础单元,也是AI解决NLP领域高阶任务的重要环节
词性标注(pos)
- 定义
对每个词语进行词性的标注:动词、名词、形容词等
- 实现方式
import jieba.posseg as pseg # POS词性标注
# POS词性
def demo1():
content = "鲁迅爱北京天安门"
result = pseg.lcut(content)
for word,pos in result:
print(word,"=",pos)
if __name__ == '__main__':
# POS词性标注
demo1()
三、文本张量的表示方法
文本张量的表示方法有几种
- onehot
- word2vec
- CBOW:连续词袋模式。使用两边的词预测中间的内容
- Skip-gram:跳词模式。使用中间的词预测两边的内容
- word embedding
每个词对应矩阵中的一个向量,这个矩阵叫词向量 ,词向量数字的个数可以自定义
结论:
词和词之间没有语义关系用One-Hot,有语义关系用Word Embedding 和Word2Vec
Word Embedding词向量是动态的, 能够根据语义变化而变化。对词的上下文信息更好点
Word2Vec 是静态的,对多义词处理效果不佳。
展开查看详情
One-Hot 词向量表示
针对每一个词汇,都会用一个向量表示,向量的长度是n(n就是词表大小),n代表去重之后的词汇总量,而且向量中只有0和1两种数字 也称之为:独热编码、01编码
代码实现:
One-Hot 词向量代码实现
import os
# 注意:1- 代码放在整个文件的最上面;2- 0需要是字符串的类型
os.environ["TF_ENABLE_ONEDNN_OPTS"]="0"
import joblib
# from tensorflow.keras.preprocessing.text import Tokenizer # 词汇映射器
from keras.src.legacy.preprocessing.text import Tokenizer # 上面的替代方案
"""
获得词向量的one-hot方式总结:
优点:实现、理解简单
缺点:
1- 词向量是一个稀疏向量(大多数值为0,信息密度低),会浪费存储和计算资源
2- 对多义词的处理不好。例如:过过过过过过,中的3对过的词向量是同一个
"""
def demo01():
# 1- 准备语料数据
vocabs = ["周杰伦", "陈奕迅", "王力宏", "李宗盛", "吴亦凡", "鹿晗"]
# vocabs = ["过过", "过过", "过过"] # 3个过过的one-hot是同一个
# 2- 训练词汇映射器
# 2.1- 创建词汇映射器
my_tokenizer = Tokenizer()
# 2.2- 用语料库训练
my_tokenizer.fit_on_texts(vocabs)
# 2.3- 得到训练好的词和索引的映射关系
# word_index类型是字典类型。key是词,value是词索引,索引从1开始
word_dict = my_tokenizer.word_index
# print(type(word_dict))
# print(word_dict)
# 3- 分别获得每个词的one-hot词向量
for word in vocabs:
# 3.1- 初始化全0的列表
one_hot = [0]*len(vocabs)
# 3.2- 获得词在词汇映射器中的索引位置
index = word_dict[word]-1
# 3.3- 将指定位置的值设置为1即可
one_hot[index] = 1
print(f"{word}-->{one_hot}")
# 4- 保存训练好的模型
joblib.dump(my_tokenizer,"../model/my_tokenizer.pkl")
def demo02():
word = "李宗盛"
# 1- 加载训练好的模型
my_tokenizer = joblib.load("../model/my_tokenizer.pkl")
# 2- 得到某个词的one-hot词向量
# 2.1- 得到训练好的词和索引的映射关系
word_dict = my_tokenizer.word_index
# 2.2- 初始化全0的列表
one_hot = [0] * len(word_dict)
# 2.3- 获得词在词汇映射器中的索引位置
index = word_dict[word] - 1
# 2.4- 将指定位置的值设置为1即可
one_hot[index] = 1
print(f"{word}-->{one_hot}")
# 基于纯Python入门试学班的代码实现
def demo03():
# 1- 准备语料数据
vocabs = ["周杰伦", "陈奕迅", "王力宏", "李宗盛", "吴亦凡", "鹿晗"]
# 2- 获得每个词的词向量
for word in vocabs:
# 2.1- 初始化全0的列表
one_hot = [0]*len(vocabs)
# 2.2- 获得词对应的索引
index = vocabs.index(word)
# 2.3- 将对应位置的值设置为1
one_hot[index] = 1
print(f"{word}-->词索引{index}-->one-hot词向量{one_hot}")
if __name__ == '__main__':
# 1- 训练模型:也就是训练词汇映射器
demo01()
# 2- 使用训练好的模型
# demo02()
# 3- 用最基本的方式实现
# demo03()One-hot总结:
获得词向量的one-hot方式总结:
- 优点:实现、理解简单
- 缺点:
- 1- 词向量是一个稀疏向量,会浪费存储和计算资源
- 2- 对多义词的处理不好。例如:过过过过过过,中的3对过的词向量是同一个
Word2Vec模型
- 是将文本变成词向量张量的一种方法,是一种无监督(自监督)的训练方法,本质是训练一个模型,将模型的参数矩阵当作所有词汇的词向量表示。基于one-hot的形式进行优化改造
- 它又分为两种具体模式:
- CBOW:连续词袋模式。使用两边的词预测中间的内容
- Skip-gram:跳词模式。使用中间的词预测两边的内容
CBOW【了解】
CBOW【了解】
核心思想:给一段文本,选择一定的窗口,然后利用上下文预测中间目标词
- 实现过程

skip-gram【了解】
skip-gram【了解】
核心思想: 给出一段文本,选择一定窗口获取数据集,利用中间词来预测上下文
- 实现过程

Fasttext实现Word2Vec代码【掌握】
- 基本过程
1.获取数据
2.训练模型(训练词向量)
正常安装:pip install fasttext -i https://mirrors.aliyun.com/pypi/simple/
如果失败:pip install fasttext-wheel -i https://mirrors.aliyun.com/pypi/simple/
3.向量的检验
4.超参数设定
5.模型的保存和加载
代码实现:
Fasttext 实现 Word2Vec
"""
如果不管是安装fasttext还是fasttext-wheel都失败,那么原因是python版本过高。
操作步骤如下:
1- 先进入对应的虚拟环境
2- 安装低版本的python解释器
conda install python=3.10
3- 安装fasttext
pip install fasttext-wheel -i https://mirrors.aliyun.com/pypi/simple/
"""
import fasttext
def demo01():
# 1- 使用无监督学习训练模型
"""
为什么这里只能使用无监督学习?
答:因为数据中没有明确标记目标值。有监督学习对文件内容有严格要求,有__label__
"""
# model = fasttext.train_unsupervised("data/fil9")
model = fasttext.train_unsupervised("data/gz03ag")
# 2- 保存训练好的模型
model.save_model("model/word2vec.pkl")
def demo02():
# 1- 加载训练好的模型
model = fasttext.load_model("model/word2vec.pkl")
# 2- 获得某个词的词向量
word_vec = model.get_word_vector("hello")
print(word_vec)
def demo03():
# 1- 加载训练好的模型
model = fasttext.load_model("model/word2vec.pkl")
# 2- 获得相近的几个词
# 会从词形、词义方面进行查找。
# result_list = model.get_nearest_neighbors("dog")
result_list = model.get_nearest_neighbors("cat")
# 3- 输出
print(result_list)
def demo04():
"""
参数解释:
input:训练集路径
model:word2vec的模式。默认是skipgram,可以设置为cbow
dim:词向量的维度,该值越大训练越耗时,但是存储的信息越丰富
epoch:训练的轮次
lr:初始学习率
thread:训练的线程个数
"""
model = fasttext.train_unsupervised(
input="data/gz03ag",
model="cbow",
dim=200,
epoch=1,
lr=0.1,
thread=10
)
model.save_model("word2vec_better.pkl")
if __name__ == '__main__':
# 1- 训练并保存模型
# demo01()
# 2- 获得词的词向量
# demo02()
# 3- 获得相近的词
# demo03()
# 4- 超参数调优设置【掌握】
demo04()
词嵌入Word Embedding
word2vec缺点:静态的、固定的vec表示方法,对多义词处理效果不佳
- 词嵌入层: 将词变成词向量
借助nn.Embedding(num_embeddings, embed_dim):
num_embeddings:去重后的词汇表中总共有多少个词
embed_dim:向量维度,也就是向量中有多少个数字。实际工作一般设置为128、256、 512等
- 代码实现
nn.Embedding 词嵌入代码实现
import os
import torch
os.environ['TF_ENABLE_ONEDNN_OPTS']='0'
from tensorflow.keras.preprocessing.text import Tokenizer # 词汇映射表
import jieba
import torch.nn as nn
from torch.utils.tensorboard import SummaryWriter # 词向量可视化化
if __name__ == '__main__':
# 1- 准备文本数据
sentence1 = '传智教育是一家上市公司,旗下有黑马程序员品牌。我是在黑马这里学习人工智能'
sentence2 = "我爱自然语言处理"
sentence_list = [sentence1,sentence2]
# 2- 分词处理
word_list = []
for sen in sentence_list:
word_list.append(jieba.lcut(sen))
# print(word_list)
# 3- 使用语料库对Tokenizer词汇映射器进行训练
# 3.1- 创建Tokenizer实例对象
my_token = Tokenizer()
# 3.2- 模型训练
my_token.fit_on_texts(word_list)
# 3.3- 得到索引和词的映射关系,结果是一个字典。注意:索引从1开始
# 【了解】1- 首先根据词在句子中的顺序来排序;2- 然后将出现频次高的词排在前面;3- 如果频次相同,那么按照首次出现的顺序排序
index_word = my_token.index_word
word_num = len(index_word)
print(index_word)
# 4- 创建词嵌入层
"""
num_embeddings:去重后的词汇表中总共有多少个词
embedding_dim:每个词的词向量维度(也就是向量中有多少个数字)
"""
ebd = nn.Embedding(num_embeddings=word_num,embedding_dim=6)
# 5- 得到词向量
for i in range(word_num):
# 5.1- 根据词索引得到词向量
word_vector = ebd(torch.tensor(i))
# 5.2- 打印输出
print(f"索引是{i+1},对应的词是 {index_word.get(i+1)},词向量{word_vector}")
# 6- 可视化展示:通过tensorboard(张量面板)观察词之间的相似性
summary_obj = SummaryWriter(log_dir="./runs")
summary_obj.add_embedding(ebd.weight.data,index_word.values())
summary_obj.close()结果可视化:
- 命令:tensorboard –logdir=runs –host 127.0.0.1
- 截图

- 访问:使用Edge浏览器来访问。输入链接 http://127.0.0.1:6006


四、文本数据分析
文本数据分析的目的是快速了解语料质量,为后续模型训练做准
主要做三件事:
标签数量分布:检查样本是否均衡,不均衡则增减数据
句子长度分布:确定截断或补齐的基准长度
词频统计与词云:统计词汇总量、通过词云发现脏数据
文本数据分析【理解】
文本数据分析有哪些方法
1、标签数量分布
2、句子长度分布
3、词频统计和词云
文本数据分析的作用
1、帮助我们理解语料
2、帮助我们检查语料, 快速分析语料中可能存在的问题.
例如:
数据质量类: 错别字, 语法错误, 重复内容, 缺失值...
数据均衡类: 标签分布不均, 句子长度不同...
标签数量分布
目的: 查询样本类别是否均衡,如果样本过大,需要减少数据;如果样本过少,需要增加数据
- 代码实现
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
"""
如果出现AttributeError: 'FigureCanvasInterAgg' object has no attribute 'tostring_rgb'. Did you mean: 'tostring_argb'?
那么是matplotlib的版本过高导致的
pip uninstall -y matplotlib
pip install matplotlib==3.8.4 -i https://mirrors.aliyun.com/pypi/simple/
"""
if __name__ == '__main__':
# 1- 读取文件
"""
注意:需要指定具体的分隔符sep,否则会报错pandas.errors.ParserError: Error tokenizing data. C error: Expected 6 fields in line 12, saw 8
"""
train_df = pd.read_csv("data/train.tsv",encoding="UTF-8",sep="\t")
dev_df = pd.read_csv("data/dev.tsv",encoding="UTF-8",sep="\t")
# 2- 展示训练集
plt.style.use("fivethirtyeight")
sns.countplot(x="label",data=train_df)
plt.title("train")
plt.show()
# 3- 展示验证集
sns.countplot(x="label", data=dev_df)
plt.title("dev")
plt.show()
句子长度分布
目的: 模型一般规定需要输入固定的尺寸,也就是长度统一,通过分析句子长度,可以明确大部分样本属于什么长度范围,然后进行句子的长短补齐或截断
- 解释list( map(lambda x: len(x), sentence_series))
if __name__ == '__main__':
my_data = [11,22,33]
map_result = map(lambda num:num*10, my_data) # 这里实际是得到了一个生成器对象
# print(map_result) # 得到的是内存地址值
# 取值方式一【推荐】:转成List列表
# list_result = list(map_result)
# print(list_result)
print("-"*30)
# 取值方式二:for循环
# for i in map_result:
# print(i)
print("-" * 30)
# 取值方式三:next一个个取值
print(next(map_result))
print(next(map_result))
print(next(map_result))
- 代码实现
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
def demo01():
# 1- 读取数据
df = pd.read_csv("data/train.tsv",sep="\t",encoding="UTF-8")
# 2- 统计句子长度
# 2.1- 获得句子列
sentence_series = df["sentence"]
# 2.2- 计算句子长度
# 方式一:list(map)
# df["length"] = list(map(lambda line:len(line),sentence_series))
# 方式二:apply
df["length"] = sentence_series.apply(lambda line:len(line))
# print(df.head())
# 3- 绘制图形
# 3.1- 绘制分布直方图
plt.style.use("fivethirtyeight")
sns.countplot(x="length",data=df)
plt.xticks([])
plt.title("length_dist")
plt.show()
# 3.2- 绘制趋势曲线
# kde:让曲线更加平滑
sns.displot(x="length",data=df,kde=True)
plt.show()
def demo02():
# 1- 读取数据
df = pd.read_csv("data/train.tsv", sep="\t", encoding="UTF-8")
# 2- 统计句子长度
# 2.1- 获得句子列
sentence_series = df["sentence"]
# 2.2- 计算句子长度
df["length"] = sentence_series.apply(lambda line: len(line))
# 3- 绘制图形
sns.stripplot(x="label",y="length",data=df,hue="label")
plt.title("label_length")
plt.show()
if __name__ == '__main__':
# 句子长度分布
demo01()
# 好评差评的句子长度分布
demo02()
词频和高频词云
词频: 这里指的是统计样本中词汇的总数量(需要去重)
高频词云目的: 可以方便我们查看数据集中是否存在脏数据,进而实现人工的审核和清洗
- 解释chain(*map())
chain的作用可以简单理解为和List.extend等价,但是有区别:chain返回一个的是一个迭代器,因此对内存的使用极低,而且不修改原始列表
# 导包
from itertools import chain
import jieba
def dm01():
list1 = ['今天天很好', '今天天很热']
# 对每个字符串进行分词处理
tmp_result = map(lambda x: jieba.lcut(x), list1)
print(list(tmp_result))
print(*tmp_result)
# 把上述结果合并, 不会去重.
result = list(chain(*tmp_result))
print(f'result: {result}')
# 上述格式最终版写法, 即: 一行.
result = list(chain(*map(lambda x: jieba.lcut(x), list1)))
print(f'result: {result}')
if __name__ == '__main__':
dm01()
- 词频_代码实现
# 导包
import jieba
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt # 推荐安装 pip install matplotlib==3.9
from itertools import chain # 迭代器工具
# 解决Matplotlib绘图时 中文乱码问题.
plt.rcParams['font.sans-serif'] = ['SimHei'] # Mac本字体改为: ['Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# 1. 词频统计.
def dm01_word_count():
# 1. 读取数据.
train_data = pd.read_csv('./data/train.tsv', sep='\t')
test_data = pd.read_csv('./data/dev.tsv', sep='\t')
# 2. 统计 训练集中 词汇总数.
train_vocab = set(chain(*map(lambda x: jieba.lcut(x), train_data['sentence'])))
# 3. 统计 测试集中 词汇总数.
test_vocab = set(chain(*map(lambda x: jieba.lcut(x), test_data['sentence'])))
# 4. 打印结果.
print(f'训练集的 词汇总数: {len(train_vocab)}')
print(f'测试集的 词汇总数: {len(test_vocab)}')
if __name__ == '__main__':
# 词频统计
dm01_word_count()- 高频词云_代码实现
import pandas as pd
from itertools import chain
from wordcloud import WordCloud # 词云类
import jieba.posseg as pseg
import matplotlib.pyplot as plt
def get_a_word(line):
# 分词并且标注词性
word_dict = pseg.lcut(line)
# print(word_dict)
result_list = []
# 过滤形容词
for word,pos in word_dict:
if pos=="a":
result_list.append(word)
return result_list
def show_cloud(a_word_list):
# 1- 创建词云对象
wordcloud_obj = WordCloud(font_path="data/SimHei.ttf",max_words=100,background_color="white")
# 2- 词汇列表以空格分隔拼接成字符串
words_str = " ".join(a_word_list)
# 3- 绘制图形
wordcloud_obj.generate(words_str)
plt.figure()
# bilinear:让文字边缘更加平滑
plt.imshow(wordcloud_obj,interpolation="bilinear")
plt.axis("off")
plt.show()
def word_cloud():
# 1- 读取文件,并且取出评价内容
df = pd.read_csv("data/train.tsv",sep="\t",encoding="UTF-8")
sentence_series = df["sentence"]
# 2- 句子分词,过滤出形容词
# 注意:map返回的是生成器,你要真的调用它,才会触发数据的产生
a_word_list = list(chain(*map(get_a_word,sentence_series)))
# a_word_list = list(chain(*map(lambda line: [word for word,pos in pseg.lcut(line) if pos=="a"],sentence_series)))
# print(a_word_list)
# 3- 绘制词云
show_cloud(a_word_list)
if __name__ == '__main__':
word_cloud()五、文本特征处理
文本特征处理主要做两件事:
N-Gram 特征:将连续 n 个相邻词组合为新特征,如 bi-gram (2-gram) 的"我爱",提升模型对上下文的理解
文本长度规范:对超长文本截断、不足补齐,确保模型输入尺寸统一
文本特征处理【熟悉】
【介绍一下n-gram】
将n个连续相邻的token组合到一起,n-gram特征
【为什么要规范文本长度】
模型的输入需要【每个batch】或者【整个数据集】,统一句子长度
对语料添加普适性的特征:n-gram
对语料进行规范长度:适配模型的输入
添加N-Gram特征
n-gram介绍:
概述:
就是将连续的n个词组合到一块, 把这些连续片段当做1个新特征(小词组特征), 帮我们分析文本的规律.
分析:
uni-gram(1-gram): 把每个 词/字 拆出来.
bi-gram(2-gram): 找连续2个词的组合.
tri-gram(3-gram): 找连续3个词的组合.
目的:
让计算机更好的理解 文本规律,也就是上下文信息.
例如:
分词内容: 我| 爱| 黑马
uni-gram: 我| 爱| 黑马
bi-gram: 我爱|爱黑马
tri—gram: 我爱黑马
- zip函数解释
if __name__ == '__main__':
list1 = [1, 2, 3, 4, 5, 6]
list2 = [2, 3, 4]
result = list(zip(list1, list2))
print(result)
- 代码实现
"""
n-gram:指的是 将相邻的n个词拼接到一起成为新词的过程。其中n一般取值为1、2、3
1:uni-gram,不进行拼接操作
2:bi-gram,将相邻的2个词拼接到一起
3:tri-gram,将相邻的3个词拼接到一起
作用:通过拼接相邻词的过程,提升模型对语义上下文的理解
注意:n的值实际工作中一般是3以内,大多数情况是2。如果n太大,会导致词汇表个数膨胀,太长的拼接没有意义
"""
def n_gram_fn(n_gram):
# 1- 测试数据
word_list = ["aa","bb","cc","dd"]
# 2- 对相邻的词进行合并
"""
2-gram:
["aa","bb","cc","dd"]
["bb","cc","dd"]
3-gram:
["aa","bb","cc","dd"]
["bb","cc","dd"]
["cc","dd"]
"""
lists = [word_list[i:] for i in range(n_gram)]
print(lists)
print(list(zip(*lists)))
if __name__ == '__main__':
n_gram_fn(n_gram=1)
n_gram_fn(n_gram=2)
n_gram_fn(n_gram=3)文本长度规范
意义: 一般模型的输入需要等尺寸大小的矩阵, 所以需要对超长文本做截断, 不足的做补齐。这就是文本长度规范.
- 代码实现
# from tensorflow.keras.preprocessing import sequence
from keras.preprocessing import sequence
sen_list = [
[1, 23, 5, 32, 55, 63, 2, 21, 78, 32, 23, 1],
[2, 32, 1, 23, 1]
]
# 用框架提供的方法实现句子长度的规范
def demo01():
"""
sequences:要进行长度规范的句子列表
maxlen:长度规范中的句子长度要求统一为多长,指的是词的个数
truncating:截断的方向。默认是pre,从前面开始截断;post从后面开始截断
padding:填充的方向。默认是pre,从前面开始填充;post从后面开始填充
value:使用什么值进行填充。推荐使用默认的0,因为对原始数据的影响最小
"""
result = sequence.pad_sequences(sen_list,maxlen=10,truncating="post",padding="post")
# result = sequence.pad_sequences(sequences=sen_list,maxlen=10,truncating="pre",padding="pre")
# result = sequence.pad_sequences(sequences=sen_list,maxlen=10,value=6666)
print(result)
def demo02():
# 1- 定义一个空列表用来存储规范化后的句子
result_list = []
maxlen = 10 # 句子的长度
# 2- 分别对每条句子进行处理
for sen in sen_list:
if len(sen)>maxlen:
# 超长的要截断
result_list.append(sen[:maxlen])
else:
# 短的要填充
result_list.append(sen + [0]*(maxlen-len(sen)))
print(result_list)
if __name__ == '__main__':
# 用框架提供的方法实现句子长度的规范
demo01()
# 使用最简单的python代码实现
demo02()