NLP
简介
NLP(Natural Language Processing)是自然语言处理的缩写,是人工智能和语言学领域的交叉学科,旨在让计算机能够理解和处理人类语言。
NLP 的目标包括让计算机能够读取、解析、理解和生成人类语言文本,从而进行各种与语言相关的任务,如文本分类、情感分析、机器翻译、问答系统、聊天机器人等。
NLP研究的内容
NLP 的研究内容包括但不限于以下几个方面:
-
词法分析:包括分词、词性标注、命名实体识别等。
-
句法分析:分析句子结构,如短语划分、依存关系分析等。
-
语义分析:理解句子或文本的含义,包括词义消歧、语义角色标注等。
-
信息抽取:从文本中提取结构化信息,如关系抽取、事件抽取等。
-
文本生成:根据特定要求生成自然语言文本,如文本摘要、文本续写等。
-
文本分类:将文本划分为预定义的类别,如情感分析、主题分类等。
-
机器翻译:将一种语言的文本转换为另一种语言的文本。
-
问答系统:根据用户提出的问题,从文本或知识库中检索答案。
NLP 研究者通常会使用各种算法和模型,如基于规则的方法、基于统计的方法、基于深度学习的方法等。近年来,随着深度学习技术的快速发展,基于神经网络的 NLP 模型,如循环神经网络(RNN)、长短期记忆网络(LSTM)、Transformer 等,在 NLP 任务中取得了显著的性能提升。
核心任务
- 自然语言理解 - NLU (Natural Language Understanding)
- 自然语言生成 - NLG (Natural Language Generation)
NLU
NLU就是机器需要理解人的意思
让我们来举个栗子:
- 标点歧义:下雨天留客天天就我不留
- 结构歧义:这是许多朋友送来的礼物
- 语义歧义:来上课的多半是男生
- 相同意思:我想听歌;来点音乐;放首歌
难点
- 语言的多样性:自然语言有很多不同的表达,组合方式非常灵活,不同的组合可以表达多种含义,总能找到很多例外的情况。
- 语言的歧义性:如果不联系上下文,缺少环境的约束,语言有很大的歧义性。
- 语言的鲁棒性:自然语言在输入的过程中,尤其是通过语音识别获得的文本,会存在多字、少字、错字、噪音等问题。
- 语言的知识依赖:语言是对世界的符号化描述,语言天然连接着世界知识。
- 语言的上下文:上下文的概念包括很多种:对话的上下文、设备的上下文、应用的上下文、用户画像。
应用
- 机器翻译(有道、百度翻译等)
- 机器客服(各种app里面的机器客户)
- 智能音箱(小爱音箱、天猫精灵等)
NLG
NLG机器根据信息生成文本内容,该信息可以是语音、视频、图片、文字等等
方式
- text - to - text:文本到语言的生成
- data - to - text:数据到语言的生成
LEVEL
- 数据合并:自然语言处理的简化形式,这将允许将数据转换为文本(通过类似 Excel的函数)。
- 模板化的NLG:这种形式的NLG使用模板驱动模式来显示输出。数据动态地保持更改,并由预定义的业务规则集(如if/else循环语句)生成。
- 高级NLG:这种形式的自然语言生成就像人类一样。它理解意图,添加智能,考虑上下文,并将结果呈现在用户可以轻松阅读和理解的富有洞察力的叙述中。
应用
- 自动写作(自动写新闻,自动写论文等)
- 聊天机器人(各种手机开发的内置聊天机器人,智能音响,商场导航机器人等)
- BI的解读和报告生成(各行各业解读报告生成比如体检报告)
发展历程
- 神经语言模型(2001): 引入前馈神经网络作为第一个神经语言模型,为后续语言建模任务奠定基础。
- 多任务学习(2008): Collobert和Weston首次将多任务学习应用于神经网络,通过共享参数在不同任务之间实现信息传递。
- 词嵌入(2013): 引入词嵌入作为语言建模的关键组成部分,将单词映射到连续向量空间。
- NLP神经网络(2013): 开始出现基于神经网络的NLP模型,标志着从传统方法向深度学习方法的过渡。
- Sequence-to-Sequence模型(2014): 引入了序列到序列(seq2seq)模型,广泛应用于机器翻译等任务。
- 注意力机制(2015): 注意力机制的引入提高了模型对输入中不同部分的关注度,改善了序列处理任务的性能。
- 基于记忆的网络(2015): 利用记忆网络处理长距离依赖关系,提高了对长文本序列的建模能力。
- 预训练语言模型(2018): 引入预训练语言模型,通过大规模数据的预训练在特定任务上取得显著性能提升。
常见任务
- 分词:将句子、段落、文章这种长文本,分解为以字词为单位的数据结构,方便后续的 处理分析工作。
- 词性标注:为每个单词分配一个词性标签(如名词、动词、形容词等),以帮助识别实体。
- 命名实体识别(ner):从文本中识别和分类命名实体,如人名、地名、组织机构名、日期、时间、货币等。
分词
概述
分词模型就是将句子、段落、文章这种长文本,分解为以字词为单位的数据结构,方便后续的 处理分析工作的模型。
分词在NLP(自然语言处理)中扮演着至关重要的角色,是许多NLP任务和应用的基石。以下是分词在NLP中的一些主要作用:
-
文本预处理:分词是文本预处理的重要步骤之一。在将文本数据输入到NLP模型之前,通常需要对文本进行清洗、去除停用词、分词等预处理操作。分词能够将连续的文本切分成独立的词汇单元,便于后续的分析和处理。
-
特征提取:分词有助于从文本中提取有意义的特征。在NLP任务中,如文本分类、情感分析、命名实体识别等,分词可以将文本转化为适合机器学习模型处理的特征向量。通过分词,可以提取出文本中的关键词、短语或句子,作为模型的输入特征。
-
语言理解:分词对于计算机理解人类语言具有重要意义。通过将连续的文本切分成词汇单元,计算机可以更容易地识别和理解文本中的语义信息。分词可以帮助计算机识别出文本中的主语、谓语、宾语等语法成分,进而理解文本的含义和上下文关系。
-
信息检索:在信息检索领域,分词是构建高效搜索引擎的关键技术之一。通过分词,搜索引擎可以将用户的查询语句和文档库中的文本进行匹配,从而找到相关的文档。分词可以确保查询语句和文档中的词汇单元在语义上保持一致,提高检索的准确性和效率。
-
机器翻译:在机器翻译中,分词是翻译过程中的重要环节。通过将源语言文本进行分词,机器翻译系统可以更容易地识别出文本中的词汇单元和语法结构,进而生成准确的翻译结果。分词还可以帮助机器翻译系统处理不同语言之间的词汇对齐和语法差异问题。
-
问答系统:在问答系统中,分词有助于将用户的问题和系统中的知识库进行匹配。通过分词,系统可以将用户的问题切分成独立的词汇单元,并与知识库中的信息进行比对和匹配,从而找到相关的答案。分词可以提高问答系统的准确性和响应速度。
常见的分词模型
- jieba
- ansj分词器
- Hanlp(最高支持python3.8)
- Stanford
- 哈工大LTP
- KCWS分词器
- IK
- 清华大学THULAC
- ICTCLAS
jieba分词
jieba分词是一个用于中文文本分词的Python库
安装
pip3 install jieba
使用
# 导入jieba库
import jieba
# jieba分词提供了多种分词模式
# **精确模式**:将句子最精确地切开,适合文本分析。
seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list)) # 输出: 我/ 来到/ 北京/ 清华大学
# **全模式**:把句子中所有的可以成词的词语都扫描出来,速度非常快,但是不能解决歧义。
seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list)) # 输出: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
# **搜索引擎模式**:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
seg_list = jieba.cut_for_search("我来到北京清华大学")
print("Search Mode: " + "/ ".join(seg_list)) # 输出: 我/ 来到/ 北京/ 清华/ 华大/ 大学/ 清华大学
# **添加自定义词典**:jieba支持用户自定义词典,可以在分词时包含jieba词库中没有的词。
jieba.load_userdict("userdict.txt") # 加载自定义词典
seg_list = jieba.cut("他来到了网易杭研大厦")
print(" ".join(seg_list)) # 输出: 他/ 来到/ 了/ 网易/ 杭研/ 大厦
词向量
概述
词向量(Word Embedding)是自然语言处理(NLP)中用来表示词汇的一种高维向量。这种向量通常是通过训练神经网络模型从大量文本数据中学习得到的,能够捕捉词汇之间的语义和语法关系。
常见的词向量模型
one-hot编码
无论是人类还是计算机都很难直接将语言字符进行计算。我们期望着把语言字符转换为一种便于计算的形式,也就是把对应的词汇用数值类型的数据进行唯一表示。最简单的一种将语言字符转换为便于计算的一种方式就是one-hot编码。
我们举一个简单的例子:我们为每一种水果创建了一个新的列,并且在原始数据中的水果对应的列上标记为 1,其余列标记为 0
Word2Vec
Word2vec 也叫 Word Embeddings,中文名“词向量”。作用就是将自然语言中的字词转为计算机可以理解的稠密向量(Dense Vector)。
我们使用gensim来进行说明
安装
pip install gensim
案例
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
import logging
# 配置日志,避免训练过程中的警告信息
# logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
# 假设我们有一个名为'text_corpus.txt'的文本文件,每行包含一个句子,句子中的单词由空格分隔
sentences = LineSentence('text_corpus.txt') # 加载文本数据
# 训练Word2Vec模型
# 参数可以根据你的数据和需求进行调整
#参数如vector_size(向量维度)、window(上下文窗口大小)、min_count(最小词频)和workers(工作线程数)都可以根据你的数据集和需求进行调整。
model = Word2Vec(sentences, vector_size=100, window=15, min_count=1, workers=4)
# 保存模型,以便后续使用
model.save("word2vec.model")
# 加载已保存的模型
# model = Word2Vec.load("word2vec.model")
# 查找单词的向量表示
vector = model.wv['apple'] # 假设'apple'在我们的词汇表中
# print(vector)
# 查找最相似的单词
similar_words = model.wv.most_similar('apple')
print(similar_words)
Embedding
在机器学习和自然语言处理(NLP)中,embedding(嵌入)是一种将一个高维空间中的对象(如单词、短语、句子、图像等)映射到一个低维、稠密、连续的向量空间中的表示方法。这种表示方法通常能够保留原始对象之间的某些关系或属性,使得在向量空间中相似的对象具有相近的表示。
安装
pip3 install torch
案例
import torch
import torch.nn as nn
import torch.optim as optim
# 超参数
vocab_size = 10000 # 词汇表大小
embedding_dim = 50 # 嵌入维度
output_dim = 2 # 输出维度(例如,二分类任务)
num_epochs = 5 # 训练轮数
batch_size = 64 # 批处理大小
learning_rate = 0.001 # 学习率
# 模拟文本数据(实际中你会从文本数据集中获取这些索引)
# 这里我们随机生成一些单词索引作为示例
text_indices = torch.randint(0, vocab_size, (batch_size, 10)) # (batch_size, sequence_length)
# 标签数据(随机生成)
labels = torch.randint(0, output_dim, (batch_size,))
# 定义模型
class SimpleEmbeddingModel(nn.Module):
def __init__(self, vocab_size, embedding_dim, output_dim):
super(SimpleEmbeddingModel, self).__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.fc = nn.Linear(embedding_dim, output_dim)
def forward(self, text_indices):
# 取文本序列中最后一个单词的嵌入(简化的例子)
embedded = self.embedding(text_indices)[:, -1, :]
output = self.fc(embedded)
return output
# 实例化模型
model = SimpleEmbeddingModel(vocab_size, embedding_dim, output_dim)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=learning_rate)
# 训练模型
for epoch in range(num_epochs):
# 前向传播
outputs = model(text_indices)
loss = criterion(outputs, labels)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 打印统计信息
if (epoch+1) % 1 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}')
# 训练完成后,你可以通过调用model.embedding来获取嵌入层
# 例如,查询索引为5的单词的嵌入向量
embedding_vector = model.embedding(torch.tensor([5], dtype=torch.long))
print(embedding_vector)