【3】深度学习之Pytorch——如何使用张量处理表格数据集(葡萄酒数据集)

news2024/11/28 12:42:27

在这里插入图片描述
张量是PyTorch中数据的基础。神经网络将张量输入并产生张量作为输出,实际上,神经网络内部和优化期间的所有操作都是张量之间的操作,而神经网络中的所有参数(例如权重和偏差)也都是张量。

怎样获取一条数据、一段视频或一段文本,并且用张量表示它们,然后用适合于训练深度学习模型的方式进行处理。这是我们需要解决的问题和学习的方向。

表格数据

机器学习工作中遇到的最简单的数据形式是位于电子表格、CSV(以逗号分隔值)文件或数据库中的。无论使用哪种介质,此数据都是一个表格,每个样本(或记录)包含一行,其中的列包含这个样本的一条信息。

首先,我们假设样本在表格中的显示顺序是没有意义的。这与时间序列不同,这里的表是独立样本的集合,而在时间序列中,样本是在时间维度上相关的。

列可以包含数值型数据(例如特定位置的温度)或标签(例如表示样品属性的字符串,比如“蓝色”)。因此,表格数据通常不是同质的(homogeneous),不同的列有不同的类型。你可能有一列显示苹果的重量,另一列则用标签编码其颜色。

然而,PyTorch张量是同质的。其他数据科学软件包,例如Pandas,具有dataframe的概念,dataframe即用异构(heterogenous)的列来表示数据的对象。相比之下,PyTorch中的信息被编码为数字,通常为浮点数(尽管也支持整数类型)。(PyTorch中的)数值编码是有意为之的,因为神经网络是将实数作为输入并通过连续应用矩阵乘法和非线性函数产生实数作为输出的数学实体。

看了上面的介绍,那么我们的第一步就是将异构的现实世界数据编码成浮点数张量以供神经网络使用。

举一个简单的例子,假设我们现在手里面有一份数据集是关于葡萄酒的数据

fixed acidity
volatile acidity
citric acid
residual sugar
chlorides
free sulfur dioxide
total sulfur dioxide
density
pH
sulphates
alcohol
quality

该文件包含用逗号分隔的值的集合,总共12列,第一行是包含列名称的标题行。前11列包含化学变量的值。最后一列包含从0(最差)到10(优秀)的感官质量得分。以下是列名在数据集中显示的顺序:针对此数据集可能的机器学习任务是通过化学表征来预测质量得分。

在这里插入图片描述
此图中,你将看到质量随着硫含量减少而提高。

Python提供了多个选项来快速加载CSV文件。三种常用的选择是

Python自带的csv模块
NumPy
Pandas

第三个选项是最省时和最省内存的方法,但是我们将避免仅仅是加载文件就将的额外的库引入学习曲线。因为我们已经介绍了NumPy,并且PyTorch具有出色的NumPy互操作性,所以将继续使用NumPy来加载文件并将生成的NumPy数组转换为PyTorch张量,如下面的代码所示。

import csv
import numpy as np
wine_path = "./winequality-white.csv"
wineq_numpy = np.loadtxt(wine_path, dtype=np.float32, delimiter=";",
     skiprows=1)
wineq_numpy

指定了二维数组的类型(32位浮点数)和用于分隔每一行各值的分隔符,并指出不应读取第一行,因为它包含列名。接下来,检查是否已读取所有数据

然后进一步将NumPy数组转成PyTorch张量:

import torch
wineq = torch.from_numpy(wineq_numpy)
wineq.shape, wineq.type()

输出

(torch.Size([4898, 12]), 'torch.FloatTensor')
data = wineq[:, :-1] # 除最后一列外所有列
data, data.shape

输出

(tensor([[ 7.0000,  0.2700,  0.3600,  ...,  3.0000,  0.4500,  8.8000],
         [ 6.3000,  0.3000,  0.3400,  ...,  3.3000,  0.4900,  9.5000],
         [ 8.1000,  0.2800,  0.4000,  ...,  3.2600,  0.4400, 10.1000],
         ...,
         [ 6.5000,  0.2400,  0.1900,  ...,  2.9900,  0.4600,  9.4000],
         [ 5.5000,  0.2900,  0.3000,  ...,  3.3400,  0.3800, 12.8000],
         [ 6.0000,  0.2100,  0.3800,  ...,  3.2600,  0.3200, 11.8000]]),
 torch.Size([4898, 11]))

如果你想将target张量转换成标签张量,那么你有两个选择,具体取决于策略或使用分类数据的方式。第一种选择是将标签视为整数向量:

target = wineq[:, -1].long()
target
tensor([6, 6, 6,  ..., 6, 7, 6])

如果目标是字符串标签(例如颜色),则可以采用相同的方法为每个字符串分配一个整数。

另一种选择是构建独热(one-hot)编码,即将10个分数编码成10个向量,每个向量除了一个元素为1外其他所有元素都设置为0。此时,分数1可以映射到向量(1,0,0,0,0,0,0,0,0,0),分数5映射到(0,0,0,0,1,0,0,0,0,0),等等。分数值与非零元素的索引相对应的事实纯属偶然;你可以打乱上述分配,从分类的角度来看,什么都不会改变。

上述两种方法有明显的区别。将葡萄酒质量分数编码成分数的整数向量中会引入了分数的可排序性,在这个例子下可能是适当的,因为分数1低于分数4。这还会在分数之间产生一定的距离(例如1和3之间的距离与2和4之间的距离相同。)如果这符合你的定量关系,那就太好了。

否则,如果分数纯粹是定性的(例如颜色),则独热编码更适合,因为它不涉及隐含的顺序或距离关系。当整数之间的分数值(例如2.4)对应用没有意义时(即要么是这个值要么是那个值),独热编码才适用。

可以使用scatter_方法来实现独热编码,该方法将源张量中的值沿作为参数提供的索引进行填充。

target_onehot = torch.zeros(target.shape[0], 10)
target_onehot.scatter_(1, target.unsqueeze(1), 1.0)
tensor([[0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        ...,
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 1., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.]])

说实话非常的方便,这里提供了一个比较好的方法,快速便捷的帮助我们进行了编码(适用于分类任务)

现在看一下scatter_的作用。

首先请注意,其名称下划线结尾。PyTorch中,此约定表示该方法不会返回新的张量,而是就地修改源张量。 scatter_的参数是

  • 指定后面两个参数所处理的维度
  • 列张量,指示要填充的索引
  • 包含填充元素的张量或者单个标量(上例中即1.0)

换句话说,前面的调用可以这样理解:“对于每一行,获取目标标签的索引(在本例中即葡萄酒质量分数),并将其用作列索引以设置值为1.0。结果就是得到了一个编码分类信息的张量。

scatter_的第二个参数,即索引张量,必须具有与待填充张量相同的维数。由于target_onehot是二维(4898x10)的,因此你需要使用unsqueeze为target添加一个额外的维:

target_unsqueezed = target.unsqueeze(1)
target_unsqueezed
tensor([[6],
        [6],
        [6],
        ...,
        [6],
        [7],
        [6]])

调用unsqueeze增加了一个单例的维度,从包含4898个元素的一维张量到尺寸为(4898x1)的二维张量,其内容并未改变。没有添加新元素;你决定使用额外的索引来访问元素。也就是说,你用target[0]访问target的第一个元素,并用target_unsqueezed[0,0]访问其未压缩(unsqueezed)对象的第一个元素。

PyTorch允许你在训练神经网络时直接将类别索引用作目标。但是,如果要用作网络的分类输入,则必须将其转换为独热编码张量。

首先,获取每列的均值和标准差:

data_mean = torch.mean(data, dim=0)
data_mean
data_var = torch.var(data, dim=0)
data_var

dim = 0表示沿维数0进行计算。此时,你可以通过减去平均值并除以标准偏差来对数据进行归一化,这有助于学习过程。

“dim = 0” 表示在计算中沿维数为0的方向进行运算。例如,如果您有一个矩阵,则沿维数0计算可以是对矩阵中每一行求和,并将结果作为一个向量返回。

data_normalized = (data - data_mean) / torch.sqrt(data_var)
data_normalized

使用torch.le函数确定target中哪些行对应的分数小于或等于3:

bad_indexes = torch.le(target, 3)
bad_indexes.shape, bad_indexes.dtype, bad_indexes.sum()
torch.le是小于等于的意思,例如:

x = torch.tensor([1, 2, 3, 4])
y = torch.tensor([2, 2, 2, 2])
print(torch.le(x, y))

输出:
tensor([1, 1, 0, 0])

torch.gt是大于的意思,例如:

x = torch.tensor([1, 2, 3, 4])
y = torch.tensor([2, 2, 2, 2])
print(torch.gt(x, y))

输出:
tensor([0, 0, 1, 1])

torch.lt是小于的意思,例如:

x = torch.tensor([1, 2, 3, 4])
y = torch.tensor([2, 2, 2, 2])
print(torch.lt(x, y))

输出:
tensor([1, 0, 0, 0])

torch.ge是大于等于的意思,例如:

x = torch.tensor([1, 2, 3, 4])
y = torch.tensor([2, 2, 2, 2])
print(torch.ge(x, y))

输出:
tensor([0, 1, 1, 1])

输出

(torch.Size([4898]), torch.bool, tensor(20))

bad_indexes中只有20个元素为1!通过利用PyTorch中称为高级索引(advanced indexing)的功能,可以使用0/1张量来索引数据张量。此张量本质上将数据筛选为仅与索引张量中的1对应的元素(或行)。bad_indexes张量具有与target相同的形状,其值是0或1,具体取决于阈值与原始target张量中每个元素之间比较结果:

bad_data = data[bad_indexes]
bad_data.shape

请注意,新的bad_data张量只有20行,这与bad_indexes张量1的个数相同。另外,bad_data保留所有11列。

现在,你可以开始获取被分为好、中、坏三类的葡萄酒的信息。对每列取.mean:

bad_data = data[torch.le(target, 3)]
# 对于numpy数组和PyTorch张量,&运算符执行逻辑和运算
mid_data = data[torch.gt(target, 3) & torch.lt(target, 7)]
good_data = data[torch.ge(target, 7)]

bad_mean = torch.mean(bad_data, dim=0)
mid_mean = torch.mean(mid_data, dim=0)
good_mean = torch.mean(good_data, dim=0)

for i, args in enumerate(zip(col_list, bad_mean, mid_mean, good_mean)):
    print('{:2} {:20} {:6.2f} {:6.2f} {:6.2f}'.format(i, *args))
 0 fixed acidity          7.60   6.89   6.73
 1 volatile acidity       0.33   0.28   0.27
 2 citric acid            0.34   0.34   0.33
 3 residual sugar         6.39   6.71   5.26
 4 chlorides              0.05   0.05   0.04
 5 free sulfur dioxide   53.33  35.42  34.55
 6 total sulfur dioxide 170.60 141.83 125.25
 7 density                0.99   0.99   0.99
 8 pH                     3.19   3.18   3.22
 9 sulphates              0.47   0.49   0.50
10 alcohol               10.34  10.26  11.42

劣质葡萄酒似乎具有更高的二氧化硫总含量(total sulfur dioxide),另外还有其他差异。你可以使用二氧化硫总含量的阈值作为区分好酒和差酒的粗略标准。现在获取二氧化硫总含量列中低于你刚刚计算的中值的索引,如下所示:

total_sulfur_threshold = 141.83
total_sulfur_data = data[:,6]
predicted_indexes = torch.lt(total_sulfur_data, total_sulfur_threshold)
predicted_indexes.shape, predicted_indexes.dtype, predicted_indexes.sum()
(torch.Size([4898]), torch.bool, tensor(2727))

上面的阈值预测略高于一半的葡萄酒是高品质的。

接下来,你需要获取(实际)优质葡萄酒的索引

actual_indexes = torch.gt(target, 5)
actual_indexes.shape, actual_indexes.dtype, actual_indexes.sum()
(torch.Size([4898]), torch.bool, tensor(3258))

由于实际的优质葡萄酒比阈值预测的多约500例,这证明该阈值并不完美。

现在,你需要查看预测与实际的吻合程度。在预测索引和实际索引之间执行逻辑与运算(请记住,每个索引都是0/1数组)得到交集,用这个交集来确定预测表现如何:

n_matches = torch.sum(actual_indexes & predicted_indexes).item()
n_predicted = torch.sum(predicted_indexes).item()
n_actual = torch.sum(actual_indexes).item()
n_matches, n_matches / n_predicted, n_matches / n_actual

这里就不具体进行接下来的预测了,主要是通过实际的案例数据知道如何将数据集转换为张量并通过具体的一些运算操作来实现这些模型所需的特点。

每文一语

当你无法改变现实的时候,那就先从自己开始改变吧!

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

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

相关文章

Java面试知识点

工作也有好些年了,从刚毕业到前几年看过无数的面试题,总想着自己写一个面试总结,随着自我认识的变化,一些知识点的理解也越来越不一样了。写下来温故而知新。很多问题可能别人也总结过,但是答案不尽相同,如…

纯css实现loading加载中(多种展现形式)

前言 现如今网页越来越趋近于动画,相信大家平时浏览网页或多或少都能看到一些动画效果,今天我们来做一个有意思的动画效果,纯 css 实现 loading 加载中(多种展现形式),下面一起看看吧。 1. 常规 loading 实…

Linux系统之cuda 11情况下如何配置pytorch 10.2

由于目前pytorch1.8.2只能支持到10.2的版本,但ubuntu最新的系统驱动直接支持了cuda 11.4, 并且cuda tooklit支持的默认下载也是11.0。1、确认NVIDIA驱动安装lspci|grep NVIDIA1. 需要先降低cuda tooklit的版本(卸载新版本)cuda-uninstaller in /usr/loca…

统一附件存储MINIO部署使用

一、基于docker环境部署 1、创建docker-compose配置文件 1)创建 docker-compose-minio.yml文件,内容如下: version: 3.7# Settings and configurations that are common for all containers x-minio-common: &minio-commonimage: quay…

结构体+枚举+联合体

目录 一、结构体的声明 (一)结构的基础知识 (二)结构的声明 (三)特殊的声明 (四)结构的自引用 1. 一个结构体内部包含一个类型为该结构本身的成员(不合法&…

Day19 C++STL入门基础知识十一——map、multimap容器 构造赋值、大小交换、插入删除、查找统计、排序【全面深度剖析+例题代码展示】

💃🏼 本人简介:男 👶🏼 年龄:18 ✍每日一句:【道固远,笃行可至;事虽巨,坚为必成】 文章目录1. 基本概念2. 构造赋值① 函数原型② 代码展示③ 测试结果3. 大小…

基于tensorflow的垃圾分类系统

项目描述 该项目基于PySide2和PyQt5设计界面UI,搭配QT Designer进行界面设计。 基于TensorFlow中的Keras模型,进行垃圾分类模型的训练。 项目包含功能有:使用者注册登录功能、管理员训练模型、用户使用模型进行分类。 功能介绍 一、注册登…

JVM调优

JVM调优-VisualVmVisualVm/ Jconsule远程连接第一种方式第二种方式:java 11开启远程GC连接如果还连不上考虑防火墙拦截了端口firewall-cmd --list-all,查看一下并暴露对应端口连接配置VisualVm界面简介采集GC信息的一些命令垃圾回收器切换VisualVm/ Jconsule远程连接…

unity 框选目标

先制作选框: 创建一个Image,给Sourece Image随便添加一张方形图片,如果添加圆的出来就是圆,这个看情况而定,然后勾掉Fill Center这样就镂空了 这种框选一般都是作为组件存在所以代码要做成单例类,默认情况…

【Mysql第十期 数据类型】

文章目录1. MySQL中的数据类型2.类型介绍2.2 可选属性2.2.2 UNSIGNED2.2.3 ZEROFILL2.3 适用场景2.4 如何选择?3. 浮点类型3.2 数据精度说明3.3 精度误差说明4. 定点数类型4.1 类型介绍4.2 开发中经验5. 位类型:BIT6. 日期与时间类型6.1 YEAR类型6.2 DAT…

程序的编译与链接(C语言为例) #代码写好后到运行期间要经过怎样的过程呢?# 粗略版 #

编译与链接前言程序的环境程序的编译与链接写在最后前言 每当我们运行一段代码时,编译器都会自动的帮我们编译代码并将代码转换为一个二进制可执行文件(.exe), 有了这个可执行文件,便可以执行我们写的程序了。那么编译…

Linux-Ubuntu18.04安装anaconda及python解释器环境的配置

1.anaconda的下载anaconda官网搜索链接,点击下载注意:anaconda的下载位置2.anaconda的安装利用如下命令进行安装:$ bash /home/xiaowang/下载/Anaconda3-2022.10-Linux-x86_64.sh一直点击回车enter,阅读文件内容文件阅读完毕&…

canal五部曲-如何保证消息的顺序

分析CanalRocketMQProducer.send canal发送消息到RocketMQ使用到了partitionNum、partitionHash 通过partitionHash可以把消息发送到RocketMQ的不同分区上,因为同一个分区在消费时有序的 public void send(final MQDestination destination, String topicName, com.…

2020年因果推断综述《A Survey on Causal Inference》

最近阅读了TKDD2020年的《A Survey on Causal Inference》,传送门,自己对文章按照顺序做了整理,同时对优秀的内容进行融合,如有不当之处,请多多指教。 文章对因果推理方法进行了全面的回顾,根据传统因果框…

威胁情报是什么

文章目录前言一、威胁情报是什么?数据与情报IOC二、威胁情报的分类1.战略情报2.技术情报3.战术情报4.运营情报三、总结四、参考前言 只要有斗争冲突,就有那些研究、分析和努力去了解对手的人。一场战争的输赢,取决于你对对手的了解&#xff0…

springboot启动过程源码

概述版本<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.3.RELEASE</version><relativePath/></parent>启动入口代码package com.ybjdw.tool;i…

如何解决混合精度训练大模型的局限性问题

混合精度已经成为训练大型深度学习模型的必要条件&#xff0c;但也带来了许多挑战。将模型参数和梯度转换为较低精度数据类型&#xff08;如FP16&#xff09;可以加快训练速度&#xff0c;但也会带来数值稳定性的问题。使用进行FP16 训练梯度更容易溢出或不足&#xff0c;导致优…

【王道数据结构】第六章(下) | 图的应用

目录 一、最小生成树 二、最短路径 三、有向⽆环图描述表达式 四、拓扑排序 五、关键路径 一、最小生成树 1、最小生成树的概念 对于一个带权连通无向图G &#xff08;V,E)&#xff0c;生成树不&#xff0c;每棵树的权(即树中所有边上的权值之和)也可能不同。设R为G的所…

【2023】Prometheus-接入Alertmanager并实现邮件告警通知

目录1.使用二进制方式安装Alertmanager2.Alertmanager配置3.alert接入prometheus4.创建告警配置文件&#xff08;在prometheus服务器&#xff09;5.测试告警1.使用二进制方式安装Alertmanager 下载安装包 wget https://github.com/prometheus/alertmanager/releases/download…

Python pip工具使用

一、pip工具 1、pip简介 pip 是一个通用的 Python包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能&#xff0c;便于我们对 Python的资源包进行管理。 在安装 Python时&#xff0c;会自动下载并且安装 pip。 &#xff08;1&#xff09;查看是否安装 pip 查看…