【神经网络与深度学习】文本情感分类

数据准备

AclImdb – v1 Dataset 是用于二进制情绪分类的大型电影评论数据集,其涵盖比基准数据集更多的数据,其中有 25,000 条电影评论用于训练,25,000 条用于测试,还有其他未经标记的数据可供使用。

数据预处理和数据装载

import re

from torch.utils.data import DataLoader
from torch.utils.data import Dataset
import os

def tokenization(content):
    content = re.sub("<.*?>"," ",content)
    fileters = ['\t','\n','\x97','\x96','#','%','$','&',"\.","\?","!","\,"]
    content = re.sub("|".join(fileters)," ",content)
    tokens = [i.strip().lower() for i in content.split()]
    return tokens

def collate_fn(batch):
    """

    :param batch:( [tokens, labels], [tokens, labels])
    :return:
    """
    content, label  = list(zip(*batch))
    return content,label

class ImdbDataset(Dataset):
    def __init__(self, train=True):
        self.train_data_path = '..\\aclImdb\\train\\'
        self.test_data_path = '..\\aclImdb\\test\\'
        data_path = self.train_data_path if train else self.test_data_path
        #把所有文件名放入列表
        temp_data_path = [os.path.join(data_path,"pos"), os.path.join(data_path+"neg")]
        print(temp_data_path)
        self.total_file_path = [] #所有评论文件路径
        for path in temp_data_path:
            file_name_list = os.listdir(path)
            file_path_list = [os.path.join(path, i) for i in file_name_list if i.endswith(".txt")]
            self.total_file_path.extend(file_path_list)

    def __len__(self):
        return len(self.total_file_path)

    def __getitem__(self, index):
        file_path = self.total_file_path[index]
        # 获取label
        labelstr = file_path.split("\\")[-2]
        label = 0 if labelstr == "neg" else 1
        # 获取内容
        content = open(file_path).read()
        tokens = tokenization(content)


        return tokens, label

def get_data(train=True):
    imbd_dataset = ImdbDataset(train)
    data_loader = DataLoader(imbd_dataset, batch_size=2, shuffle=True,collate_fn=collate_fn)
    return data_loader

文本序列化

把文本里每个词语和其对应数字,使用字典保存 即句子—>数字列表
思路

  1. 句子进行分词(tokenization)
  2. 词语存入字典,统计出现次数,根据出现次数对齐进行过滤
  3. 把文本 转 数字序列
  4. 把 数字序列 转 文本

遇到新出现的字符再词典里没有,可以用特殊字符替代
预保持每个batch里的序列大小一致,使用填充方法

"""
构建词典 把句子转换成序列 再把序列转成句子
"""

class Word2Sequence:
    UNK_TAG = "UNK"
    PAD_TAG = "PAD"

    UNK =0
    PAD =1

    def __init__(self):
        self.dict = {
            self.UNK_TAG: self.UNK,
            self.PAD_TAG: self.PAD
        }
        self.count = {}

    def fit(self, sentence):

        # 把单个句子保存到dict
        for word in sentence:
            self.count[word] = self.count.get(word, 0)+1

    def build_vocab(self, min=5, max=None, max_features=None):
        """

        :param min:
        :param max:
        :param max_features: 一共保留多少个词语
        :return:
        """
        # 删除count中词频小于min的词语
        self.count = {word:value for word, value in self.count.items() if value>min}
        # 删除count中词频大于max的词语
        if max is not None:
            self.count = {word: value for word, value in self.count.items() if value < max}
        # 限制保留的词语数
        if max_features is not None:
            temp = sorted(self.cout.items(), key=lambda x:x[-1], reverse=True)[:max_features]
            self.count = dict(temp)

        # 把 词语 ——>数字
        for word in self.count:
            self.dict[word] = len(self.dict)

        # 得到一个反转的dict字典
        self.inverse_dict = dict(zip(self.dict.values(), self.dict.keys()))

    def transform(self, sentence, max_len=None):
        """
        把句子 转成 序列
        :param sentence:  [word1, word2, ..]
        :param max_len: 对句子进行填充或者裁剪
        :return:
        """
        if max_len is not None:
            if max_len > len(sentence):
                sentence = sentence + [self.PAD_TAG] * (max_len - len(sentence)) # 填充
            if max_len < len(sentence):
                sentence = sentence[:max_len] # 裁剪

        return [self.dict.get(word, self.UNK) for word in sentence]

    def inverse_transform(self, indices):
        # 把 序列 ——>句子
        return [self.inverse_dict.get(idx) for idx in indices]

if __name__ == '__main__':
    ws = Word2Sequence()
    ws.fit(["我","是","你","的","爸爸"])
    ws.fit(["我","是","我","的","人"])
    ws.build_vocab(min=0)

    print(ws.dict)
    re = ws.transform(["我","爱","人"],max_len=10)
    print(re)
    ret = ws.inverse_transform(re)
    print(ret)
    

模型构建(简单全连接)

注意 word_embedding的使用!

"""
定义模型
"""
import torch
import torch.nn as nn
import torch.nn.functional as F
from lib import ws,max_len
from dataset import get_data
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.embedding = nn.Embedding(len(ws), 100)
        self.fc = nn.Linear(100*max_len, 2)



    def forward(self, input):
        """

        :param input: [batch_size, max_len]
        :return:
        """
        x = self.embedding(input) # [batch_size, max_len, 100]
        x = x.view([-1, 100*max_len])
        output = self.fc(x)
        return F.log_softmax(output,dim=-1)

model = MyModel()
optimizer = torch.optim.Adam(model.parameters(),lr=0.001)
def train(epoch):
    for idx,(input,target) in enumerate(get_data(train=True)):
        # 梯度清零
        optimizer.zero_grad()
        output= model(input)
        loss = F.nll_loss(output,target)
        loss.backward()
        optimizer.step()
        print(loss.item())

if __name__ == '__main__':
    for i in range(1):
        train(epoch=i)

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 引言 随着社交媒体和互联网的普及,人们在日常生活中产生了大量的文本数据,如评论、微博、新闻等。这些文本数据中包含了大量的情感信息,对于企业和个人来说,了解消费者或用户的情感倾向是非常重要的。文本情感分类就是将文本数据根据其情感倾向进行分类的任务。 传统的文本情感分类算法主要基于词袋模型和统计特征,这些算法往往需要手动提取特征,并且对于文本中的语义信息无法很好地处理。现在,深度学习技术的发展使得文本情感分类任务得到了很大的改善,深度学习模型可以从原始的文本数据中学习到高层次的语义特征并进行分类。 本文将介绍基于深度学习文本情感分类算法的设计和实现,主要包括以下内容: - 文本情感分类任务的定义和评估指标 - 常见的深度学习模型及其在文本分类任务中的应用 - 模型训练和优化方法 - 实验结果分析 2. 文本情感分类任务 文本情感分类任务是将一段文本分为正面、负面或中性三个类别中的一个。在实际应用中,还可能需要更细粒度的分类,如喜欢、不喜欢、中立、愤怒、悲伤等。对于文本情感分类任务,评估指标主要有准确率、召回率、精确率和F1值等。 - 准确率(Accuracy):分类正确的样本数占总样本数的比例。 - 召回率(Recall):分类正确的正样本数占实际正样本数的比例。 - 精确率(Precision):分类正确的正样本数占分类为正样本的样本数的比例。 - F1值:综合考虑精确率和召回率的值,F1值越高,分类效果越好。 3. 常见的深度学习模型 深度学习模型在文本分类中的应用主要有卷积神经网络(Convolutional Neural Network,CNN)、长短时记忆网络(Long Short-Term Memory,LSTM)、循环神经网络(Recurrent Neural Network,RNN)等。这些模型在文本分类任务中的表现都非常好,具体应用如下: - CNN模型:CNN模型主要用于图像识别任务,但是在文本分类任务中也有广泛的应用。CNN模型可以对文本中的n-gram特征进行提取和组合,从而学习到连续的语义信息。例如,可以使用卷积层对文本的词向量表示进行卷积,然后使用池化层将结果压缩成固定长度的向量,最后使用全连接层进行分类。 - LSTM模型:LSTM模型是一种能够处理长序列数据的循环神经网络模型。在文本分类任务中,LSTM模型可以捕捉文本中的长期依赖关系,从而提高分类性能。LSTM模型在处理文本时,可以将每个词的词向量表示作为输入,然后使用LSTM单元对序列进行处理。 - RNN模型:RNN模型是一种能够处理序列数据的循环神经网络模型,它可以对序列数据进行逐个处理,并且可以将前面的信息传递给后面。在文本分类任务中,RNN模型可以对文本中的历史信息进行建模,从而提高分类性能。RNN模型在处理文本时,可以将每个词的词向量表示作为输入,然后使用RNN单元对序列进行处理。 4. 模型训练和优化方法 在深度学习模型中,模型的训练和优化是非常重要的环节。常见的模型训练和优化方法主要有以下几种: - 梯度下降法:梯度下降法是一种常用的优化方法,它通过计算误差函数相对于参数的梯度,并根据梯度的反方向更新参数。梯度下降法可以使用批量梯度下降法(Batch Gradient Descent,BGD)、随机梯度下降法(Stochastic Gradient Descent,SGD)或者小批量梯度下降法(Mini-Batch Gradient Descent,MBGD)等不同的方式进行。 - 反向传播算法:反向传播算法是一种计算神经网络中误差梯度的方法。在深度学习模型中,反向传播算法通常与梯度下降法一起使用,用于更新模型的参数。 - Dropout:Dropout是一种常用的正则化方法,它可以随机地将神经元的输出设置为0,从而防止过拟合。Dropout可以在训练期间随机选择一些神经元进行dropout操作,从而强制模型学习到更加鲁棒的特征。 - Batch Normalization:Batch Normalization是一种常用的优化方法,它可以加速模型的训练并提高模型的准确率。Batch Normalization可以对每一层的输出进行标准化,从而使得输入到每一层的值都在一个较小的范围内,从而加速模型的训练过程。 5. 实验结果分析 为了评估基于深度学习文本情感分类算法的性能,我们可以使用公开的数据集进行实验。例如,可以使用IMDB数据集、Yelp数据集或者Amazon数据集等进行实验。在实验中,我们需要将数据集划分为训练集、验证集和测试集,并使用交叉验证等方法进行模型的选择和参数的调优。实验结果可以使用准确率、召回率、精确率和F1值等指标进行评估。 总之,基于深度学习文本情感分类算法可以有效地处理文本中的语义信息,从而提高分类性能。在实际应用中,我们可以根据具体的任务选择合适的深度学习模型和优化方法,并对模型进行训练和优化,从而得到更好的分类结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值