从项目入手机器学习——(三)数据预处理(下)自动编码器

本文会开始介绍目前机器学习中常用的自动化编码工具。

大家可能有疑问,既然有自动化编码,为什么之前还要将手动编码呢?原因在于目前的自动化编码封装的非常好,以至于是完全的黑盒,不理解基础原理的人用起来就不知道它在做什么,因此还是希望大家能掌握了解自动编码在做什么。

值得一提的是,自动编码几乎和训练是无法分开的,没有训练的编码和随机分布没什么区别(也就是编码没什么意义)但考虑到本专题的连续性,文本会尽可能淡化训练这一部分。

加州住房数据集

加载数据集

python 复制代码
from sklearn.datasets import fetch_california_housing
from pandas import DataFrame

house = fetch_california_housing()
pd = DataFrame(data=house.data, columns=house.feature_names)
pd["MedHouseVal"] = house.target
print(pd.head())

输出如下

当然,对于自动编码来说,我们不太需要关注标签名称,只需要知道数据维度即可,因此也可以不通过pd直接打印

python 复制代码
X = house.data[:5]  # 仅取5条样本,维度:(5, 8)
print("原始数字数据(5条样本,8维特征):")
print(f"数据维度:{X.shape}")
print(f"前2条原始数据:\n{X[:2]}\n")

数据归一化

自动编码器对编码器对数值尺度非常敏感,因此归一化是必要的,归一化的原理并不复杂,简单理解就是按相对大小把数据变到区间[ 0 , 1 ]之间,例如列表[0, 1, 2, 3, 4]归一化之后就是[0, 0.25, 0.5, 0.75, 1],当然,Min-Max 归一化实际上可以把数据变到任意区间上,对自动编码器来说,只要不同的标签都在同一区间即可

python 复制代码
# 归一化
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(0, 1))
X_scaled = scaler.fit_transform(X)
print("归一化后的数字数据(0-1区间):")
print(f"数据维度:{X_scaled.shape}")
print(f"前2条归一化数据:\n{X_scaled[:2]}\n")

这一步还可以做标准化,但不是必须步骤,所以不再赘述

转为张量

编码器仅支持张量作为输入,因此需要把列表转为张量(初学者把张量理解成多维向量即可,其实我也不觉得它们有什么区别)

python 复制代码
# 转为张量
import torch
X_tensor = torch.tensor(X_scaled, dtype=torch.float32)
print("转为张量后的输入:")
print(f"张量维度:{X_tensor.shape}")
print(f"前2条张量数据:\n{X_tensor[:2]}\n")

定义编码器

python 复制代码
# 定义编码器
# 可修改参数input_dim和latent_dim来调整输入和输出维度
import torch.nn as nn
class NumericEncoder(nn.Module):
    def __init__(self, input_dim=8, latent_dim=3):
        super(NumericEncoder, self).__init__()
        # 编码器结构:8维 → 5维(隐藏层) → 3维(核心特征)
        self.encoder = nn.Sequential(
            nn.Linear(input_dim, 5),  # 第一层:8→5
            nn.ReLU(),                # 激活函数
            nn.Linear(5, latent_dim), # 第二层:5→3
            nn.ReLU()                 # 激活函数
        )
    
    def forward(self, x):
        return self.encoder(x)  # 仅返回编码结果
    
# 初始化编码器
encoder = NumericEncoder(input_dim=8, latent_dim=3)
print("【步骤2】编码器结构:")
print(encoder)
print()

这里我们可修改参数input_dim和latent_dim来调整输入和输出维度,当然input_dim是我们之前查看数据集得到的8个标签,因此最好不要修改。

至于编码器中间的结构,涉及到神经网络如何搭建,不是本文的重点(其实就像搭积木一样一层一层拼好,每一层根据想要的效果接上对应的层就行,不过想要设计一个好的网络还是很需要相关知识的)

编码器输出

正如前面所说,自动编码几乎和训练是无法分开的,没有训练的编码和随机分布没什么区别,本文仅演示编码器的输入输出过程,因此跳过训练这一步。

python 复制代码
# 设为评估模式(无梯度计算,仅前向传播)
print(f"编码前输入维度:{X_tensor.shape} (8维)")
print(f"编码前向量:{X_tensor[:2]}\n")
encoder.eval()
with torch.no_grad():
    encoded_features = encoder(X_tensor)  # 执行编码

print("编码后的核心特征:")
print(f"编码后输出维度:{encoded_features.shape} (3维)")
print(f"前2条编码结果:\n{encoded_features[:2]}\n")

可以很明显的看到,经过编码器,两条八维的tensor成功被编码为两条三维的tensor。但是仍然要强调

  • 未训练时,nn.Linear(8,5)nn.Linear(5,3)的权重、偏置都是随机值;
  • 此时输入 8 维的归一化数据,经过编码器得到的 3 维输出,只是随机的数值组合 ,和直接从均匀分布 / 正态分布中采样的结果没有本质区别,完全不包含原始数据的任何核心特征

自动编码器的训练过程,是通过重构损失(原始输入和解码器输出的差异)来优化编码器 + 解码器的参数。没有训练的 "编码",只是一次无意义的数学变换;只有经过训练,编码器才能输出和数据内在结构匹配的特征。

本来计划这里再给一个本文数据集的例子,但是现在NLP基本上被transformers杀穿了,所以NLP的数据集基本上都是tokenizer来处理的,还是有一定的门槛,以后讲完transformers再补上吧

相关推荐
Eloudy1 分钟前
用 Python 直写 CUDA Kernel的技术,CuTile、TileLang、Triton 与 PyTorch 的深度融合实践
人工智能·pytorch
神的泪水2 分钟前
CANN 实战全景篇:从零构建 LLM 推理引擎(基于 CANN 原生栈)
人工智能
yuanyuan2o23 分钟前
【深度学习】全连接、卷积神经网络
人工智能·深度学习·cnn
八零后琐话8 分钟前
干货:Claude最新大招Cowork避坑!
人工智能
汗流浃背了吧,老弟!26 分钟前
BPE 词表构建与编解码(英雄联盟-托儿索语料)
人工智能·深度学习
软件聚导航34 分钟前
从 AI 画马到马年红包封面,我还做了一个小程序
人工智能·chatgpt
啊森要自信1 小时前
CANN ops-cv:AI 硬件端视觉算法推理训练的算子性能调优与实战应用详解
人工智能·算法·cann
要加油哦~1 小时前
AI | 实践教程 - ScreenCoder | 多agents前端代码生成
前端·javascript·人工智能
玄同7651 小时前
从 0 到 1:用 Python 开发 MCP 工具,让 AI 智能体拥有 “超能力”
开发语言·人工智能·python·agent·ai编程·mcp·trae
新缸中之脑1 小时前
用RedisVL构建长期记忆
人工智能