NLP_自然语言处理项目(1):客户评价分类(基于PyTorch)


大家好,我是Loong,今天给大家分享一个关于客户评价分类的NLP项目。这个项目,主要利用NLP技术对客户输入的评价进行分析并且进行一个简单的二分类——正向/负向。可以参考学习!

目录

前言

一、下载数据集

二、测试数据集是否下载成功

三、构建模型

四、加载数据集

五、开启训练

六、测试

七、验证效果

八、结果展示

结语


前言

NLP(自然语言处理)任务是指使用计算机程序和算法来理解、解释和生成人类语言的各项任务。以下是一些常见的NLP任务:
1. 文本分类:将文本数据分配到一个或多个类别中,例如垃圾邮件检测、情感分析。
2. 情感分析:识别文本中的情感倾向,如正面、负面或中性。
3. 实体识别(NER):从文本中识别出具有特定意义的实体,如人名、地点、组织名等。
4. 词性标注:为文本中的每个单词标注正确的词性,如名词、动词、形容词等。
5. 句法分析:分析文本的句法结构,确定单词之间的关系,如主谓宾结构。
6. 机器翻译:将一种语言的文本自动翻译成另一种语言。
7. 文本摘要:从长文本中提取关键信息,生成简洁的摘要。
8. 问答系统:根据给定的问题,从一组文档中找到最合适的答案。
9. 文本生成:自动生成文本,如撰写新闻报道、生成诗歌等。
10. 对话系统:创建能够与人类进行交流的聊天机器人。
11. 语义理解:理解句子或文本的含义,而不仅仅是字面意思。
12. 语音识别:将语音信号转换为文本。
13. 关键词提取:从文本中提取出代表文档主题的关键词。
14. 文本相似度:计算两段文本之间的相似度,用于文档聚类或重复内容检测。
15. 自然语言生成(NLG):从数据生成自然语言描述,常用于报告生成。

一、下载数据集

  • 注意:如果是在线下载需要科学上网(后期更新会讲到如何科学上网)
from datasets import load_dataset

# 加载 ChnSentiCorp 数据集并指定缓存目录为 /root/240620code/first_nlp_project/data/test 目录
dataset = load_dataset('seamew/ChnSentiCorp', cache_dir='/root/240620code/first_nlp_project/data/test')

二、测试数据集是否下载成功

from datasets import list_datasets, load_dataset, load_from_disk

# # 设置data_files 
# data_files = {
#     'train': '/root/240620code/first_nlp_project/data/ChnSentiCorp/chn_senti_corp-train.arrow',
#     'test': '/root/240620code/first_nlp_project/data/ChnSentiCorp/chn_senti_corp-test.arrow',
#     'validation': '/root/240620code/first_nlp_project/data/ChnSentiCorp/chn_senti_corp-validation.arrow'}
# # 加载arrow数据集
# dataset = load_dataset('arrow', data_files=data_files)
# # 保存至本地
# dataset.save_to_disk('/root/240620code/first_nlp_project/datasets/chn_senti_corp')
# # 从本地加载数据集
dataset = load_from_disk("/root/240620code/first_nlp_project/datasets/ChnSentiCorp")


# 查看一下训练集
train_datas = dataset["train"]
for train_data in train_datas:
    print(train_data)

三、构建模型

import torch
from transformers import BertModel
from torch import nn

DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

pretrained = BertModel.from_pretrained("bert-base-chinese").to(DEVICE)

# print(pretrained)

# 定义下游任务模型
class MyModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc = nn.Linear(768, 2)

    def forward(self, input_ids, attention_mask, token_type_ids):
        with torch.no_grad():
            out = pretrained(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
        out = self.fc(out.last_hidden_state[:, 0])
        out = out.softmax(dim=1)
        return out

四、加载数据集

from torch.utils.data import Dataset
from datasets import load_from_disk

class MyDataset(Dataset):
    def __init__(self, split):
        # 1、从huggingface官网下拉取数据集(网络好)
        # self.dataset = load_dataset(path='seamew/ChnSentiCorp', split="train")

        # 2、从本地加载数据集
        self.dataset = load_from_disk("/root/240620code/first_nlp_project/datasets/ChnSentiCorp")
        if split == "trian":
            self.dataset = self.dataset["train"]
        elif split == "validation":
            self.dataset = self.dataset["validation"]
        else:
            self.dataset = self.dataset["test"]
    def __len__(self):
        return len(self.dataset)

    def __getitem__(self, item):
        text = self.dataset[item]["text"]
        label = self.dataset[item]["label"]

        return text, label

if __name__ == '__main__':
    myDataset = MyDataset("train")
    for data in myDataset:
        print(data)
        

五、开启训练

import torch
from torch import nn
from mydata import MyDataset
from torch.utils.data import DataLoader
from net import MyModel
from transformers import AdamW, BertTokenizer

DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

EPOCH = 30000

token = BertTokenizer.from_pretrained("bert-base-chinese")

def collate_fn(data):
    sents = [i[0] for i in data]
    label = [i[1] for i in data]

    # 编码
    data = token.batch_encode_plus(
        batch_text_or_text_pairs = sents,
        # 当句子长度大于max_length时,截断
        truncation = True,
        # 一律补齐到max_length长度
        padding = "max_length",
        max_length = 500,
        return_tensors = "pt",
        return_length = True
    )

    input_ids = data["input_ids"]
    attention_mask = data["attention_mask"] 
    token_type_ids = data["token_type_ids"]
    labels = torch.LongTensor(label)

    return input_ids, attention_mask, token_type_ids, labels

# 创建数据集
train_date = MyDataset("train")
# 加载数据 drop_last:不满足要求的数据集直接丢弃  collate_fn:对加载进来的数据进行处理 -> 编码处理
train_loader = DataLoader(dataset=train_date, batch_size=32, shuffle=True, drop_last=True, collate_fn=collate_fn)



def train():
    model = MyModel().to(DEVICE)
    optimizer = AdamW(model.parameters(), lr=5e-4)
    loss_func = nn.CrossEntropyLoss()
    # 开始训练
    model.train()
    for epoch in range(EPOCH):
        for i, (input_ids, attention_mask, token_type_ids, labels) in enumerate(train_loader):
            input_ids = input_ids.to(DEVICE)
            attention_mask = attention_mask.to(DEVICE)
            token_type_ids = token_type_ids.to(DEVICE)
            labels = labels.to(DEVICE)
            out = model(input_ids, attention_mask, token_type_ids)

            loss = loss_func(out, labels)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            if i % 5 == 0:
                out = out.argmax(dim=1)
                acc = (out == labels).sum().item() / len(labels)
                print("epoch======>", epoch, i, "loss======>", loss.item(), "acc======>", acc)
        torch.save(model.state_dict(), f"/root/240620code/first_nlp_project/params/{epoch}bert01.pth")
        print(epoch, "参数保存成功!")

if __name__ == '__main__':
    train()

    # for i, (input_ids, attention_mask, token_type_ids, labels) in enumerate(train_loader):
    #     print(i)
    #     print("input_ids:", input_ids.shape)
    #     print("attention_mask:", attention_mask.shape)
    #     print("token_type_ids:", token_type_ids.shape)
    #     print("labels:", labels.shape)

六、测试

import torch
from torch import nn
from mydata import MyDataset
from torch.utils.data import DataLoader
from net import MyModel
from transformers import AdamW, BertTokenizer

DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

token = BertTokenizer.from_pretrained("bert-base-chinese")

def collate_fn(data):
    sents = [i[0] for i in data]
    label = [i[1] for i in data]

    # 编码
    data = token.batch_encode_plus(
        batch_text_or_text_pairs = sents,
        # 当句子长度大于max_length时,截断
        truncation = True,
        # 一律补齐到max_length长度
        padding = "max_length",
        max_length = 500,
        return_tensors = "pt",
        return_length = True
    )

    input_ids = data["input_ids"]
    attention_mask = data["attention_mask"] 
    token_type_ids = data["token_type_ids"]
    labels = torch.LongTensor(label)

    return input_ids, attention_mask, token_type_ids, labels

# 创建数据集
test_date = MyDataset("test")
# 加载数据 drop_last:不满足要求的数据集直接丢弃  collate_fn:对加载进来的数据进行处理 -> 编码处理
test_loader = DataLoader(dataset=test_date, batch_size=32, shuffle=True, drop_last=True, collate_fn=collate_fn)

def test():
    model = MyModel().to(DEVICE)
    model.load_state_dict(torch.load("/root/240620code/first_nlp_project/params/16bert01.pth"))
    # 开始测试
    model.eval()
    acc = 0
    total = 0
    for i, (input_ids, attention_mask, token_type_ids, labels) in enumerate(test_loader):               
        input_ids = input_ids.to(DEVICE)
        attention_mask = attention_mask.to(DEVICE)
        token_type_ids = token_type_ids.to(DEVICE)
        labels = labels.to(DEVICE)
        out = model(input_ids, attention_mask, token_type_ids)
                
        out = out.argmax(dim=1)
        acc += (out == labels).sum().item()
        total += len(labels)
    print(acc / total)

if __name__ == '__main__':
    test()

七、验证效果

import torch
from net import MyModel
from transformers import BertTokenizer

DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
names = ["负向评价", "正向评价"]
model = MyModel().to(DEVICE)

token = BertTokenizer.from_pretrained("bert-base-chinese")

def collate_fn(data):
    sents = []
    sents.append(data)
    # 编码
    data = token.batch_encode_plus(
        batch_text_or_text_pairs = sents,
        # 当句子长度大于max_length时,截断
        truncation = True,
        # 一律补齐到max_length长度
        padding = "max_length",
        max_length = 500,
        return_tensors = "pt",
        return_length = True
    )

    input_ids = data["input_ids"]
    attention_mask = data["attention_mask"] 
    token_type_ids = data["token_type_ids"]

    return input_ids, attention_mask, token_type_ids

def val():
    model.load_state_dict(torch.load("/root/240620code/first_nlp_project/params/16bert01.pth"))
    # 开始验证
    model.eval()
    while True:
        data = input("请输入测试数据(输入'q'退出):")
        if data == "q":
            print("测试结束!")
            break
        input_ids, attention_mask, token_type_ids = collate_fn(data=data)
        input_ids = input_ids.to(DEVICE)
        attention_mask = attention_mask.to(DEVICE)
        token_type_ids = token_type_ids.to(DEVICE)

        with torch.no_grad():
            out = model(input_ids, attention_mask, token_type_ids)
            out = out.argmax(dim=1)
            print("模型判定:", names[out], "\n")

if __name__ == '__main__':
    val()

八、结果展示

结语

本次分享就到这了,如果上面代码对您有帮助,欢迎点个赞!!!

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值