NLP-使用Word2vec实现文本分类

news2024/11/28 9:27:19

Word2Vec模型通过学习大量文本数据,将每个单词表示为一个连续的向量,这些向量可以捕捉单词之间的语义和句法关系。本文做文本分类是结合Word2Vec文本内容text,预测其文本标签label。以下使用mock商品数据的代码实现过程过下:

1、准备数据

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")
print(device)

tmp = spark.sql("""
select sku_name,scene
 from dmb_rpt.dmb_jdt_dmbrpt_items_attribute_a_det_m  where dt='2024-07-15'
group by sku_name,scene
""")
tmp.show(2, False)

corpus_file = 'large_corpus_sku_name_and_category.txt'
tmp.toPandas().to_csv(corpus_file, sep=',', index=False, mode='w',header=False )

2、加载数据

import pandas as pd

# 加载自定义中文数据
train_data = pd.read_csv(corpus_file, sep=',', header=None)
print("train data:",train_data[:5])

# 构造数据集迭代器
def coustom_data_iter(texts, labels):
    for x, y in zip(texts, labels):
        yield x, y
        
x = train_data[0].values[:]
#多类标签的one-hot展开
y = train_data[1].values[:]
print("x[:5]:\n",x[:5])
print("y[:5]:\n",y[:5])

3、训练 Word2Vec 模型

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)

# Word2Vec可以直接训练模型,一步到位。这里分了三步
# 第一步构建一个空模型
# 第二步使用 build_vocab 方法根据输入的文本数据 x 构建词典。build_vocab 方法会统计输入文本中每个词汇出现的次数,并按照词频从高到低的顺序将词汇加入词典中。
# 第三步使用 train 方法对模型进行训练,total_examples 参数指定了训练时使用的文本数量,这里使用的是 w2v.corpus_count 属性,表示输入文本的数量

# 保存 Word2Vec 模型及词向量
w2v.save('w2v_model.pkl')

4、搭建文本分类模型

4.1 查看文本分类
# 查看分类
label_name = list(set(train_data[1].values[:]))
print(label_name)

4.2 定义文本向量处理函数
# 将文本转化为向量
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


# 这段代码定义了一个函数 average_vec(text),它接受一个包含多个词的列表 text 作为输入,并返回这些词对应词向量的平均值。该函数

# 首先初始化一个形状为 (1, 100) 的全零 numpy 数组来表示平均向量
# 然后遍历 text 中的每个词,并尝试从 Word2Vec 模型 w2v 中使用 wv 属性获取其对应的词向量。如果在模型中找到了该词,函数将其向量加到 vec 中。如果未找到该词,函数会继续迭代下一个词
# 最后,函数返回平均向量 vec

# 然后使用列表推导式将 average_vec() 函数应用于列表 x 中的每个元素。得到的平均向量列表使用 np.concatenate() 连接成一个 numpy 数组 x_vec,
# 该数组表示 x 中所有元素的平均向量。x_vec 的形状为 (n, 100),其中 n 是 x 中元素的数量。

# 定义文本向量为词向量的avg
text_pipeline  = lambda x: average_vec(x)
# 根据分类index查找分类名称
label_pipeline = lambda x: label_name.index(x)

print(text_pipeline("茅台贵州"))
print(label_pipeline("聚会"))

4.3 搭建文本分类模型
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)
 
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)

# 训练和评估
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 {:1d} | {: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
            start_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

4.4 加载数据,模型训练
# !pip install torchtext
import math
from torch.utils.data.dataset  import random_split
from torchtext.data.functional import to_map_style_dataset

# 初始化
num_class  = len(label_name)
vocab_size = 100000
em_size    = 12
model      = TextClassificationModel(num_class).to(device)

# 超参数
EPOCHS     = 10 # epoch
LR         = 5  # 学习率
BATCH_SIZE = 64*6 # 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, [math.floor(len(train_dataset)  *0.8),  math.ceil(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 {:1d} | time: {:4.2f}s | '
          'valid_acc {:4.3f} valid_loss {:4.3f} | lr {:4.6f}'.format(epoch,
                                           time.time() - epoch_start_time,
                                           val_acc,val_loss,lr))
 
    print('-' * 69)

4.5 模型评价
test_acc, test_loss = evaluate(valid_dataloader)
print('模型准确率为:{:5.4f}'.format(test_acc))
模型准确率为:0.6767
4.6 模型文本分类预测
def predict(text, text_pipeline):
    with torch.no_grad():
        text = torch.tensor(text_pipeline(text), dtype=torch.float32)
        print(text.shape)
        print("==>:", text)
        output = model(text)
        return output.argmax(1).item()

model = model.to("cpu")

for ex_text_str in ["【浓香】五粮液甲辰龙年纪念酒(5瓶装)", "【浓香】五粮液财富人生蓝钻", 
                    "【酱香】茅台集团 茅乡名家名作酒", "【浓香】五粮液囍祥瑞添福文化酒"]:
    print("该商品适合的场景是:%s" %label_name[predict(ex_text_str, text_pipeline)])

Done

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

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

相关文章

关闭Xshell后,任务将结束-tmux

Xshell标签中的会话结束后,会话中运行的进程也将被结束。 关闭标签 解释: xshell在断开连接后会中止所有正在运行的进程和任务,因为xshell客户端是通过ssh协议连接到远程服务器的,一旦连接断开,所有与该会话相关的进程…

数据结构 - 红黑树

文章目录 前言一、红黑树介绍1、红黑树的概念2、红黑树的性质 二、实现红黑树1、基本框架2、插入3、删除4、查找5、测试红黑树6、红黑树代码 三、红黑树性能四、AVL树和红黑树的差别 前言 红黑树是一种二叉搜索树,所以学习前需要学会基本的二叉搜索树,并…

超越源自内省:《自卑与超越》

作者主页: 🔗进朱者赤的博客 精选专栏:🔗经典算法 作者简介:阿里非典型程序员一枚 ,记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法(公众号同名) ❤️觉得文章还…

JS 改造数组对象,将其不确定的key作为value,并合并相同key的value值

const data [{"苹果": 3839,"小米": 1423,"华为": 4965,"oppo": 3334,"vivo": 2820,"一加": 4751},{"苹果": 3560,"小米": 2099,"华为": 3192,"oppo": 4210,"vivo…

anaconda 安装

环境 win 11 安装 下载安装包 https://www.anaconda.com/download 2.打开安装包,这里基本上就是下一步下一步 3.配置环境变量 对应自己安装的目录文件夹 D:\anaconda3 D:\anaconda3\Scripts D:\anaconda3\Library\bin4.打开命令行测试 常用命令 初始化 co…

python毕业设计选题求职招聘系统-可视化大屏

✌网站介绍:✌10年项目辅导经验、专注于计算机技术领域学生项目实战辅导。 ✌服务范围:Java(SpringBoo/SSM)、Python、PHP、Nodejs、爬虫、数据可视化、小程序、安卓app、大数据等设计与开发。 ✌服务内容:免费功能设计、免费提供开题答辩P…

【限免】16PAM、16PSK、16QAM、16CQAM星座图及误码率【附MATLAB代码】

​微信公众号:智能电磁频谱算法 QQ交流群:949444104 主要内容 MATLAB代码 % Parameters M 16; N 4; % Number of circles for CQAM SNR_dB 0:2:25; % Extended SNR range to reach higher values num_symbols 1e5; % Total number of symbols for s…

静态路由学习笔记

1. 静态路由应用场景 (1)静态路由由网络管理员手动配置,配置方便,对系统要求低,适用于拓扑结构简单并且稳定的小型网络。 (2)缺点是不能自动适应网络拓扑的变化,需要人工干预过多。…

保险丝(常见元器件及电路基础知识)

分类:简单分为熔断式和非熔断式 电压:保险丝的额定电压是指它的公称额定电压, 通常就是保险丝断开后能够承受的最大电压值保险丝通电时两端所承受的电压大大小于其额定电压,因此额定电压基本上无关紧要。 电流: PFC为功率因数矫…

Java之开发 系统设计 分布式 高性能 高可用

1、restful api 基于rest构建的api 规范: post delete put get 增删改查路径 接口命名 过滤信息状态码 2、软件开发流程 3、命名规范 类名:大驼峰方法名:小驼峰成员变量、局部变量:小驼峰测试方法名:蛇形命名 下划…

语言模型及数据集

一、定义 1、语言模型的目标是估计序列的联合概率,一个理想的语言模型就能够基于模型本身生成自然文本。 2、对一个文档(词元)序列进行建模, 假设在单词级别对文本数据进行词元化。 3、计数建模 (1)其中…

AI绘画;喂饭进阶!教你如何用Stable Diffusion生成高清建筑手工模型图,一篇文章搞懂什么是Lora模型和CKPT主模型!

前言 刚接触Stable Diffusion不久的你,是否有这样的疑问: Q1: Stable Diffusion中的主模型CKPT是什么? Q2: Stable Diffusion中的Lora模型又是什么? Q3: 在哪儿可以下载好用的AI绘图模型? Q4: Stable Diffusion 如…

【SpringBoot】2 项目搭建

创建项目 1)确实本地 jdk 版本 打开命令行窗口:快捷键 Windows R,输入 CMD,敲回车 执行命令:java -version 2)在项目 clone 的位置创建 Spring Boot 项目,使用 Maven 进行依赖管理&#xff…

最新爆火的开源AI项目 | LivePortrait 本地安装教程

LivePortrait 本地部署教程,强大且开源的可控人像AI视频生成 1,准备工作,本地下载代码并准备环境,运行命令前需安装git 以下操作不要安装在C盘和容量较小的硬盘,可以找个大点的硬盘装哟 2,需要安装FFmp…

大疆创新2025校招内推

大疆2025校招-内推 一、我们是谁? 大疆研发软件团队,致力于把大疆的硬件设备和大疆用户紧密连接在一起,我们的使命是“让机器有温度,让数据会说话”。 在消费和手持团队,我们的温度来自于激发用户灵感并助力用户创作…

聊聊基于Alink库的主成分分析(PCA)

概述 主成分分析(Principal Component Analysis,PCA)是一种常用的数据降维和特征提取技术,用于将高维数据转换为低维的特征空间。其目标是通过线性变换将原始特征转化为一组新的互相无关的变量,这些新变量称为主成分&…

react中useMemo钩子函数的使用

1.使用useMemo前展示 import { useState,useMemo } from "react"function kanno(num){console.log(999,num);return num }function UseMemo(){const [count1,setCount1] useState(0)const [count2,setCount2] useState(0)const result kanno(count1)console.log(…

ELK安装(Elasticsearch+Logstash+Kibana+Filebeat)

一、简介 1.1、软件简介 ELK其实是Elasticsearch,Logstash 和 Kibana三个产品的首字母缩写,这三款都是开源产品。 1.1.1、Elasticsearch简介 Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析…

magento2 安装win环境和linux环境

win10 安装 安装前提,php,mysql,apach 或nginx 提前安装好 并且要php配置文件里,php.ini 把错误打开 display_errorsOn开始安装 检查环境 填写数据库信息 和ssl信息,如果ssl信息没有,则可以忽略 填写域名和后台地址&#xff0…

花几千上万学习Java,真没必要!(二十九)

1、基本数据类型包装类: 测试代码1: package apitest.com; //使用Integer类的不同方法处理整数。 //将字符串转换为整数(parseInt)和Integer对象(valueOf), //将整数转换回字符串(…