欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 神经网络基础-价格分类案例

神经网络基础-价格分类案例

2025/2/23 23:59:08 来源:https://blog.csdn.net/dwjf321/article/details/145185756  浏览:    关键词:神经网络基础-价格分类案例

文章目录

    • 1. 需求分析
    • 2. 导入所需工具包
    • 3. 构建数据集
    • 4. 构建分类网络模型
    • 5. 训练模型
    • 6. 模型训练
    • 7. 评估模型
    • 8. 模型优化

学习目标:

  1. 掌握构建分类模型流程
  2. 动手实践整个过程

1. 需求分析

小明创办了一家手机公司,他不知道如何估算手机产品的价格。为了解决这个问题,他收集了多家公司的手机销售数据。该数据为二手手机的各个性能的数据,最后根据这些性能得到4个价格区间,作为这些二手手机售出的价格区间。主要包括:

battery_power电池一次可存储的电量,单位:毫安/时
blue是否有蓝牙
clock_speed微处理器执行指令的速度
dual_sim是否支持双卡
fc前置摄像头百万像素
four_g是否有4G
int_memory内存(GB)
m_dep移动深度(cm)
mobile_wt手机重量
n_cores处理器内核数
pc主摄像头百万像素
px_height像素分辨率高度
px_width像素分辨率宽度
ram随机存储器(兆字节)
sc_h手机屏幕高度(cm)
sc_w手机屏幕宽度(cm)
talk_time一次充电持续时长
three_g是否有3G
touch_screen是否有触屏控制
wifi是否能连wifi
price_range价格区间(0,1,2,3)

我们需要帮助小明找出手机的功能(例如:RAM等)与其售价之间的某种关系。我们可以使用机器学习的方法来解决这个问题,也可以构建一个全连接的网络。

需要注意的是: 在这个问题中,我们不需要预测实际价格,而是一个价格范围,它的范围使用 0、1、2、3 来表示,所以该问题也是一个分类问题。接下来我们还是按照四个步骤来完成这个任务:

  • 准备训练集数据

  • 构建要使用的模型

  • 模型训练

  • 模型预测评估

2. 导入所需工具包

# 导入相关模块
import torch
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import time

3. 构建数据集

数据共有 2000 条, 其中 1600 条数据作为训练集, 400 条数据用作测试集。 我们使用 sklearn 的数据集划分工作来完成。并使用 PyTorch 的 TensorDataset 来将数据集构建为 Dataset 对象,方便构造数据集加载对象。

#1. 导入相关模块
import torch
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import time# 构建数据集
def load_dataset():# 使用pandas 读取数据data = pd.read_csv('data/手机价格预测.csv')# 特征值和目标值x,y = data.iloc[:,:-1],data.iloc[:,-1]# 类型转换:特征值,目标值x = x.astype(np.float32)y = y.astype(np.int64)# 划分训练集和测试集x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=88)# 构建数据集,转换为pytorch格式train_dataset = TensorDataset(torch.from_numpy(x_train.values), torch.from_numpy(y_train.values))test_dataset = TensorDataset(torch.from_numpy(x_test.values), torch.from_numpy(y_test.values))#返回结果return train_dataset, test_dataset,x_train.shape[1],len(np.unique(y))if __name__ == '__main__':train_dataset, test_dataset,input_dim,class_num = load_dataset()print("输入特征数:",input_dim)print("分类个数:",class_num)

输出结果为:

输入特征数: 20
分类个数: 4

4. 构建分类网络模型

构建全连接神经网络来进行手机价格分类,该网络主要由三个线性层来构建,使用relu激活函数。

网络共有 3 个全连接层, 具体信息如下:

  1. 第一层: 输入为维度为 20, 输出维度为: 128
  2. 第二层: 输入为维度为 128, 输出维度为: 256
  3. 第三层: 输入为维度为 256, 输出维度为: 4
# 构建网络模型
class PhonePriceModel(nn.Module):def __init__(self,input_dim,output_dim):super(PhonePriceModel, self).__init__()# 1. 第一层: 输入为维度为 20, 输出维度为: 128self.linear1 = nn.Linear(input_dim, 128)# 2. 第二层: 输入为维度为 128, 输出维度为: 256self.linear2 = nn.Linear(128, 256)# 3. 第三层: 输入为维度为 256, 输出维度为: 4self.linear3 = nn.Linear(256, output_dim)def forward(self, x):# 前向传播过程x = torch.relu(self.linear1(x))x = torch.relu(self.linear2(x))output = self.linear3(x)# 获取数据结果return outputif __name__ == '__main__':train_dataset, test_dataset,input_dim,class_num = load_dataset()print("输入特征数:",input_dim)print("分类个数:",class_num)# 模型实例化model = PhonePriceModel(input_dim,class_num)

5. 训练模型

网络编写完成之后,我们需要编写训练函数。所谓的训练函数,指的是输入数据读取、送入网络、计算损失、更新参数的流程,该流程较为固定。我们使用的是多分类交叉生损失函数、使用 SGD 优化方法。最终,将训练好的模型持久化到磁盘中。

# 模型训练过程
def train(train_dataset,input_dim,class_num):# 固定随机数种子torch.manual_seed(0)# 初始化模型model = PhonePriceModel(input_dim,class_num)# 损失函数criterion = nn.CrossEntropyLoss()# 优化方法optimizer = optim.SGD(model.parameters(), lr=1e-3)# 训练轮数num_epochs = 50# 遍历轮数for epoch_idx in range(num_epochs):# 初始化数据加载器dataloader = DataLoader(train_dataset, batch_size=8, shuffle=True)# 训练时间start = time.time()# 计算损失total_loss = 0.0total_num = 1# 遍历每个batch数据进行处理for x,y in dataloader:# 将数据送入网络中进行预测output = model(x)# 计算损失loss = criterion(output, y)#梯度清零optimizer.zero_grad()# 方向传播loss.backward()# 参数更新optimizer.step()# 损失计算total_num += 1total_loss += loss.item()# 打印损失变换结果print('epoch: %4s loss: %.2f, time: %.2fs' % (epoch_idx + 1, total_loss / total_num, time.time() - start))# 保存模型torch.save(model.state_dict(), 'model/phone.ptn')

6. 模型训练

if __name__ == '__main__':train_dataset, test_dataset,input_dim,class_num = load_dataset()print("输入特征数:",input_dim)print("分类个数:",class_num)# 模型训练过程train(train_dataset,input_dim,class_num)

输出结果:

epoch:    1 loss: 13.31, time: 0.25s
epoch:    2 loss: 0.96, time: 0.24s
epoch:    3 loss: 0.90, time: 0.24s
epoch:    4 loss: 0.89, time: 0.25s
epoch:    5 loss: 0.86, time: 0.26s
...
epoch:   46 loss: 0.68, time: 0.25s
epoch:   47 loss: 0.69, time: 0.26s
epoch:   48 loss: 0.68, time: 0.28s
epoch:   49 loss: 0.69, time: 0.24s
epoch:   50 loss: 0.69, time: 0.24s

7. 评估模型

使用训练好的模型,对未知的样本的进行预测的过程。我们这里使用前面单独划分出来的验证集来进行评估。

# 4 评估模型
def test(test_dataset,input_dim,class_num):# 加载模型和训练好的网络参数model = PhonePriceModel(input_dim,class_num)model.load_state_dict(torch.load('model/phone.ptn',weights_only=False))# 构建加载器dataloader = DataLoader(test_dataset, batch_size=8, shuffle=True)# 评估测试集correct = 0# 遍历测试集中的数据for x,y in dataloader:# 将其送入网络中output = model(x)# 获取类别结果y_pred = torch.argmax(output, dim=1)# 获取预测正确的个数correct += (y_pred == y).sum().sum()# 求预测精度print('Acc: %.5f' % (correct.item() / len(test_dataset)))
if __name__ == '__main__':train_dataset, test_dataset,input_dim,class_num = load_dataset()print("输入特征数:",input_dim)print("分类个数:",class_num)# 评估模型test(test_dataset,input_dim,class_num)

输出结果:

Acc: 0.62500

8. 模型优化

我们前面的网络模型在测试集的准确率为: 0.54750, 我们可以通过以下方面进行调优:

  1. 优化方法由 SGD 调整为 Adam
  2. 学习率由 1e-3 调整为 1e-4
  3. 对数据数据进行标准化
  4. Dropout 正则化
  5. 调整训练轮次
# 使用Adam方法优化网络
#1. 导入相关模块
import torch
from tensorboard import summary
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
import torch.nn as nn
import torch.optim as optim
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import time#2. 构建数据集
def load_dataset():# 使用pandas 读取数据data = pd.read_csv('data/手机价格预测.csv')# 特征值和目标值x,y = data.iloc[:,:-1],data.iloc[:,-1]# 类型转换:特征值,目标值x = x.astype(np.float32)y = y.astype(np.int64)# 划分训练集和测试集x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=88)# 数据标准化scaler = StandardScaler()x_train = scaler.fit_transform(x_train)x_test = scaler.fit_transform(x_test)x_train = torch.tensor(x_train,dtype=torch.float32)x_test = torch.tensor(x_test,dtype=torch.float32)# 构建数据集,转换为pytorch格式train_dataset = TensorDataset(x_train, torch.from_numpy(y_train.values))test_dataset = TensorDataset(x_test, torch.from_numpy(y_test.values))#返回结果return train_dataset, test_dataset,x_train.shape[1],len(np.unique(y))
#2. 构建网络模型
class PhonePriceModel(nn.Module):def __init__(self,input_dim,output_dim,p_dropout=0.4):super(PhonePriceModel, self).__init__()# 第一层: 输入为维度为 20, 输出维度为: 128self.linear1 = nn.Linear(input_dim, 128)# Dropout优化self.dropout = nn.Dropout(p_dropout)# 第二层: 输入为维度为 128, 输出维度为: 256self.linear2 = nn.Linear(128, 256)# Dropout优化self.dropout = nn.Dropout(p_dropout)# 第三层: 输入为维度为 256, 输出维度为: 4self.linear3 = nn.Linear(256, output_dim)def forward(self, x):# 前向传播过程x = torch.relu(self.linear1(x))x = torch.relu(self.linear2(x))output = self.linear3(x)# 获取数据结果return output# 3. 模型训练过程
def train(train_dataset,input_dim,class_num):# 固定随机数种子torch.manual_seed(0)# 初始化模型model = PhonePriceModel(input_dim,class_num)# 损失函数criterion = nn.CrossEntropyLoss()# 优化方法# optimizer = optim.SGD(model.parameters(), lr=1e-3)# Adam优化方法 调整学习率为 lr=1e-4optimizer = torch.optim.Adam(model.parameters(), lr=1e-4, betas=(0.9, 0.99))# 训练轮数 100 - 0.9075 50 - 0.9125num_epochs = 50# 遍历轮数for epoch_idx in range(num_epochs):# 初始化数据加载器dataloader = DataLoader(train_dataset, batch_size=8, shuffle=True)# 训练时间start = time.time()# 计算损失total_loss = 0.0total_num = 1# 遍历每个batch数据进行处理for x,y in dataloader:# 将数据送入网络中进行预测output = model(x)# 计算损失loss = criterion(output, y)#梯度清零optimizer.zero_grad()# 方向传播loss.backward()# 参数更新optimizer.step()# 损失计算total_num += 1total_loss += loss.item()# 打印损失变换结果print('epoch: %4s loss: %.2f, time: %.2fs' % (epoch_idx + 1, total_loss / total_num, time.time() - start))# 保存模型torch.save(model.state_dict(), 'model/phone2.ptn')
# 4 评估模型
def test(test_dataset,input_dim,class_num):# 加载模型和训练好的网络参数model = PhonePriceModel(input_dim,class_num)model.load_state_dict(torch.load('model/phone2.ptn',weights_only=False))# 构建加载器dataloader = DataLoader(test_dataset, batch_size=8, shuffle=True)# 评估测试集correct = 0# 遍历测试集中的数据for x,y in dataloader:# 将其送入网络中output = model(x)# 获取类别结果y_pred = torch.argmax(output, dim=1)# 获取预测正确的个数correct += (y_pred == y).sum().sum()# 求预测精度print('Acc: %.5f' % (correct.item() / len(test_dataset)))
if __name__ == '__main__':train_dataset, test_dataset,input_dim,class_num = load_dataset()print("输入特征数:",input_dim)print("分类个数:",class_num)# 模型训练train(train_dataset,input_dim,class_num)test(test_dataset,input_dim,class_num)

这里我们调整 Adam方法优化梯度下降,学习率调整为1e-4,样本数据采用标准化处理。采用Dropout正则化。最后输出结果:

Acc: 0.91250

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词