【NLP练习】使用Word2Vec实现文本分类

news2025/1/16 3:47:16
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

一、数据预处理

1. 任务说明

本次加入Word2Vec使用PyTorch实现中文文本分类,Word2Vec则是其中的一种词嵌入方法,是一种用于生成词向量的浅层神经网络模型。Word2Vec通过学习大量的文本数据,将每个单词表示为一个连续的向量,这些向量可以捕捉单词之间的语义和句法关系。数据示例如下:
在这里插入图片描述

2. 加载数据

import torch
import torch.nn as nn
import torchvision
from torchvision import transforms,datasets
import os,PIL,pathlib,warnings

warnings.filterwarnings("ignore")   #忽略警告信息

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

输出:

device(type='cpu')
import pandas as pd

#加载自定义中文数据
train_data = pd.read_csv(r'D:\Personal Data\Learning Data\DL Learning Data\train.csv',sep ='\t',header = None)
train_data.head()

输出:
在这里插入图片描述

#构造数据集迭代器
def coustom_data_iter(texts,labels):
 for x,y in zip(texts,labels):
  yield x,y

x = train_data[0].values[:]
y = train_data[1].values[:]

3. 构建词典

from gensim.models.word2vec import Word2Vec
import numpy as np

#训练Word2Vec浅层神经网络模型
w2v = Word2Vec(vector_size=100,   #特征向量的维度,默认为100
              min_count=3)        #对字典做截断,词频少于min_count次数的单词会被丢弃掉,默认值为5
w2v.build_vocab(x)
w2v.train(x,
         total_examples=w2v.corpus_count,
         epochs=20)

输出:

(2732920, 3663560)
#将文本转化为向量
def average_vec(text):
    vec = np.zeros(100).reshape((1,100))
    for word in text:
        try:
            vec += w2v.wv[word].reshape((1,100))
        except KeyError:
            continue
    return vec

#将词向量保存为Ndarray
x_vec = np.concatenate([average_vec(z) for z in x])

#保存Word2Vec模型及词向量
w2v.save(r'D:\Personal Data\Learning Data\DL Learning Data\w2v.pkl')
train_iter = coustom_data_iter(x_vec, y)
len(x),len(x_vec)

输出:

(12100, 12100)
label_name = list(set(train_data[1].values[:]))
print(label_name)
['Music-Play', 'Travel-Query', 'Weather-Query', 'Audio-Play', 'Radio-Listen', 'Video-Play', 'Calendar-Query', 'HomeAppliance-Control', 'Alarm-Update', 'Other', 'TVProgram-Play', 'FilmTele-Play']

4. 生成数据批次和迭代器


text_pipeline = lambda x : average_vec(x)
label_pipeline = lambda x : label_name.index(x)

print(text_pipeline('我想看和平精英上战神必备技巧的游戏视频'))
print(label_pipeline('Video-Play'))

输出:

[[ -3.16253691  -1.9659146    3.77608298   1.06067566  -5.1883576
   -8.70868033   3.89949582  -2.18139926   6.70676575  -4.99197783
   16.07808281   9.24493882 -15.24484421  -6.60270358  -6.24634131
   -3.64680131  -2.53697125   2.8301437    7.22867384  -2.13360262
    2.1341381    6.06681348  -4.65962007   1.23247945   4.33183173
    2.15399135  -1.83306327  -2.49018155  -0.22937663   1.57925591
   -3.22308699   3.56521453   5.94520254   3.46486389   3.46772102
   -4.10725167   0.31579057   9.28542571   7.48527321  -2.93014296
    8.39484799 -11.3110949    4.46019076  -0.64214947  -6.3485507
   -5.3710938    1.6277833   -1.44570495   7.21582842   3.29212736
    0.79481401  10.0952674   -0.72304608  -0.46801499   6.08651663
   -0.67166806  10.56184006   1.74745524  -4.52621601   1.8375443
   -5.368839    10.54501078  -2.85536074  -4.55352878 -13.42422374
    3.17138463   7.39386847  -2.24578104 -16.08510212  -5.7369401
   -2.90420356  -4.19321531   3.29097138  -9.36627482   3.67335742
   -0.80693699  -0.53749662  -3.67742246   0.48116201   5.51754848
    0.82724179   4.13207588   0.86254621  13.13354776  -3.11359251
    2.18450189   9.11669949  -4.88159943   2.01295654  11.02899793
   -5.33385142  -7.47531134  -4.02018939  -0.52363324  -1.79980185
    4.00845213  -2.436053     0.16959296  -7.10417359  -0.55219389]]
5
#生成数据批次和迭代器
from torch.utils.data import DataLoader

def collate_batch(batch):
    label_list, text_list = [],[]        
    for(_text, _label) in batch:
        #标签列表
        label_list.append(label_pipeline(_label))
        #文本列表
        processed_text = torch.tensor(text_pipeline(_text), dtype=torch.float32)
        text_list.append(processed_text)

    label_list = torch.tensor(label_list,dtype=torch.int64)
    text_list = torch.cat(text_list)
    return text_list.to(device), label_list.to(device)

#数据加载器
dataloader = DataLoader(
    train_iter,
    batch_size = 8,
    shuffle = False,
    collate_fn = collate_batch
)

二、构建模型

1. 搭建模型

#搭建模型
from torch import nn

class TextClassificationModel(nn.Module):
    def __init__(self, num_class):
        super(TextClassificationModel,self).__init__()
        self.fc = nn.Linear(100, num_class)

    def forward(self, text):
        return self.fc(text)

2. 初始化模型

#初始化模型
#定义实例
num_class = len(label_name)
vocab_size = 100000
em_size = 12
model = TextClassificationModel(num_class).to(device)

3. 定义训练与评估函数

#定义训练与评估函数
import time

def train(dataloader):
    model.train()          #切换为训练模式
    total_acc, train_loss, total_count = 0,0,0
    log_interval = 50
    start_time = time.time()
    for idx, (text,label) in enumerate(dataloader):
        predicted_label = model(text)
        optimizer.zero_grad()                             #grad属性归零
        loss = criterion(predicted_label, label)          #计算网络输出和真实值之间的差距,label为真
        loss.backward()                                   #反向传播
        torch.nn.utils.clip_grad_norm_(model.parameters(),0.1)  #梯度裁剪
        optimizer.step()                                  #每一步自动更新
        
        #记录acc与loss
        total_acc += (predicted_label.argmax(1) == label).sum().item()
        train_loss += loss.item()
        total_count += label.size(0)
        if idx % log_interval == 0 and idx > 0:
            elapsed = time.time() - start_time
            print('|epoch{:d}|{:4d}/{:4d} batches|train_acc{:4.3f} train_loss{:4.5f}'.format(
                epoch,
                idx,
                len(dataloader),
                total_acc/total_count,
                train_loss/total_count))
            total_acc,train_loss,total_count = 0,0,0
            staet_time = time.time()

def evaluate(dataloader):
    model.eval()      #切换为测试模式
    total_acc,train_loss,total_count = 0,0,0
    with torch.no_grad():
        for idx,(text,label) in enumerate(dataloader):
            predicted_label = model(text)
            loss = criterion(predicted_label,label)   #计算loss值
            #记录测试数据
            total_acc += (predicted_label.argmax(1) == label).sum().item()
            train_loss += loss.item()
            total_count += label.size(0)
    
    return total_acc/total_count, train_loss/total_count

三、训练模型

1. 拆分数据集并运行模型

#拆分数据集并运行模型
from torch.utils.data.dataset   import random_split
from torchtext.data.functional  import to_map_style_dataset

# 超参数设定
EPOCHS      = 10   #epoch
LR          = 5    #learningRate
BATCH_SIZE  = 64   #batch size for training

#设置损失函数、选择优化器、设置学习率调整函数
criterion   = torch.nn.CrossEntropyLoss()
optimizer   = torch.optim.SGD(model.parameters(), lr = LR)
scheduler   = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma = 0.1)
total_accu  = None

# 构建数据集
train_iter = coustom_data_iter(train_data[0].values[:],train_data[1].values[:])
train_dataset   = to_map_style_dataset(train_iter)
split_train_, split_valid_ = random_split(train_dataset,
                                         [int(len(train_dataset)*0.8),int(len(train_dataset)*0.2)])

                                           
train_dataloader    = DataLoader(split_train_, batch_size = BATCH_SIZE, shuffle = True, collate_fn = collate_batch)
valid_dataloader    = DataLoader(split_valid_, batch_size = BATCH_SIZE, shuffle = True, collate_fn = collate_batch)

for epoch in range(1, EPOCHS + 1):
    epoch_start_time = time.time()
    train(train_dataloader)
    val_acc, val_loss = evaluate(valid_dataloader)
    #获取当前的学习率
    lr = optimizer.state_dict()['param_groups'][0]['lr']
    if total_accu is not None and total_accu > val_acc:
        scheduler.step()
    else:
        total_accu = val_acc
    print('-' * 69)
    print('| epoch {:d} | time:{:4.2f}s | valid_acc {:4.3f} valid_loss {:4.3f}'.format(
        epoch,
        time.time() - epoch_start_time,
        val_acc,
        val_loss))
    print('-' * 69)

输出:

|epoch1|  50/ 152 batches|train_acc0.724 train_loss0.02592
|epoch1| 100/ 152 batches|train_acc0.820 train_loss0.01937
|epoch1| 150/ 152 batches|train_acc0.832 train_loss0.01843
---------------------------------------------------------------------
| epoch 1 | time:1.11s | valid_acc 0.827 valid_loss 0.019
---------------------------------------------------------------------
|epoch2|  50/ 152 batches|train_acc0.842 train_loss0.01750
|epoch2| 100/ 152 batches|train_acc0.831 train_loss0.01787
|epoch2| 150/ 152 batches|train_acc0.841 train_loss0.01953
---------------------------------------------------------------------
| epoch 2 | time:1.14s | valid_acc 0.780 valid_loss 0.029
---------------------------------------------------------------------
|epoch3|  50/ 152 batches|train_acc0.873 train_loss0.01189
|epoch3| 100/ 152 batches|train_acc0.884 train_loss0.00944
|epoch3| 150/ 152 batches|train_acc0.905 train_loss0.00763
---------------------------------------------------------------------
| epoch 3 | time:1.09s | valid_acc 0.886 valid_loss 0.009
---------------------------------------------------------------------
|epoch4|  50/ 152 batches|train_acc0.891 train_loss0.00794
|epoch4| 100/ 152 batches|train_acc0.894 train_loss0.00711
|epoch4| 150/ 152 batches|train_acc0.905 train_loss0.00646
---------------------------------------------------------------------
| epoch 4 | time:1.09s | valid_acc 0.874 valid_loss 0.009
---------------------------------------------------------------------
|epoch5|  50/ 152 batches|train_acc0.902 train_loss0.00593
|epoch5| 100/ 152 batches|train_acc0.909 train_loss0.00591
|epoch5| 150/ 152 batches|train_acc0.897 train_loss0.00687
---------------------------------------------------------------------
| epoch 5 | time:1.03s | valid_acc 0.890 valid_loss 0.008
---------------------------------------------------------------------
|epoch6|  50/ 152 batches|train_acc0.909 train_loss0.00592
|epoch6| 100/ 152 batches|train_acc0.900 train_loss0.00609
|epoch6| 150/ 152 batches|train_acc0.904 train_loss0.00607
---------------------------------------------------------------------
| epoch 6 | time:1.02s | valid_acc 0.890 valid_loss 0.008
---------------------------------------------------------------------
|epoch7|  50/ 152 batches|train_acc0.908 train_loss0.00559
|epoch7| 100/ 152 batches|train_acc0.906 train_loss0.00604
|epoch7| 150/ 152 batches|train_acc0.902 train_loss0.00623
---------------------------------------------------------------------
| epoch 7 | time:1.00s | valid_acc 0.888 valid_loss 0.008
---------------------------------------------------------------------
|epoch8|  50/ 152 batches|train_acc0.906 train_loss0.00558
|epoch8| 100/ 152 batches|train_acc0.904 train_loss0.00592
|epoch8| 150/ 152 batches|train_acc0.908 train_loss0.00602
---------------------------------------------------------------------
| epoch 8 | time:1.08s | valid_acc 0.888 valid_loss 0.008
---------------------------------------------------------------------
|epoch9|  50/ 152 batches|train_acc0.903 train_loss0.00566
|epoch9| 100/ 152 batches|train_acc0.911 train_loss0.00550
|epoch9| 150/ 152 batches|train_acc0.904 train_loss0.00630
---------------------------------------------------------------------
| epoch 9 | time:1.20s | valid_acc 0.889 valid_loss 0.008
---------------------------------------------------------------------
|epoch10|  50/ 152 batches|train_acc0.910 train_loss0.00564
|epoch10| 100/ 152 batches|train_acc0.912 train_loss0.00550
|epoch10| 150/ 152 batches|train_acc0.897 train_loss0.00633
---------------------------------------------------------------------
| epoch 10 | time:1.09s | valid_acc 0.889 valid_loss 0.008
---------------------------------------------------------------------
test_acc,test_loss = evaluate(valid_dataloader)
print('模型准确率为:{:5.4f}'.format(test_acc))

输出:

模型准确率为:0.8843

2. 测试指定数据

def predict(text,text_pipeline):
    with torch.no_grad():
        text = torch.tensor(text_pipeline(text),dtype = torch.float32)
        print(text.shape)
        output = model(text)
        return output.argmax(1).item()

ex_text_str = "还有双鸭山到淮阴的汽车票吗13号的"
print("该文本的类别是:%s" %label_name[predict(ex_text_str,text_pipeline)])
torch.Size([1, 100])
该文本的类别是:Travel-Query

四、总结

Word2Vec 通过学习单词的上下文关系,将单词映射到向量空间。这使得语义上相似的单词在向量空间中具有相近的位置。因此,使用 Word2Vec 可以更好地捕获文本中的语义信息,从而提高文本分类的准确性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1608889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode微博发布案例

样例: CSS代码: * {margin: 0;padding: 0; }ul{list-style: none; }.w {width: 900px;margin: 0 auto; }.controls textarea {width: 878px;height: 100px;resize: none;border-radius: 10px;outline: none;padding-left: 20px;padding-top: 10px;font-size: 18px; }.controls…

ADOP带您了解什么是光纤跳线

光纤跳线(也称为光纤连接器)是指光缆两端都装有连接器插头,用来实现光路活动连接。一端装有插头则称为光纤尾纤。光纤跳线用于从设备到光纤布线链路的跳接线,具有较厚的保护层。它在光纤通信系统、光纤接入网、光纤数据传输以及局…

【RAG 论文】面向知识库检索进行大模型增强的框架 —— KnowledGPT

论文:KnowledGPT: Enhancing Large Language Models with Retrieval and Storage Access on Knowledge Bases ⭐⭐⭐⭐ 复旦肖仰华团队工作 论文速读 KnowledGPT 提出了一个通过检索知识库来增强大模型生成的 RAG 框架。 在知识库中,存储着三类形式的知…

Nginx第3篇-使用ngx_http_proxy_connect_module配置https正向代理

场景 我使用python爬虫,然后需要个代理,所以就用Nginx搭了一个代理服务器。对Nginx也不太熟,慢慢摸索,搭建完之后发现只能代理http的请求,无法穿透https。几经折腾和摸索发现一个强大的HTTP代理模块:ngx_h…

ceph osd分组

一、前言 使用分组可以更好的管理osd,将不同类型的磁盘,分到不同的组中,例如hhd类型的osd分配到hhd组,ssd类型的osd分配到ssd组,将io要求不高的分配到hhd组做存储,io要求高的分配到ssd组做存储 二、配置 查…

李沐-16 PyTorch 神经网络基础【动手学深度学习v2】

注:1. 沐神对应章节视频出处 2.代码使用Jupyter Notebook运行更方便 3.文章笔记出处 一、层和块 层:层(1)接受一组输入, (2)生成相应的输出, (3)由一组可调整…

JVM知识点总结二

参考文章:【Java面试题汇总】JVM篇(2023版)_jvm面试题2023-CSDN博客 1、说说你了解的JVM内存模型: JVM由三部分组成:类加载子系统、运行时数据区、执行引擎 JVM内存模型: 内存模型里的运行时数据区&#…

短信登录session-redis

1.流程 1.1 发送验证码 模拟路径 http://127.0.0.1:8080/api/user/code?phone1335566 Request Method:POSTcontroller层 /*** 发送手机验证码*/PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {…

GitHub/R3D3项目环境配置踩坑记录

1、前言 项目链接地址:SysCV/r3d3 (github.com) 按照安装步骤容易出现的问题,environment.yaml文件中安装相关包,其中还有两个pip install githttps://github.com/..........这两个建议注释掉,后面再来安装这两个。 2、问题及解…

电脑本地搭建privateGPT流程

文章目录 前言效果所需文件流程1,python版本2,工程文件安装2.1服务端搭建2.2客户端搭建 3,模型下载 前言 当我的电脑主机在本地运行privateGPT的时候我听到了cpu风扇在呼啸, 至于privateGPT是干什么的, 其实就相当于一个文档分析软件,只不过内置了一个gpt,你把文件丟给他,你可…

鸿蒙OpenHarmony【搭建Ubuntu环境】

搭建Ubuntu环境 在嵌入式开发中,很多开发者习惯于使用Windows进行代码的编辑,比如使用Windows的Visual Studio Code进行OpenHarmony代码的开发。但当前阶段,大部分的开发板源码还不支持在Windows环境下进行编译,如Hi3861、Hi3516…

【论文源码实战】轻量化MobileSAM,分割一切大模型出现,模型缩小60倍,速度提高40倍

前言 MobileSAM模型是在2023年发布的,其对之前的SAM分割一切大模型进行了轻量化的优化处理,模型整体体积缩小了60倍,运行速度提高40倍,但分割效果却依旧很好。 MobileSAM在使用方法上沿用了SAM模型的接口,因此可以与…

matlab学习003-绘制由差分方程表示的离散系统图像

目录 1,题目 2,使用函数求解差分方程 1)基础知识 ①filter函数和impz函数 ②zeros函数 ☀ 2)绘制图像 ​☀ 3)对应代码 如果连简单的信号都不会的,建议先看如下文章👇,之…

UE4 相机围绕某点旋转

关卡(一个相机CameraActor,一个Cube(名叫Target)): 关卡蓝图里的逻辑(为了大家看得清楚,特意连得很紧凑,也比较乱,不然一张截图放不下): 只对Yaw 只Pitch: 同样对Roll: 围绕任…

Java maven项目打包自动测试并集成jacoco生成代码测试覆盖度报告

引入Junit 引入 junit5 单元测试依赖 <properties><junit.version>5.10.2</junit.version><jacoco.version>0.8.12</jacoco.version></properties><dependencies><!-- 单元测试 --><dependency><groupId>org.jun…

墨子web3时事周报

蚂蚁集团Web3研发进展与布局 国内Web3赛道的领军企业——蚂蚁集团&#xff0c;凭借其在前沿科技领域的深耕不辍&#xff0c;已在Web3技术研发疆域缔造了卓越战绩。特别是在引领行业革新的关键时刻&#xff0c;集团于今年四月末震撼推出了颠覆性的Web3全套解决方案&#xff0c…

easyui datagrid单元格点击进入编辑时,行会自动向上错位

现象描述&#xff0c;点击第20行可编辑的单元格进入编辑状态时&#xff0c;滚动条自动滚动到第19行了。导致第20行被分页遮挡&#xff0c;看不到无法编辑。 排查了一天百度AI说是滚动定位问题&#xff0c;最后发现是自己设置的列有问题&#xff0c;表格总共五列&#xff0c;全…

如何搭建线下陪玩系统(本地伴游、多玩圈子)APP小程序H5多端前后端源码交付,支持二开!

一、卡顿的优化方法 1、对陪玩系统源码中流媒体传输的上行进行优化&#xff0c;通过提升推流端的设备性能配置、推流边缘CDN节点就近选择等方式解决音视频数据源流的卡顿。 2、对陪玩系统源码中音视频数据的下载链路进行优化&#xff0c;通过选择更近更优质的CDN边缘节点来减少…

软航H5 PDF签章产品经nginx代理之后浏览器中PDF盖章时提示:签章失败:网络错误 的问题排查及解决办法

目录 问题现象 问题排查思路 问题处理办法 附&#xff1a;软航H5 PDF签章产品介绍 软航电子签章系统 软航版式文档签批系统 问题现象 问题描述&#xff1a;在系统中集成了软航H5 PDF签章产品&#xff0c;软航H5 PDF签章产品的对应服务是通过nginx代理的&#xff0c;在奇安…

FPGA_verilog语法整理

FPGA_verilog语法整理 verilog的逻辑值 verilog的常数表达 位宽中指定常数的宽度&#xff08;表示成二进制数的位数&#xff09;&#xff0c;单引号加表示该常数为几进制的底数符号。 二进制底数符号为b&#xff0c;八进制为 o&#xff0c;十进制为d&#xff0c;十六进制为 h…