NLP基础

一、基本概念:

1. 自然语言处理(NLP)基础

  • 定义:人工智能领域,旨在使计算机能够理解、解释和生成人类语言。
  • 目标:理解语言、生成语言、机器翻译、情感分析、语音识别等。
  • 挑战:语言的多样性、歧义性、复杂性。

2.常用的概念名词,便于理解任务。

  1. 词表/词库(Vocabulary):文本数据集中出现的所有单词的集合。
  2. 语料库(Corpus):用于NLP任务的文本数据集合,可以是大规模的书籍、文章、网页等。
  3. 词嵌入(Word Embedding):将单词映射到低维连续向量空间的技术,用于捕捉单词的语义和语法信息。
  4. ​停用词(Stop Words):在文本处理中被忽略的常见单词,如"a"、"the"、"is"等,它们通常对文本的意义贡献较 小。
  5. 分词(Tokenization):将文本分割成一个个单词或标记的过程,为后续处理提供基本的单位。
  6. 词频(Term Frequency):在给定文档中,某个单词出现的次数。
  7. 逆文档频率(Inverse Document Frequency):用于衡量一个单词在整个语料库中的重要性,是将词频取倒数并取 对数的值。
  8. TF-IDF(Term Frequency-Inverse Document Frequency):一种常用的文本特征表示方法,综合考虑了词频和逆文档频率。
  9. 词袋模型(Bag of Words):将文本表示为一个单词的集合,忽略了单词的顺序和语法结构。
  10. N-gram:连续的N个单词构成的序列,用于捕捉文本中的局部特征和上下文信息。
  11. 序列:指的是一个按顺序排列的元素集合。这些元素可以是字符、单词、句子,甚至更抽象的结构。序列的每个元素都有特定的顺序和位置,这意味着它们不能随意重排,否则会影响其意义或功能。

二、NLP中的特征工程

1、独热编码(One-Hot Encoding)

是自然语言处理和机器学习中常用的一种编码技术,用于将分类数据转换为机器学习算法可以更好处理的数值型格式。

2、TF-IDF(Term Frequency-Inverse Document Frequency)

衡量单词在文档中的重要性。

3、n-grams

连续n个词的序列,用于捕捉上下文信息。

4、稠密编码

是一种将离散特征(如单词、字符或其他类型的标记)映射到连续的向量空间的方法。在这个空间中,相似或相关的特征会被映射到相近的位置。

工作原理

向量化:每个类别特征被映射到一个固定维度的实数向量。

语义捕捉:通过训练学习得到的向量能够捕捉到特征之间的语义关系。

5、特征嵌入(Word Embedding)

特征嵌入是稠密编码在NLP中的具体应用,用于将单词映射到密集的向量表示。

维度:词嵌入向量的维度通常远小于词汇表的大小,例如,一个词汇表有100,000个单词,而词嵌入向量的维度可能只有300维。

训练:词嵌入向量通常是通过在大量文本数据上训练神经网络模型学习得到的。

6、词嵌入算法

Embedding Layer

在自然语言处理(NLP)中,嵌入层(Embedding Layer)是一个非常重要的组件,它用于将离散的符号表示(如单词、字符或其他类型的标记)转换为连续的、稠密的向量表示。这些向量表示捕捉了标记之间的语义和句法关系,使得模型能够更好地理解和处理文本数据。

定义

嵌入层通常是一个可学习的权重矩阵,其中每一行代表一个可能的标记的嵌入向量。在训练过程中,这些嵌入向量会根据任务的上下文进行调整和优化。

工作原理
  1. 初始化:嵌入层开始时通常用小的随机值初始化。
  2. 索引查找:输入数据(如单词的索引)用来索引嵌入矩阵,以获取相应的嵌入向量。
  3. 前向传播:这些嵌入向量被用作模型的输入,传递到后续的层中进行进一步的处理。
  4. 反向传播:在训练过程中,通过反向传播算法更新嵌入层的权重。
特点
  • 高维表示:嵌入向量通常是高维的,可以捕捉丰富的语义信息。
  • 稀疏性:在初始化阶段,嵌入向量是随机的,但通过学习变得有意义。
  • 可微分:嵌入层的权重可以通过梯度下降等优化算法进行更新。
简单使用:
text = '早岁已知世事艰,仍许飞鸿荡云间。一路寒风身如絮,命海沉浮客独行。千磨万击心铸铁,殚精竭虑铸一剑。今朝剑指叠云处,炼蛊炼人还炼天。'

import torch
import torch.nn as nn
import jieba
# 1、jieba分词
words = jieba.lcut(text)
words = set(words)
# print(words)

# 2、构建词表
index_to_word = {}
word_to_index = {}
for idex,word in enumerate(words):
    index_to_word[idex] = word
    word_to_index[word] = idex
# print(word_to_index)
# print(index_to_word)

# 3、词嵌入层
embed = nn.Embedding(num_embeddings=len(word_to_index),embedding_dim=3)

# 4、将文本转为词向量表示
for word in words:
    idx = word_to_index[word]
    # 获取词向量
    word_vec = embed(torch.tensor([idx]))
    print(word_vec)

word2vec

用于生成词嵌入,即把词语转换为计算机可以更容易处理的数值形式。Word2Vec 通过在大量文本数据上训练一个浅层神经网络来实现这一目标。

Word2Vec 有两种主要的训练模型:

  1. Continuous Bag of Words (CBOW):预测一个词的周围词。
  2. Skip-Gram:根据一个词预测它周围的词。
Skip-Gram

简单实现的代码(主要掌握思路:根据目标单词来预测上下文单词 )

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from matplotlib import pyplot as plt

# 语料库,包含训练模型的句子
sentences = ["i like dog", "i like cat", "i like animal",
             "dog cat animal", "apple cat dog like", "cat like fish",
             "dog like meat", "i like apple", "i hate apple",
             "i like movie book music apple", "dog like bark", "dog friend cat"]

# 构建词表
word_list = " ".join(sentences).split()
word_dict = {w: i for i, w in enumerate(set(word_list))}
vocab_size = len(word_dict)

# 创建skip训练数据集
skip_grams = []
for sentence in sentences:
    words = sentence.split()
    for i, word in enumerate(words):
        if i == 0 or i == len(words) - 1:
            continue
        target = word_dict[word]
        context = [word_dict[words[i-1]], word_dict[words[i+1]]]
        for c in context:
            skip_grams.append([target, c])

# 定义超参数
emb_dim = 11
batch_size = 111

# 定义skip模型
class Word2Vec(nn.Module):
    def __init__(self, vocab_size, emb_dim):
        super(Word2Vec, self).__init__()
        self.W = nn.Parameter(torch.rand(vocab_size, emb_dim))
        self.W2 = nn.Parameter(torch.rand(emb_dim, vocab_size))

    def forward(self, x):
        x = self.W[x]  # 从词嵌入矩阵中获取嵌入向量
        return torch.matmul(x, self.W2)  # 矩阵乘法

# 训练开始
model = Word2Vec(vocab_size=vocab_size, emb_dim=emb_dim)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

def random_batch(data, batch_size):
    input_batch = []
    target_batch = []
    for _ in range(batch_size):
        center_word, context_word = np.random.choice(len(data), 2)
        input_batch.append(data[center_word][0])
        target_batch.append(data[context_word][1])
    return torch.LongTensor(input_batch), torch.LongTensor(target_batch)

for epoch in range(10000):
    input_batch, target_batch = random_batch(skip_grams, batch_size)
    optimizer.zero_grad()
    output = model(input_batch)
    loss = criterion(output, target_batch)
    loss.backward()
    optimizer.step()
    if epoch % 1086 == 0:
        print('Epoch:', epoch, 'Loss:', loss.item())

# 可视化词嵌入
W = model.W.data.numpy()
plt.figure(figsize=(10, 10))
for i, label in enumerate(word_dict.keys()):
    plt.scatter(W[i, 0], W[i, 1])
    plt.annotate(label, xy=(W[i, 0], W[i, 1]), xytext=(5, 5), textcoords='offset points')
plt.show()
CBOW模型

简单实现的代码(掌握主要思路:根据上下文单词来预测目标单词 )

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from matplotlib import pyplot as plt
import random

# 语料库
sentences = [
    "i like dog", "i like cat", "i like animal",
    "dog cat animal", "apple cat dog like", "cat like fish",
    "dog like meat", "i like apple", "i hate apple",
    "i like movie book music apple", "dog like bark", "dog friend cat"
]

# 构建词表
word_sequence = ' '.join(sentences).split()
word_list = list(set(word_sequence))
word_dict = {w: i for i, w in enumerate(word_list)}

# 创建CBOW训练数据集
cbow_data = []
for sentence in sentences:
    words = sentence.split()
    for i, word in enumerate(words):
        if i == 0 or i == len(words) - 1:
            continue
        target = word_dict[word]
        context = [word_dict[words[j]] for j in range(i - 1, i + 2) if j != i and j >= 0 and j < len(words)]
        cbow_data.append((context, target))  # 确保这里是元组

# 模型参数
vocab_size = len(word_dict)
embedding_size = 300
hidden_size = 100  # 新增隐藏层大小
batch_size = 32


# 定义CBOW模型
class CBOW(nn.Module):
    def __init__(self, vocab_size, embedding_size, hidden_size):
        super(CBOW, self).__init__()
        self.embed = nn.Embedding(vocab_size, embedding_size)
        self.hidden = nn.Linear(embedding_size, hidden_size)  # 新增隐藏层
        self.linear = nn.Linear(hidden_size, vocab_size)

    def forward(self, x):
        x = self.embed(x)
        avg_x = torch.mean(x, dim=1)  # 这里使用num_dim=1以求取每一行的平均值
        hidden_x = torch.relu(self.hidden(avg_x))  # 激活函数
        output = self.linear(hidden_x)
        return output

    # 训练开始


model = CBOW(vocab_size, embedding_size, hidden_size)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)


def random_batch(data, batch_size):
    input_batch = []
    target_batch = []
    while len(input_batch) < batch_size:
        context, target = random.choice(data)
        input_batch.append(context)  # 这里是上下文词索引的列表
        target_batch.append(target)

        # 将上下文列表转换为张量并需要调整形状
    input_batch = torch.tensor(input_batch, dtype=torch.long)
    target_batch = torch.tensor(target_batch, dtype=torch.long)
    return input_batch, target_batch


for epoch in range(10000):
    input_batch, target_batch = random_batch(cbow_data, batch_size)
    optimizer.zero_grad()
    output = model(input_batch)
    loss = criterion(output, target_batch)
    loss.backward()
    optimizer.step()
    if epoch % 1086 == 0:
        print('Epoch:', epoch, 'Loss:', loss.item())

    # 可视化词嵌入
embeddings = model.embed.weight.data.numpy()
plt.figure(figsize=(10, 10))
plt.scatter(embeddings[:, 0], embeddings[:, 1])  # 只取嵌入的前两个维度
for i, label in enumerate(word_list):
    plt.annotate(label, xy=(embeddings[i, 0], embeddings[i, 1]),
                 textcoords='offset points', xytext=(5, 5), ha='center')
plt.show()
gensim API调用

API参数详解

  • sentences:训练数据,是一个包含句子的列表,其中每个句子是单词的列表。
  • vector_size:特征向量的维度。
  • window:上下文窗口的大小。
  • min_count:忽略总频率低于此值的所有单词。
  • workers:训练并行化的线程数。

常用方法

  • wv[key]:获取单词的词向量,key为单词。
  • wv.most_similar(positive=[...], topn=10):基于上下文的相似词,positive是正向影响的词列表,topn是返回的相似词数量。
  • wv.similarity(word1, word2):计算两个单词之间的相似度。
  • wv.most_similar_to_given(向量, topn=10):给定一个词向量,找出与之最相似的词。

常用属性

  • wv.index_to_key:将索引映射回单词的列表。
  • wv.key_to_index:将单词映射到索引的字典。

一个超级简单的模型使用过程:

from gensim.models import Word2Vec
import numpy as np
from matplotlib import pyplot as plt

sentences = [
    "i like dog", "i like cat", "i like animal",
    "dog cat animal", "apple cat dog like", "cat like fish",
    "dog like meat", "i like apple", "i hate apple",
    "i like movie book music apple", "dog like bark", "dog friend cat"
]

token_list = [sentence.split() for sentence in sentences]

model = Word2Vec(sentences=token_list, min_count=1, window=1, workers=4, sg=0,vector_size=2)

word_list = list(model.wv.index_to_key)

for i,word in enumerate(word_list):
    w = model.wv[word]
    x,y = float(w[0]),float(w[1])
    plt.scatter(x,y)
    plt.annotate(word,xy=(x,y),xytext=(0,0),textcoords='offset points')
plt.show()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值