NLP自然语言处理

NLP就是人与机器沟通的"桥梁"。

NLP的基础概念

概念名词

词表/词库(Vocabulary)

文本数据集中出现的所有单词的集合。

语料库(Corpus)

用于NLP任务的文本数据集合。

词嵌入(Word Embedding)

将单词映射到低维连续向量空间的技术,用于捕捉单词的语义和语法信息。

分词(Tokenization)

将文本分割成一个个单词或标记的过程,为后续处理提供基本的单位。

停用词(Stop Words)

在文本处理中被忽略的常见单词,如"a"、"the"、"is"等

词频(Term Frequency)

在给定文档中,某个单词出现的次数。

词性标注(Part-of-Speech Tagging)

为每个词赋予正确的词法标记。

句法分析(Parsing)

分析句子的结构,确定词语间的语法关系。

词干提取(Stemming)与词形还原(Lemmatization)

词干提取:将词转换为词干或原型形式,去除变化或衍生部分。

词形还原:将词还原为词源或词典中的词目形式。

词向量化(Word Vector)

将词语表示为实数向量,以捕捉语言与实数间的关系。

TF-IDF(Term Frequency-Inverse Document Frequency)

一种常用的文本特征表示方法,综合考虑了词频和逆文档频率。

命名实体消歧(Named Entity Disambiguation)与识别(Named Entity Recognition)

命名实体消歧:确定文本中提到的实体的具体含义,如区分同名不同义的实体。

命名实体识别:识别文本中具有特定意义的实体,并分类为人名、机构名、日期等。

序列常见类型

字符序列

一个字符串就是一个字符序列,每个字符按顺序排列。 例子:"hello" 是一个由 hello 组成的字符序列。
2.

单词序列

一句话可以看作是一个单词序列,每个单词按照一定顺序排列。 例子:"I love NLP" 是一个由 IloveNLP 组成的单词序列。
3.

时序数据

在时间序列中,元素是按时间顺序排列的,常用于预测问题。 例子:股票价格数据可以看作是随时间变化的数值序列。
4.

语音序列

在语音处理任务中,语音信号可以被分解为按时间顺序排列的帧序列(特征向量序列)。
5.

其他序列

序列还可以表示一些更抽象的结构,比如DNA序列(由碱基组成的序列)、事件序列等。

基本流程

1.语料获取

利用已经建好的数据集或第三方语料库

获取网络数据

与第三方合作获取数据,通过购买的方式获取部分需求文本数据

2.语料预处理

去除数据中非文本内容

中文分词 jieba分词软件

词性标注。词性标注指给词语打上词类标签,如名词、动词、形容词等,常用的词性标注方法有基于规则的算法、基于统计的算法等。

去停用词。停用词就是句子中没必要存在的词,去掉停用词后对理解整个句子的语义没有影响。中文文本中存在大量的虚词、代词或者没有特定含义的动词、名词,在文本分析的时候需要去掉。

3.文本向量化(特征工程)

文本数据经过预处理去除数据中非文本内容、中文分词、词性标注和去停用词后,基本上是干净的文本了。但此时还是无法直接将文本用于任务计算,需要通过某些处理手段,预先将文本转化为特征向量。一般可以调用一些模型来对文本进行处理,常用的模型有词袋模型(Bag of Words Model)、独热表示、TF-IDF 表示、n元语法(n-gram)模型和 Word2Vec模型等。

4.模型构建

5.模型训练

6.模型评价

NLP中的特征工程

在自然语言处理(NLP)中,特征工程 是指将文本数据转换为适合机器学习模型使用的数值表示的过程

传统NLP中的特征工程

独热编码 one - hot

独热编码(One-Hot Encoding) 是一种常见的特征表示方法,通常用于将离散的类别型数据转换为数值型表示,它的特点是将每个类别表示为一个向量,在该向量中,只有一个元素为1,其余元素全部为0。

例:在nlp中,构成词库{time, fruit, flies, like, a, an, arrow, banana},banana的one-hot表示就是:[0,0,0,0,0,0,0,1],"like a banana" 的one-hot表示就是:[0,0,0,1,1,0,0,1]。

词频-逆文档频率(TF-IDF)

词频

在计算词频(TF)时,分母是文档中的总词数 ,不考虑重复

例:"Fruit flies like time flies a fruit" ,TF("files")=2/7

逆文档频率**(Inverse Document Frequency, IDF)**

逆文档频率用来衡量一个词在整个文档集合(语料库)中的重要性。它的目的是降低那些在很多文档中频繁出现的词的权重,例如"the"、"is"这种常见词,或者低频罕见词tetrafluoroethylene(四氟乙烯)。

D表示文档集合,t是要计算的词。+1 是为了避免分母为 0 的情况。

math在文章中出现5次,文章有200个词,则IDF=log[200/(5+1)]

TF-IDF 计算

TF-IDF 是 TF 和 IDF 相乘

一个词在特定文档中出现的频率越高(TF高),并且在整个语料库中出现得越少(IDF高),它的 TF-IDF 值就越高。可以找出在文章中重点但不常见的词,比如一些专业名词等。

n-grams

n-grams 是特征工程中的一种技术,它通过将文本中的连续 n 个词(或字符)组合起来,形成一个短语来捕捉文本中的局部上下文信息。n 可以为 1、2、3 等,具体取决于希望捕捉的上下文范围。

  • 1-gram(Unigram) :每个单独的词作为一个单位。例如,"I love NLP" 的 1-gram 是 ["I", "love", "NLP"]

  • 2-grams(Bigram) :相邻的两个词组合成一个短语。例如,"I love NLP" 的 2-grams 是 ["I love", "love NLP"]

  • 3-grams(Trigram) :相邻的三个词组合成一个短语。例如,"I love NLP" 的 3-grams 是 ["I love NLP"]

深度学习中NLP的特征输入

稠密编码(特征嵌入)

稠密编码(Dense Encoding)

通常指的是将离散或高维稀疏数据转化为低维的连续、密集向量表示。

特征嵌入(Feature Embedding)

特征嵌入,也成为词嵌入,是稠密编码的一种表现形式,目的是将离散的类别、对象或其他类型的特征映射到一个连续的向量空间。

特点:

  • 低维度:相比稀疏表示(如独热编码),稠密编码的维度更低,能够减少计算和存储成本。

  • 语义相似性:嵌入向量之间的距离(如欧氏距离或余弦相似度)可以表示这些对象之间的语义相似性。

  • 可微学习:嵌入表示通常通过神经网络进行学习,并且通过反向传播算法进行优化。

词嵌入算法

Embedding Layer

API

nn.Embedding(num_embeddings=10, embedding_dim=4)

  1. num_embeddings 表示词的数量

  2. embedding_dim 表示用多少维的向量来表示每个词

代码示例

python 复制代码
import torch
import torch.nn as nn
import jieba

test="今天天气真好,好久没有这么好的天了"

#文本分词
words=jieba.lcut(test)

# print(words)
# 输出:
# ['今天天气', '真', '好', ',', '好久', '没有', '这么', '好', '的', '天', '了']

#构建词典
index_to_word={}
word_to_index={}
for i,word in enumerate(set(words)):
    if word not in word_to_index:
        index_to_word[i]=word
        word_to_index[word]=i
# print(word_to_index)
# print(index_to_word)
#输出:
"""
{'今天天气': 0, '真': 1, '好': 2, ',': 3, '好久': 4, '没有': 5, '这么': 6, '
的': 8, '天': 9, '了': 10}
{0: '今天天气', 1: '真', 2: '好', 3: ',', 4: '好久', 5: '没有', 6: '这么', 8: '的', 9: '天', 10: '了'}
"""

#词嵌入层
#第一个参数:词表单词总数 第二个:词嵌入维度
embed=nn.Embedding(len(word_to_index),2)

#将文本转成词向量表示
print("-"*30)
for word in words:
    i=word_to_index[word]
    # 获取词向量
    word_vector=embed(torch.tensor([i]))
    print("%3s\t" % word_vector)

"""
------------------------------
tensor([[0.4638, 1.4010]], grad_fn=<EmbeddingBackward0>)
tensor([[0.2467, 0.5415]], grad_fn=<EmbeddingBackward0>)
tensor([[ 0.1601, -0.2102]], grad_fn=<EmbeddingBackward0>)
tensor([[-0.6121, -1.8269]], grad_fn=<EmbeddingBackward0>)
tensor([[ 0.4472, -0.0368]], grad_fn=<EmbeddingBackward0>)
tensor([[-1.0996,  0.1180]], grad_fn=<EmbeddingBackward0>)
tensor([[-1.0891, -0.2760]], grad_fn=<EmbeddingBackward0>)
tensor([[ 0.1601, -0.2102]], grad_fn=<EmbeddingBackward0>)
tensor([[ 0.3143, -0.9363]], grad_fn=<EmbeddingBackward0>)
tensor([[-0.2251,  0.9102]], grad_fn=<EmbeddingBackward0>)
tensor([[-0.5780, -0.8060]], grad_fn=<EmbeddingBackward0>)
"""
word2vec

Word2vec是一个用来产生词向量的模型。是一个将单词转换成向量形式的工具。

word2vec一般分为CBOW(Continuous Bag-of-Words)与 Skip-Gram 两种模型:

1、CBOW:根据中心词周围的词来预测中心词,有negative sample和Huffman两种加速算法,

CBOW对小型数据库比较合适。

2、Skip-Gram:根据中心词来预测周围词

python 复制代码
"""
假设现在有语料库sentences = ["i like dog", "i love coffee", "i hate milk", "i love milk"] 通过词嵌入层算法和NNLM模型得到以下结果

[['i', 'like'], ['i', 'love'], ['i', 'hate'], ['i', 'love']] -> ['dog', 'coffee', 'milk', 'milk']
"""


import torch
import torch.nn as nn
import numpy
import torch.optim as optim

sentences= ["i like dog", "i love coffee", "i hate milk","i love milk"]
#创建词表和对应的映射关系
word_list = " ".join(sentences).split()
# print(word_list)
"""
['i', 'like', 'dog', 'i', 'love', 'coffee', 'i', 'hate', 'milk','i', 'love', 'milk']
"""

word_list= list(set(word_list))
word_dict = {w: i for i, w in enumerate(word_list)}
number_dict = {i: w for i, w in enumerate(word_list)}
n_class = len(word_dict)#词表大小

#设置模型超参数
m_dim=2#嵌入向量的维度
n_hidden=2#神经元数量
n_step=2#输入步长数

#创建输入的样本和目标值
def make_batch(sentences):
    input_batch = []
    target_batch = []
    
    for sen in sentences:
        word = sen.split()
        # print(word)
        input = [word_dict[n] for n in word[:-1]]
        target = word_dict[word[-1]]
        
        input_batch.append(input)
        target_batch.append(target)
        
    return input_batch,target_batch

#创建模型
class NNLM(nn.Module):
    def __init__(self,n_step,n_class,m_dim,n_hidden):
        super (NNLM,self).__init__()
        #定义嵌入层,单词索引映射为嵌入向量
        self.embed=nn.Embedding(n_class,m_dim)
        #第一层隐藏层
        self.linear1=nn.Linear(m_dim*n_step,n_hidden)
        #分类类别数就是词表大小
        self.linear2=nn.Linear(n_hidden,n_class)
        

    def forward(self,x):
        x=self.embed(x)#通过嵌入层得到的形状是(batch_size,n_step,m_dim) ->(batch_size,n_step*m_dim)
        x=x.view(-1,n_step*m_dim)#拉平为二维数据
        h=torch.tanh(self.linear1(x))
        output=self.linear2(h)
        return output
    
#初始化模型
model=NNLM(n_step,n_class,m_dim,n_hidden)

#创建损失函数和优化器
criterion=nn.CrossEntropyLoss()#损失函数 交叉熵
optimizer=optim.Adam(model.parameters(),lr=0.001)#优化器 学习率

#准备输入和目标数据
input_batch,target_batch=make_batch(sentences)
input_batch=torch.LongTensor(input_batch)
target_batch=torch.LongTensor(target_batch)




for epoch in range(5000):
    optimizer.zero_grad()#梯度清零    
    output=model(input_batch)
    loss=criterion(output,target_batch)
    
    if (epoch+1)%1000==0:
        print(f'Epoch:, %04d % (epoch+1), cost=, {loss:.6f}.format(loss)')
        
    loss.backward()#反向传播
    optimizer.step()#更新参数
    
#使用训练好的模型进行预测
predict=model(input_batch).max(1,keepdim=True)[1]

#输出预测结果
print([sen.split()[:2] for sen in sentences],'->',[number_dict[n.item()] for n in predict.squeeze()])    


"""
Epoch:, %04d % (epoch+1), cost=, 0.601257.format(loss)
Epoch:, %04d % (epoch+1), cost=, 0.511757.format(loss)
Epoch:, %04d % (epoch+1), cost=, 0.452694.format(loss)
Epoch:, %04d % (epoch+1), cost=, 0.412047.format(loss)
Epoch:, %04d % (epoch+1), cost=, 0.389134.format(loss)
[['i', 'like'], ['i', 'love'], ['i', 'hate'], ['i', 'love']] -> ['dog', 'milk', 'milk', 'milk']
相关推荐
张小生1805 分钟前
《深度学习》—— 神经网络中常用的激活函数
人工智能·深度学习·神经网络
俏皮舌大烟佬8 分钟前
NLP基础
人工智能·深度学习·自然语言处理·nlp
Kenneth風车10 分钟前
【第十二章:Sentosa_DSML社区版-机器学习之回归】
人工智能·算法·低代码·机器学习·数据挖掘·数据分析·回归
正义的彬彬侠16 分钟前
LASSO回归(L1回归L1正则化)举例说明:正则化项使不重要的特征系数逐渐为零0的过程
人工智能·机器学习·回归·线性回归
美狐美颜sdk1 小时前
实时美颜的技术突破:视频美颜SDK与直播美颜工具的开发详解
人工智能·性能优化·音视频·美颜sdk·第三方美颜sdk·视频美颜sdk
Baihai_IDP1 小时前
快速理解 GraphRAG:构建更可靠、更智能的 Chatbot
人工智能·llm·aigc
职场人参1 小时前
amr音频文件怎么转换成mp3?操作简单的几种转换方法
人工智能·语音识别
零零刷1 小时前
道路车辆功能安全 ISO 26262标准(1)—适用范围和主要内容
人工智能·功能测试·安全·自动驾驶·汽车
阿利同学2 小时前
基于opencv的车牌检测和识别系统(代码+教程)
人工智能·python·opencv·计算机视觉·车牌识别·pyqt5·联系 qq1309399183
清流君2 小时前
【自动驾驶】控制算法(九)深度解析车辆纵向控制 | 从算法基础到 Carsim 仿真实践
人工智能·笔记·算法·自动驾驶·控制算法