第23周:使用Word2vec实现文本分类

news2024/9/21 18:31:20

目录

前言

一、数据预处理

1.1 加载数据

1.2 构建词典

1.3 生成数据批次和迭代器

二、模型构建

2.1 搭建模型

2.2 初始化模型

2.3 定义训练和评估函数

三、训练模型

3.1 拆分数据集并运行模型

3.2 测试指定数据

总结


前言

  • 🍨 本文为[🔗365天深度学习训练营]中的学习记录博客
  • 🍖 原作者:[K同学啊]

说在前面

本周任务:1)基础任务---结合Word2vec文本内容(第1列)预测文本标签(第2列);优化网络结果,将准确率提升至89%;绘制出验证集的ACC与Loss图;2)进阶任务---尝试第2周的内容独立实现,尽可能不看本文的代码

我的环境:Python3.8、Pycharm2020、torch1.12.1+cu113

数据来源:[K同学啊]


一、数据预处理

1.1 加载数据

数据示例:

       zip是Python中的一个内置函数,它可以将多个序列(元组、列表等)中对应的元素打包成一个个元组,然后返回这些元组组成的一个迭代器。例如,在代码中zip(texts,labels)就是将texts和labels两个列表中对应位置的元素一一打包成一个元组,返回一个迭代器,每次迭代返回一个元组(x,y),其中x是texts中的一个元素,y是labels中对应的一个元素。这样,每次从迭代器中获取一个元素,就相当于从texts和labels中获取了一组对应的数据。在这里,zip函数主要用于将输入的texts和labels打包成一个可迭代的数据集,然后传给后续的模型训练过程中使用。

代码如下:

import torch
import os,PIL,pathlib,warnings
from torch import nn
import time
import pandas as pd
from torchvision import transforms, datasets
import jieba

warnings.filterwarnings("ignore")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)

#1.2 加载自定义中文数据
train_data = pd.read_csv('./train.csv', sep='\t', header=None)
print(train_data.head())

#1.3 构造数据集迭代器
def custom_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[:]

打印输出:

1.2 构建词典

代码如下:

#1.4 构建词典
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 属性,表示输入文本的数量如果一步到位的话代码为:w2v = Word2Vec(x, vector_size=100, min_count=3, epochs=20)

#将文本转化为向量
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])
w2v.save('w2v_model.pkl')

train_iter = custom_data_iter(x_vec, y)
print(len(x), len(x_vec))

label_name = list(set(train_data[1].values[:]))
print(label_name)

打印输出如下:

12100 12100
['FilmTele-Play', 'Weather-Query', 'Radio-Listen', 'Travel-Query', 'Alarm-Update', 'Calendar-Query', 'Music-Play', 'Other', 'Video-Play', 'TVProgram-Play', 'HomeAppliance-Control', 'Audio-Play']

这段代码定义了一个函数 average_vec(text),它接受一个包含多个词的列表text 作为输入,并返回这些词对应词向量的平均值。该函数
首先初始化一个形状为(1,100)的全零 numpy 数组来表示平均向量然后遍历 text 中的每个词,并尝试从 Word2Vec 模型 w2v 中使用 wv 属性获取其对应的词向量。如果在模型中找到了该词,函数将其向量加到 vec中。如果未找到该词,函数会继续选代下一个词
最后,函数返回平均向量 vec然后使用列表推导式将 average_vec()函数应用于列表x中的每个元素。得到的平均向量列表使用 np.concatenate()连接成一个numpy数组xvec,该数组表示x中所有元素的平均向量。xvec的形状为(n,100),其中n是x中元素的数

1.3 生成数据批次和迭代器

代码如下:

#生成数据批次和迭代器
text_pipeline = lambda x: average_vec(x)
label_pipeline = lambda x: label_name.index(x)

print(text_pipeline("你在干嘛"))
print(label_pipeline("Travel-Query"))

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)

打印输出如下:

[[ 0.71341366  1.81265011  1.44437733  0.81895351 -2.10842876 -0.53163828
   1.69011965  0.61772476  0.45250437 -1.19413337 -0.93801782 -4.51869714
   2.08006459 -0.19431476  0.54761063  0.53993282  2.45709884 -1.7272636
   3.3405721  -2.00952683  2.7074931   0.44549108 -0.3798939   0.50284129
  -2.03344245 -1.0066061  -1.57383255 -1.02822024  1.22481698 -0.74399903
   2.72032912  0.68474213 -1.08696781 -0.43206174  0.17515172  0.04883668
   0.68131649  3.37725095 -1.73957334  0.44227505  0.35449219  0.9353995
  -0.53143035  0.5939152   0.15114589 -0.67918842  1.19383969 -0.40012862
  -2.7421315   2.3960007   0.93965465 -2.33946571 -1.03136044  0.44977702
  -0.20926718 -0.48943431  1.56342356 -1.81069714  0.2234989   1.05807498
   1.99193773 -0.18156157  2.24787551 -0.63780972 -0.12800559 -0.43717601
  -2.1173833   1.23210199  2.40076267  0.39000577 -0.50040299  0.29607797
   1.25565214 -0.45914613  0.40915862 -0.72103182 -4.15503209  0.32175705
   1.13466016 -1.11661778 -0.90987498  0.02924608 -2.1390073   2.00657488
  -2.04405907 -2.21540118  2.36201783 -2.28765213 -1.62947962 -0.23354006
  -0.26953844 -2.08598122  0.30332083  1.65787105  0.44275794 -2.15785465
  -0.49007402  0.6538553  -2.73823986  0.34911314]]
3

二、模型构建

2.1 搭建模型

代码如下:

#2.1 搭建模型
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.2 初始化模型

代码如下:

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

2.3 定义训练和评估函数

代码如下:

#2.3 定义训练和评估函数
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
            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

torch.nn.utils.clip_grad norm_(model.parameters(), 0.1)是一个PyTorch函数,用于在训练神经网络时限制梯度的大小。这种操作被称为梯度裁剪(gradientclipping),可以防止梯度爆炸问题,从而提高神经网络的稳定性和性能。
在这个函数中:

  • model.parameters()表示模型的所有参数。对于一个神经网络,参数通常包括权重和偏置项。
  • 0.1 是一个指定的阈值,表示梯度的最大范数(L2范数)。如果计算出的梯度范数超过这个阈值,梯度会被缩放,使其范数等于阈值,

梯度裁剪的主要目的是防止梯度爆炸。梯度爆炸通常发生在训练深度神经网络时,尤其是在处理长序列数据的循环神经网络(RNN)中。当梯度爆炸时,参数更新可能会变得非常大,导致模型无法收敛或出现数值不稳定。通过限制梯度的大小,梯度裁剪有助于解决这些问题,使模型训练变得更加稳定。

三、训练模型

3.1 拆分数据集并运行模型

代码如下:

#三、训练模型
#3.1 拆分数据集并运行模型
from torch.utils.data.dataset import random_split
from torchtext.data.functional import to_map_style_dataset
# 超参数设定
EPOCHS = 10  # epoch
LR = 4  # 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, gamma=0.1)
total_accu = None

# 构建数据集
train_iter = custom_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)

#3.2 正式训练
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} | lr {:4.6f}'.format(epoch, time.time() - epoch_start_time,
                                                                                       val_acc, val_loss,lr))
    print('-' * 69)

test_acc, test_loss = evaluate(valid_dataloader)
print('模型准确率为:{:5.4f}'.format(test_acc))

打印输出如下:

|epoch1|  50/ 152 batches|train_acc0.748 train_loss0.02063
|epoch1| 100/ 152 batches|train_acc0.834 train_loss0.01444
|epoch1| 150/ 152 batches|train_acc0.831 train_loss0.01594
---------------------------------------------------------------------
| epoch 1 | time:9.10s | valid_acc 0.794 valid_loss 0.016 | lr 4.000000
---------------------------------------------------------------------
|epoch2|  50/ 152 batches|train_acc0.844 train_loss0.01494
|epoch2| 100/ 152 batches|train_acc0.846 train_loss0.01505
|epoch2| 150/ 152 batches|train_acc0.849 train_loss0.01442
---------------------------------------------------------------------
| epoch 2 | time:1.71s | valid_acc 0.834 valid_loss 0.017 | lr 4.000000
---------------------------------------------------------------------
|epoch3|  50/ 152 batches|train_acc0.856 train_loss0.01387
|epoch3| 100/ 152 batches|train_acc0.848 train_loss0.01376
|epoch3| 150/ 152 batches|train_acc0.863 train_loss0.01322
---------------------------------------------------------------------
| epoch 3 | time:1.93s | valid_acc 0.843 valid_loss 0.017 | lr 4.000000
---------------------------------------------------------------------
|epoch4|  50/ 152 batches|train_acc0.865 train_loss0.01316
|epoch4| 100/ 152 batches|train_acc0.856 train_loss0.01294
|epoch4| 150/ 152 batches|train_acc0.847 train_loss0.01460
---------------------------------------------------------------------
| epoch 4 | time:1.48s | valid_acc 0.830 valid_loss 0.017 | lr 4.000000
---------------------------------------------------------------------
|epoch5|  50/ 152 batches|train_acc0.882 train_loss0.00931
|epoch5| 100/ 152 batches|train_acc0.900 train_loss0.00714
|epoch5| 150/ 152 batches|train_acc0.902 train_loss0.00734
---------------------------------------------------------------------
| epoch 5 | time:1.46s | valid_acc 0.881 valid_loss 0.009 | lr 0.400000
---------------------------------------------------------------------
|epoch6|  50/ 152 batches|train_acc0.902 train_loss0.00681
|epoch6| 100/ 152 batches|train_acc0.903 train_loss0.00632
|epoch6| 150/ 152 batches|train_acc0.906 train_loss0.00641
---------------------------------------------------------------------
| epoch 6 | time:1.65s | valid_acc 0.876 valid_loss 0.009 | lr 0.400000
---------------------------------------------------------------------
|epoch7|  50/ 152 batches|train_acc0.907 train_loss0.00579
|epoch7| 100/ 152 batches|train_acc0.904 train_loss0.00610
|epoch7| 150/ 152 batches|train_acc0.908 train_loss0.00561
---------------------------------------------------------------------
| epoch 7 | time:1.50s | valid_acc 0.885 valid_loss 0.008 | lr 0.040000
---------------------------------------------------------------------
|epoch8|  50/ 152 batches|train_acc0.912 train_loss0.00535
|epoch8| 100/ 152 batches|train_acc0.915 train_loss0.00571
|epoch8| 150/ 152 batches|train_acc0.901 train_loss0.00604
---------------------------------------------------------------------
| epoch 8 | time:1.52s | valid_acc 0.884 valid_loss 0.008 | lr 0.040000
---------------------------------------------------------------------
|epoch9|  50/ 152 batches|train_acc0.909 train_loss0.00564
|epoch9| 100/ 152 batches|train_acc0.907 train_loss0.00553
|epoch9| 150/ 152 batches|train_acc0.912 train_loss0.00565
---------------------------------------------------------------------
| epoch 9 | time:1.49s | valid_acc 0.884 valid_loss 0.008 | lr 0.004000
---------------------------------------------------------------------
|epoch10|  50/ 152 batches|train_acc0.912 train_loss0.00535
|epoch10| 100/ 152 batches|train_acc0.911 train_loss0.00558
|epoch10| 150/ 152 batches|train_acc0.905 train_loss0.00580
---------------------------------------------------------------------
| epoch 10 | time:1.47s | valid_acc 0.884 valid_loss 0.008 | lr 0.000400
---------------------------------------------------------------------
模型准确率为:0.8839

3.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号的"
model = model.to("cpu")

print("该文本的类别是: %s" % label_name[predict(ex_text_str, text_pipeline)])

打印输出如下:

torch.Size([1, 100])
该文本的类别是: Travel-Query


总结

结合Word2vec文本内容(第1列)预测文本标签(第2列),准确率能达到88%以上,后续将继续优化网络结构和进行结果的可视化。

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

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

相关文章

贪吃蛇游戏:增加暂停按钮,每次增加10分蛇会变化

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>贪吃蛇游戏</title> </head> <st…

奇安信椒图--服务器安全管理系统(云锁)

奇安信椒图–服务器安全管理系统&#xff08;云锁&#xff09; 椒图 奇安信服务器安全管理系统是一款符合Gartner定义的CWPP&#xff08;云工作负载保护平台&#xff09;标准、EDR&#xff08;终端检测与响应&#xff09;、EPP终端保护平台&#xff08;终端保护平台&#xff…

山东济南最厉害的改名大师颜廷利:中国当代最伟大的哲学家之一

山东济南最厉害的改名大师颜廷利&#xff1a;中国当代最伟大的哲学家之一 颜廷利教授的哲学思想主要集中在《升命学说》中&#xff0c;强调奉献与无私奉献的重要性&#xff0c;认为金钱利益交易是现代社会的一个问题&#xff0c;并提出了一个理想的文明社会模型&#xff0c;其…

C++---由优先级队列认识仿函数

文章目录 一、优先级队列是什么&#xff1f; 二、如何使用优先级队列 1、优先级队列容器用法 2、为什么容器本身无序&#xff1f; 三、什么是仿函数&#xff1f; 1. 什么是仿函数&#xff1f; 2. 仿函数的优势 四、仿函数如何使用&#xff1f; 1、重载operator()函数 2、运用第…

分支管理

目录 创建分支 切换分支 合并分支 删除分支 合并冲突 创建分支 git branch [分支]指令 创建新的分⽀后&#xff0c;Git 新建了⼀个指针叫dev&#xff0c; * 表⽰当前 HEAD 指向的分⽀是 master 分⽀。另外&#xff0c;可以通过⽬录结构发现&#xff0c;新的 dev 分⽀…

s3c2440---ADC模数转换器

目录 一、模数转换器简述 1.1.简述 1.2.转换过程 ​编辑 1.3. ADC类别 二、普通ADC转换的实现 2.1.设置ADC控制寄存器 2.2. 读取ADC转换数据寄存器 三、总结 一、模数转换器简述 1.1.简述 S3c2440有一个10-bit的CMOS ADC 模数转换器&#xff0c;支持8个模拟通道输…

像素间的关系(邻接、连通、区域、边界、距离定义)

文章目录 像素的相邻像素4邻域D邻域8邻域 邻接、连通、区域和边界邻接类型连通区域边界 距离测度欧氏距离城市街区距离&#xff08;city-block distance&#xff09;棋盘距离&#xff08;chessboard distance&#xff09; 参考 像素的相邻像素 4邻域 坐标 ( x , y ) (x,y) (x…

kali 2024 安装SageMath

kali2024安装sagemath避坑指南 安装遇到的问题Install from conda-forge使用mamba安装sage 安装遇到的问题 刚开始使用sudo apt -y install sagemath和源码安装遇到各种包冲突&#xff0c;有的还涉及到系统底层包&#xff0c;没有避开。然后尝试使用mamba安装成功&#xff0c;…

93. UE5 GAS RPG 应用负面效果表现

在上一篇文章里&#xff0c;我们实现了添加负面效果GE&#xff0c;并且在添加GE时&#xff0c;也会给角色应用一个负面效果标签作为标识。在这一篇里&#xff0c;我们将通过负面效果标签标识&#xff0c;应用角色身上展现对应的负面效果的表现。 我们将在这篇文章里添加一个自定…

第一个React程序

虽然跟着网上的视频&#xff0c;但是都是几年前的教学视频了&#xff0c;于是就在视频的引导下&#xff0c;自己使用vite脚手架建立一个React项目。 首先来到vite官网&#xff1a; 和当时建立vue项目一样&#xff0c;使用该命令创建&#xff0c;只是后面选择框架时选择react&a…

《机器学习》 基于SVD的矩阵分解 推导、案例实现

目录 一、SVD奇异值分解 1、什么是SVD 2、SVD的应用 1&#xff09;数据降维 2&#xff09;推荐算法 3&#xff09;自然语言处理 3、核心 1&#xff09;什么是酉矩阵 2&#xff09;什么是对角矩阵 4、分解过程 二、推导 1、如何求解这三个矩阵 1&#xff09;已知&#xf…

10款好用的电脑监控软件推荐丨2024年干货整理,赶紧码住!

选择合适的电脑监控软件可以帮助企业和个人更好地管理和保护其计算机资源。以下是10款较为好用的电脑监控软件推荐。 1. 安企神 7天试用体验https://work.weixin.qq.com/ca/cawcde06a33907e60a 简介&#xff1a;安企神是一款专为企业设计的信息安全管理软件&#xff0c;提供…

算法_队列+宽度优先搜索

文章目录 前言N叉树的层序遍历题目要求题目解析代码如下 二叉树最大宽度题目要求题目解析代码如下 在每个树中找最大值题目要求题目解析代码如下 二叉树的锯齿形层序遍历题目要求题目解析代码如下 前言 本文将会向你介绍有关队列宽度优先搜索的题目&#xff1a;N叉树的层序遍历…

目标检测-RT-DETR

RT-DETR (Real-Time Detection Transformer) 是一种结合了 Transformer 和实时目标检测的创新模型架构。它旨在解决现有目标检测模型在速度和精度之间的权衡问题&#xff0c;通过引入高效的 Transformer 模块和优化的检测头&#xff0c;提升了模型的实时性和准确性。RT-DETR 可…

Linux-实用指令

目录 前言 指定运行级别 基本介绍 切换运行级别 指令类 帮助指令 man 获得帮助信息 help指令 文件目录类 pwd指令 ls指令 cd指令 mkdir命令 rmdir指令删除空目录 touch指令 cp指令 rm指令 mv指令 cat指令 more指令 less指令 echo指令 head指令 tail指令…

2024.9.6 作业

手写unique_ptr指针指针 代码&#xff1a; #include <iostream> #include <stdexcept>template <typename T> class unique_ptr { public:// 构造函数explicit unique_ptr(T* ptr nullptr) : m_ptr(ptr) {}// 析构函数~unique_ptr() {delete m_ptr;}// 禁…

设置GB/T35114服务

GB/T35114服务是下联模式&#xff0c;支持GB/T35114标准A级双向认证&#xff0c;支持国密系列硬件设备。 操作步骤 在配置-》设备-》级联配置-》GB服务配置 进行编辑。 1、点击 编辑 2、修改国标服务器地址 3、如果其他参数也需要修改&#xff0c;都可自定义&#xff0c;除了国…

FME教程:通过更新读模块,解决FME读取shapefile数据,提示意外输入,“在转换中,某些读取的要素与工作空间的要素类不匹配……”的问题

目录 一、问题情况 二、解决方法 一、问题情况 在使用制作好的FME模板读取shapefile数据时&#xff0c;有时候会遇到弹窗提示意外输入&#xff0c;模板无法运行&#xff0c;在日志信息中警示“在转换中&#xff0c;某些读取的要素与工作空间的要素类不匹配。可能由于读模块的…

2024年全国大学生数学建模竞赛(E题) 建模解析|交通流量管控|小鹿学长带队指引全代码文章与思路

我是鹿鹿学长&#xff0c;就读于上海交通大学&#xff0c;截至目前已经帮200人完成了建模与思路的构建的处理了&#xff5e; 本篇文章是鹿鹿学长经过深度思考&#xff0c;独辟蹊径&#xff0c;实现综合建模。独创复杂系统视角&#xff0c;帮助你解决国赛的难关呀。 完整内容可以…

【前端学习】AntV G6-06 使用图算法

课程链接 图算法 Algorithm | G6 (antgroup.com) 【例子 pageRank】 ​​​​​​力导向图布局 | G6 (antgroup.com) 重点部分添加注释 import G6 from antv/g6;const { pageRank } G6.Algorithm; // 在此引入 pageRankconst container document.getElementById(containe…