2.2. 数据预处理
到目前为止,我们已经介绍了一些数据操作的技术,它们都被存为张量格式。为了应用深度学习解决现实世界的问题,我们需要处理原始数据,而不是被很好的存于张量之中的数据。在 Python
中流行的数据分析工具中,pandas
包是最常用的。像 Python
庞大的生态系统中的许多其他扩展包一样,pandas
可以处理张量数据。因此,我们将简要地介绍使用 pandas
预处理原始数据并将其转换为张量格式的步骤。我们将在后面的章节中介绍更多的数据预处理技术。
2.2.1. 读取数据集
作为一个例子,我们首先人工创建数据,存储于 CSV
文件(以逗号分割),名字为【house_tiny.csv
】,其它格式存储的处理方式类似。下面,我们将数据逐行写入 CSV
文件,代码如下:
import os
os.makedirs(os.path.join('..', 'data'), exist_ok=True)
data_file = os.path.join('..', 'data', 'house_tiny.csv')
with open(data_file, 'w') as f:
f.write('NumRooms,Alley,Price\n') # Column names
f.write('NA,Pave,127500\n') # Each row represents a data example
f.write('2,NA,106000\n')
f.write('4,NA,178100\n')
f.write('NA,NA,140000\n')
# 输出如下
运行代码,会在上一级目录生成data文件夹,保存house_tiny.csv文件
要从创建的csv
文件加载原始数据集,我们导入pandas
包并调用read_csv
函数。该数据集有四行三列,每行描述房间数量(“NumRooms”)、小巷类型(“alley”)和房子的价格(“price”)。具体代码如下:
import pandas as pd
data = pd.read_csv(data_file)
print(data)
# 输出如下
NumRooms Alley Price
0 NaN Pave 127500
1 2.0 NaN 106000
2 4.0 NaN 178100
3 NaN NaN 140000
2.2.2. 处理缺失数据
注意,数据中的【NaN
】表示缺失值。传统的方法包括填补(使用其它值代替)和删除(忽略该值)操作。这里我们考虑填补数据。
通过整数位置索引(iloc
),我们将数据划分为输入(前两列数据)和输出(最后一列数据)。对于数值缺失的情况,我们用当前列的平均值代替。处理代码如下:
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())
print(inputs)
# 输出如下
NumRooms Alley
0 3.0 Pave
1 2.0 NaN
2 4.0 NaN
3 3.0 NaN
对于输入中的分类或离散值,我们认为【NaN
】是一个类别。由于“Alley”列只接受两种类型的分类值“Pave”和“NaN”,pandas
可以自动将这一列转换为两个列“Alley_Pave”和“Alley_nan”。类型为“Pave”的行将“Alley_Pave”和“Alley_nan”的值设置为1和0。丢失“Alley”类型的行将其值设置为0和1。代码如下:
inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)
# 输出如下
NumRooms Alley_Pave Alley_nan
0 3.0 1 0
1 2.0 0 1
2 4.0 0 1
3 3.0 0 1
2.2.3. 转为张量格式
上述例子中,经过处理,现在所有的输入和输出项都是数值类型,它们可以转换为张量格式。一旦数据以这种形式出现,就可以用我们在【2.1节】中介绍的张量相关函数进一步操作它们。具体代码如下:
import torch
X, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
print(X)
print(y)
# 输出如下
tensor([[3., 1., 0.],
[2., 0., 1.],
[4., 0., 1.],
[3., 0., 1.]], dtype=torch.float64)
tensor([127500, 106000, 178100, 140000])