基于词向量使用Pytorch常规自编码器对句子进行向量表示与降维

Posted Icy Hunter

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于词向量使用Pytorch常规自编码器对句子进行向量表示与降维相关的知识,希望对你有一定的参考价值。

其实句子建模进行向量化表示,应该使用递归自编码器比较合理,即基于句法树或者误差最小的原则词两两之间进行重构,重构后的再继续与剩下的进行重构,道理大概都懂,但是理论和实际还是有差距的,因为我目前还没有找到实例,找了些论文里面说的也是模模糊糊,因此我还无法使用递归自编码器实现句子建模,但是我发现许多实例是对手写数字图片进行自编码器的降维,因此我斗胆有了以下思路:
1.使用jieba切词然后使用word2vec训练词向量,每个词词向量维度v为128
2.计算每个句子词数多少,然后根据数量分布取每句的词数d为11(多退少补0)
3.将每个句子的词向量按顺序拼接成11 * 128的二维矩阵
4.将一个矩阵作为输入放入自编码器进行训练,最后降维成16维用于表示此句子

其实我这里只是纯属我个人随便玩玩而已,因此首先词向量矩阵的构建就会使得一些句子的词损失,从而影响语义,况且,直接按照词从上到下排列成一个句子,真的能够表达出一个句子这一想法以及是否要去除停用词等等,还是有待商榷的。但是还是那句话,效果不怎么样,咱跑个流程,随便玩玩总不犯法。

首先词向量获取不多讲了参考我的另一篇,只需要稍微改改就能用了https://blog.csdn.net/qq_52785473/article/details/122640697?spm=1001.2014.3001.5502
训练出一个word2vec.model的词向量模型并且保存

下面给出news_title_cut.csv文件数据内容(里面split以下全都丢进word2vec训练就能出词向量了):

新闻标题
30 万股 沸腾 家中 获准 免费 仿制 新冠 口服药 两只 股票 预定 涨停板 这家 上市公司 受益 利好 多大
对公 私募 联手 坐庄 容忍
对症 生育率 三孩 配套 发力 生育 养育 教育
房贷 供降 LPR 降息 释放 何种 信号
新冠 口服药 概念 加持 22 天大 3.4 这家 公司 董事 高管 抛出 减持 计划
2022 资本 市场 容忍 执法 亮点 重点 发力
千亿 时代 来临 快递 物流业 价值
70 余家 医药公司 预告 业绩 利润 增长
预制 资本 市场 新宠 三千 市场 赢家
半导体 业绩 预喜 隐忧 股价 集体 疯涨 行情 再现
防御 属性 外资 机构 频频 扫货
专精 特新 属性 89 潜力 符合 北交所 上市 标准
市场 热点 共振 北交所 频现 个股 大涨
央行 连续 释放 同一个 信号
年期 LPR 21 首次 下调 利于 降低 综合 融资 成本 提振 市场 信心
利差 收窄 100 基点 以内 专家 无碍 人民币 汇率 平稳 走势
开年 黑马 银行 板块 大幅 走强 因素 助力 估值 修复
2.49 万亿元 五大 险企 年度 保费 成绩单 出炉 外资 扫货
银河证券 白电 龙头 盈利 能力 有望 改善
股价 业绩 火之歌 2022 CXO 还会
2022 行业 前瞻 千亿 时代 强势 洗牌 战争 升级
中信证券 建议 关注 银行 板块 配置 价值
退市 警报 拉响 股价 跌去 97% 名高管 辞职 长租 公寓 第一股 面临 破产 清算
百万 市场 消息 银行 交易所 债券市场 互联互通 货币政策 传导 宏观调控 润滑
国盛 证券 建部 2022 工作 会议 信号 地产 有望 实质性 松动
业绩 大增 煤炭 板块 走高 长协价 中枢 上移 能源 转型 催生 主线
招商 证券 数字 人民币 专题 解读
午后 名博 看市 创新 补仓
旅游 逆势 走高 十四五 旅游业 发展 规划 提振 旅游业
换电 模式 利好 部门 发文 绿色 消费 支持 新能源 光伏 产业
取消 购买 政府 带头 采购 突迎 部门 利好 新能源 行情 重演
今起 房贷利率 下降 基点 业内 地区 下调 空间
十大 博客 后市 节前 节后 概率
再创 近十年 新高 库存 低位 警惕 行情 回转
再创 近十年 新高 库存 低位 警惕 行情 回转
Model3 交付 周期 最长 四个 补贴 退坡 保费 上涨 难掩 特斯拉 订单 猛增
总揽 2.5 万亿元 A股 五大 上市 险企 2021 保费 出炉
油价 上涨 点燃 通胀 引信 韩印 亚洲 如临大敌
激光雷达 领跑者 迎大 客户 奔驰 下单 入股 产业链 生态 制胜 关键
上海 2025 生物医药 产业 规划 万亿 新增 25 上市 企业 险资 私募 纷纷 布局
247 巴菲特 下注 风光 股神 入场
医药 之殇 近三年 净值 大涨 180% 葛兰 基民
机构 大调 疯狂 抢筹低 估值 蓝筹股 信号
魅族 卖身 吉利 5G 时代 手机 厂商 何去何从
东北 药茅 三连 跌停 市值 蒸发 千亿 长春 高新 翻盘
资产 吸引力 2021 年险 企新设 增资 入股 近年 低位 外资 唯一 亮点
宽松 春风 频吹 难改 A股 市场 弱势 格局
心跳 牛股 惨遭 地板 知名 游资 散户 大本营 接盘
默沙东 新冠药 特仿 企业 股价 先涨 一笔
30.98% 十大 重仓股 全是 宇宙
煤炭 板块 逆市 大涨 股收 涨停 煤价 持续 预期 北向 资金 大幅 加仓股 揭秘
股价 井喷 家中 获准 免费 仿制 新冠 口服药 利好 多大
部委 发文 推动 电动车 基建 发展 快充 换电 元年 开启
股价 跌去 97% 长租 公寓 第一股 走向 破产 清算
国内 家药企 获准 仿制 默沙东 新冠 口服药 公司 股价 先涨
血制品 集采 广东 揭幕 原料 稀缺 产品 玩转 灵魂 砍价
越跌 聪明 两天 狂买 200 逆势 抄底 新能源 见底 信号
环保 装备 产业 冲刺 1.3 万亿元 上市公司 提前 布局
预制 规模 万亿元 监管 灵魂 拷问 10 天飙 97% 背后 行业 预测 数据
牧原 屠宰 爆发 分析 跃居 国内 屠宰
比亚迪 涨价 阵营 分析 人士 近期 终端 或现 越涨
医药 默沙东 新冠 口服药 授权 国内 仿制 中选 药企 大涨 板块
预制 热点 控股权 一元 甩卖 大湖 股份 原形
21 上市公司 晚间 公告 速递
晚间 公告 热点 追踪 业绩 猝不及防 远海 预亏 50
双减 重击 新东方 预计 亿美元 A股 K12 公司 由盈 转亏 教培 行业 下半场 何去何从
减重 新东方 预计 亿美元 A股 K12 公司 由盈 转亏
妖股 解构 王九安 医疗 跌停 捉妖 上演 连续 打板
上海 2025 生物医药 产业 规划 万亿 险资 私募 纷纷 布局

代码如下:

# coding: utf-8
from gensim.models.word2vec import Word2Vec
import pandas as pd
import numpy as np
import torch
import torch.nn as nn
import torch.utils.data.dataloader as dataloader
from torch.utils.data import TensorDataset


def analyze():
    f = pd.read_csv("news_title_cut.csv")
    news = f["新闻标题"]
    all_num = []
    for n in news:
        num = n.split(" ")
        all_num.append(len(num))
    all_num = pd.DataFrame(all_num)
    print(all_num.describe())  # 分析每个句子的词长情况,这里选取占75%的词长为11


def get_train_data():
    model = Word2Vec.load("word2vec.model")
    f = pd.read_csv("news_title_cut.csv")
    news = f["新闻标题"]
    vectors = np.zeros((len(news), 11, 128))
    j = 0
    for new in news:
        sen = new.split(" ")
        N = 11
        new_vector = np.zeros((11, 128))
        if N <= len(sen):
            sen = sen[: N]
            i = 0
            for word in sen:
                vector = model.wv[word]
                new_vector[i, :] = vector
                i += 1
        else:
            i = 0
            for word in sen:
                vector = model.wv[word]
                new_vector[i, :] = vector
                i += 1

        vectors[j, :, :] = new_vector
        j += 1

    return vectors


# 超参数
EPOCH = 10
LR = 0.001

train_data = torch.from_numpy(get_train_data()).to(torch.float32)
train_label = torch.from_numpy(np.zeros(len(get_train_data()))).to(torch.float32)  # 标签这里用不到,但是不影响吧
dataset = TensorDataset(train_data, train_label)
train_loader = dataloader.DataLoader(dataset=dataset, shuffle=True, batch_size=10)  # 一次10组进行训练


class AutoEncoder(nn.Module):
    def __init__(self):
        super(AutoEncoder, self).__init__()

        # 压缩
        self.encoder = nn.Sequential(
            nn.Linear(11 * 128, 64 * 11),
            nn.Tanh(),
            nn.Linear(64 * 11, 32 * 11),
            nn.Tanh(),
            nn.Linear(32 * 11, 16 * 11),
            nn.Tanh(),
            nn.Linear(16 * 11, 16),
        )
        # 解压
        self.decoder = nn.Sequential(
            nn.Linear(16, 16 * 11),
            nn.Tanh(),
            nn.Linear(16 * 11, 32 * 11),
            nn.Tanh(),
            nn.Linear(32 * 11, 64 * 11),
            nn.Tanh(),
            nn.Linear(64 * 11, 128 * 11),
        )

    def forward(self, x):
        encoded = self.encoder(x)
        decoded = self.decoder(encoded)
        return encoded, decoded


autoencoder = AutoEncoder()
optimizer = torch.optim.Adam(autoencoder.parameters(), lr=LR)
loss_func = nn.MSELoss()

for epoch in range(EPOCH):
    for step, (x, b_label) in enumerate(train_loader):
        b_x = x.view(-1, 11 * 128)   # 无监督学习,解码后和原数据比求的误差
        b_y = x.view(-1, 11 * 128)   

        encoded, decoded = autoencoder(b_x)

        loss = loss_func(decoded, b_y)      # 损失函数
        if step % 100 == 0:
            print(loss)

        optimizer.zero_grad()               # 清空梯度
        loss.backward()                     # 反向传播
        optimizer.step()                    # 优化器

encoder = torch.tensor([])
for step, (x, b_label) in enumerate(train_loader):
    b_x = x.view(-1, 11 * 128)
    encoded, decoded = autoencoder(b_x)
    encoder = torch.cat((encoder, encoded), 0)

encoder = pd.DataFrame((encoder.detach().numpy()))
print(encoder)
encoder.to_csv("encoded.csv", encoding="utf-8", index=0)

encoded.csv里保存的就是编码后的句子表示。
纯属个人想法,有任何不对的地方,请大家批评指正!

以上是关于基于词向量使用Pytorch常规自编码器对句子进行向量表示与降维的主要内容,如果未能解决你的问题,请参考以下文章

基于CNN的句子分类

什么是词向量?word2vecGloveFastText分别是什么?

pytorch中nn.Embedding原理及使用

Pytorch LSTM 词性判断

干货|10分钟快速入门PyTorch 词向量

nlp学习杂记