Keras-3-实例3-回归问题

news2024/11/30 14:26:40

1. 回归问题

1.1 波士顿房价数据集加载:

  1. 预测20世界70年代中期波士顿郊区房屋价格的中位数。

  2. 已知当时郊区有一些数据点,如犯罪率、房产税率等。

  3. 与IMDB和路透社数据集相比,波士顿房价数据集样本量比较少,只有506个样本;同时,每个特征都都有不同的取值范围。

  4. 本次实验将其中102个作为测试样本,剩下的404个作为训练样本。

## 加载波士顿房价数据集
from keras.datasets import boston_housing

(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()
## 因为是回归问题,所以不再用labels,而是用targets
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/boston_housing.npz
57026/57026 [==============================] - 0s 4us/step
print(train_data.shape) ##训练样本数和特征数(单位是:千美元)
print(train_data) ## 训练样本
(404, 13)
[[1.23247e+00 0.00000e+00 8.14000e+00 ... 2.10000e+01 3.96900e+02
  1.87200e+01]
 [2.17700e-02 8.25000e+01 2.03000e+00 ... 1.47000e+01 3.95380e+02
  3.11000e+00]
 [4.89822e+00 0.00000e+00 1.81000e+01 ... 2.02000e+01 3.75520e+02
  3.26000e+00]
 ...
 [3.46600e-02 3.50000e+01 6.06000e+00 ... 1.69000e+01 3.62250e+02
  7.83000e+00]
 [2.14918e+00 0.00000e+00 1.95800e+01 ... 1.47000e+01 2.61950e+02
  1.57900e+01]
 [1.43900e-02 6.00000e+01 2.93000e+00 ... 1.56000e+01 3.76700e+02
  4.38000e+00]]
print(test_data.shape) ## 测试样本数和特征数
print(test_data) ## 测试样本
(102, 13)
[[1.80846e+01 0.00000e+00 1.81000e+01 ... 2.02000e+01 2.72500e+01
  2.90500e+01]
 [1.23290e-01 0.00000e+00 1.00100e+01 ... 1.78000e+01 3.94950e+02
  1.62100e+01]
 [5.49700e-02 0.00000e+00 5.19000e+00 ... 2.02000e+01 3.96900e+02
  9.74000e+00]
 ...
 [1.83377e+00 0.00000e+00 1.95800e+01 ... 1.47000e+01 3.89610e+02
  1.92000e+00]
 [3.58090e-01 0.00000e+00 6.20000e+00 ... 1.74000e+01 3.91700e+02
  9.71000e+00]
 [2.92400e+00 0.00000e+00 1.95800e+01 ... 1.47000e+01 2.40160e+02
  9.81000e+00]]
print(train_targets[0:10]) ## 预测目标 (房价的中位数)
print(test_targets[0:10]) ## 测试目标 (房价的中位数)
[15.2 42.3 50.  21.1 17.7 18.5 11.3 15.6 15.6 14.4]
[ 7.2 18.8 19.  27.  22.2 24.5 31.2 22.9 20.5 23.2]

1.2 数据预处理:

因为不同特征的取值范围差别比较大,所以不能直接输入神经网络中。因此需要先对这些特征做标准化 (主要是对列做标准差处理,使每一列得到均值为0,标准差为1的特征值)。

mean = train_data.mean(axis=0) ## 取每一列的均值
train_data -= mean ## 每一列特征值减去该列的均值
std = train_data.std(axis=0) ## 取每一列的标准差
train_data /= std ## 得到标准化结果

## 需要注意的是:这里测试集的均值和标准差用的也是训练集上的,因为在工作流程中,不能使用在测试集上计算得到的任何结果。
test_data -= mean
test_data /= std

1.3 构建网络:

因为样本较少,所以用一个比较小的网络:两个隐藏层,每层含有32个隐藏单元。

from keras import models
from keras import layers

def build_model():
    ## 因为后面要用交叉验证,所以需要将一个模型进行多次的实例化,所以这里定义了一个函数
    ## 构建模型
    model = models.Sequential()
    model.add(layers.Dense(32, activation="relu", input_shape=(train_data.shape[1],))) ## train_data.shape[1]=13,因为有13个特征
    model.add(layers.Dense(32, activation="relu"))
    model.add(layers.Dense(1)) ## 因为目的是预测房价中位数(是一个数值),所以保留原始输出即可。没有添加激活函数,因为激活函数会限制输出范围。

    ## 编译模型
    model.compile(optimizer="rmsprop",
                  loss="mse",       ## 损失函数用的是 均方误差 (mse, mean squared error),预测值与真实值之差的平方,是回归问题中常用的损失函数
                  metrics=["mae"])  ## 监控指标用的是 平均绝对误差 (mae, mean absolute error) ,预测值与真实值之差的绝对值
    return model

1.4 K折交叉验证:

在调节网络参数 (比如epochs等) 的同时对网络进行评估,可以用K折交叉验证的方法来处理。

K折交叉验证:将数据集分为 K 份,实例化 K 个相同的模型。将每个模型在 K-1 个数据集上训练,在剩下的那一个数据集上做验证评估。模型的验证分数等于 K 个验证分数的均值。

import numpy as np

k = 4 ## K折
num_val_samples = len(train_data) // k ## 验证集中的样本数,将训练集分为k份,每一份都会用作验证集
num_epochs = 500 ## 训练500次
all_mae_histories = [] ##保留每一轮训练中所有的 mae

for i in range(k):
    print("processing fold #", i) ## 每一折都要单独做
    val_data = train_data[i*num_val_samples: (i+1)*num_val_samples] ## 第k份的数据作为验证集
    val_targets = train_targets[i*num_val_samples: (i+1)*num_val_samples] ## 验证标签

    partial_train_data = np.concatenate([train_data[:i*num_val_samples], train_data[(i+1)*num_val_samples:]], axis=0) ## 其他的 k-1 份数据集合并,作为训练集
    partial_train_targets = np.concatenate([train_targets[:i*num_val_samples], train_targets[(i+1)*num_val_samples:]], axis=0) ## 训练标签

    model = build_model() ## 每一折都要实例化一个相同的模型
    
    ## 在训练集上训练模型,在验证集上评估模型
    history = model.fit(partial_train_data,
              partial_train_targets,
              epochs=num_epochs,
              batch_size=1,
              verbose=0,
              validation_data=(val_data, val_targets))
    mae_history = history.history["val_mae"]
    all_mae_histories.append(mae_history)

    ## 模型参数的 verbose 用法详解: https://blog.csdn.net/qq_23933415/article/details/111212898
processing fold # 0
processing fold # 1
processing fold # 2
processing fold # 3
average_mae_history = [np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)] ## 求每一次训练得到的4个模型的mae的平均值

1.5 可视化 监控指标 (mae):

import matplotlib.pyplot as plt

plt.plot(range(1, len(average_mae_history)+1), average_mae_history)
plt.xlabel("Epochs")
plt.ylabel("Validation MAE")
plt.show()

在这里插入图片描述

由于上图纵轴范围较大,将上述可视化曲线进一步平滑化

删除前10个点之后(因为前10个点取值范围与其他点不同),剩下的每个数据点做一下处理:

将每个数据点替换为前面数据点的指数移动平均值,用于得到光滑的曲线。

就是前一个点占0.9,当前点占0.1,二者加和作为当前点。

## 舍弃前10个点,后面的数据点做平滑化处理之后的结果:

def smooth_curve(points, factor=0.9):
    smoothed_points = []
    for point in points:
        if smoothed_points:
            previous = smoothed_points[-1]
            smoothed_points.append(previous*factor + point*(1-factor)) ## 当前点 = 前一个点*0.9 + 当前点*0.1
        else:
            smoothed_points.append(point)
    return smoothed_points

smooth_mae_history = smooth_curve(average_mae_history[10:])

plt.plot(range(1, len(smooth_mae_history)+1), smooth_mae_history)
plt.xlabel("Epochs")
plt.ylabel("Validation MAE")
plt.show()

在这里插入图片描述

1.6 从头开始训练最终模型:

从上述平滑后的曲线图可以看出,但epochs大约为90时,Validation MAE最小。所以选择epochs=80来重新训练模型。

model = build_model()
model.fit(train_data, train_targets, epochs=90, batch_size=8, verbose=0) ## 在所有的训练数据集上重新训练模型。
test_mse_score, test_mae_score = model.evaluate(test_data, test_targets)
4/4 [==============================] - 0s 25ms/step - loss: 19.7469 - mae: 2.7381
## 最终预测结果:
print(test_mae_score)

## 结果表示 预测价格的中位数和实际价格的中位数之间相差大约2738美元。
2.738111972808838

1.7 小结:

  1. 回归问题常用的损失函数是 均方误差 (MSE);

  2. 回归问题的评估指标最常用的是 平均绝对误差 (MAE);

  3. 如果输入特征有不同的取值范围,那么需要各自进行标准化处理 (需要注意的是:测试集的均值和标准差用的也是训练集上的,因为在工作流程中,不能使用在测试集上计算得到的任何结果);

  4. 如果可用的样本数据较少,可以用 K折交叉验证对模型进行可靠地评估;

  5. 如果训练数据较少,可以使用更小的网络来 (更少的层数、更少的隐藏单元个数) 避免出现严重的过拟合;

  6. 在从头开始重新训练模型时,要用全部的训练数据 (包括训练集和验证集) 进行模型的训练。

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

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

相关文章

数据结构——绪论/线性表

文章目录 **一 基本概念****二 算法和算法评价****三 线性表的定义和基本操作****四 线性表的顺序表示****1 定义****2 基本操作** **五 线性表的链式表示****1 单链表的定义****2 单链表的基本操作实现****3 双链表****4 循环链表****5 静态链表** 一 基本概念 数据类型&…

使用pycharm入门python的一些注意点

今儿在帮别人跑一段python代码,实际上我对python并不熟悉,只能边摸索边尝试。选择了pycharm这个工具。 一.怎么安装python使用的库文件 能用来安装python的库文件的,有很多种办法,这里只介绍pip和pip3。因为pip和pip3的优势是能…

SpringCloud第一篇:服务的注册与发现Eureka

一、spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。 二、创建服务注册中心 …

oracle细节、经验锦集

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/131054454 出自【进步*于辰的博客】> 由于是随兴记录,因此阐述的比较多而乱&…

详解Eureka服务注册和调用

目录 1.概述 2.环境 2.1.项目结构 2.2.项目架构 2.3.依赖 3.注册中心 3.1.配置使用 3.2.管理页 3.3.集群 4.服务注册 5.服务调用 5.2.Ribbon 5.3.Feign 5.4.OpenFeign 1.概述 我们把从外部进入到微服务集群里的流量称为“南北流量”、微服务集群节点间流转的流量…

HTML type=“radio“ 不显示按钮

问题 HTML中type&#xff1d;"radio" 但是在界面中不显示按钮。 详细问题 HTML中type&#xff1d;"radio" 但是在界面中不显示按钮。 笔者html核心代码 <div>性别<input type"radio" id"male" name"gender" va…

chatgpt赋能python:Python中的中文分词神器——jieba

Python中的中文分词神器——jieba 介绍 如果你曾经在处理中文文本时&#xff0c;也许会遇到中文分词的需求&#xff0c;jieba就是一款不可错过的工具。 jieba 是目前最好的 Python 中文分词库&#xff0c;它具有高效、简单和可定制等优点&#xff0c;适合各种规模的文本分词…

Linux学习之vim四种模式初探

vim是一个多模式&#xff0c;有vim /所在目录/文件名&#xff0c;若是已经有了文件&#xff0c;可以打开文件进行编辑&#xff0c;若是没有文件&#xff0c;在vim中保存之后就会有一个文件&#xff0c;相当于记事本里边新建一个文件。我现在就使用vim新建一个文件&#xff0c;然…

C# .NET EF框架 webapi 安装使用sqlite

文章目录 Sqlite安装使用Sqlite特点环境安装EF 是什么&#xff1f;EF使用举例 Nuget控制台 Sqlite安装使用 Sqlite特点 Sqlite是轻量级数据库&#xff0c;不需要安装&#xff0c;跨平台使用。是用来做小软件&#xff0c;小项目&#xff0c;快速移植的最优解。不需要像mysql和…

Verilog基础:表达式中的整数常量(integer)

相关文章 Verilog基础&#xff1a;表达式位宽的确定&#xff08;位宽拓展&#xff09; Verilog基础&#xff1a;表达式符号的确定 Verilog基础&#xff1a;数据类型 Verilog基础&#xff1a;位宽拓展和有符号数运算的联系 Verilog基础&#xff1a;case、casex、ca…

chatgpt赋能python:Python如何Input一个字典:详细教程

Python 如何 Input 一个字典&#xff1a;详细教程 在 Python 中&#xff0c;字典是一种非常有用的数据结构。它可以存储键值对&#xff0c;让我们能够通过键访问值。Python 中没有固定的语法来创建字典&#xff0c;因此本文将教你如何输入一个字典。 什么是字典&#xff1f; …

chatgpt赋能python:Python语言中的Pandas库介绍

Python语言中的Pandas库介绍 Python语言是一种十分流行的编程语言&#xff0c;以其易读易写等特点而受到工程师和数据科学家的青睐。在Python语言中&#xff0c;有一款非常流行的数据处理和分析库&#xff0c;也就是Pandas库。Pandas库在数据处理和分析方面有着出色的表现&…

iOS开发最佳实践|集成声网SDK实现语音聊天室

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c; 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。&#x1f60a; 座右铭&#xff1a;不想当开发的测试&#xff0c;不是一个好…

初探Sharding-JDBC订单表分片实现

设计订单系统有两个数据库db_order_01和db_order_02。每个数据库分别有t_order_0和t_order_1两张订单表。 订单表设计有订单ID(order_id)&#xff0c;用户ID(user_id)&#xff0c;商户ID(merchant_id)。假设商户查看订单操作要比用户查看订单的操作更加频繁。避免商户查询订单时…

NLP学习笔记五-simple RNN

NLP学习笔记五-simple RNN 我这个学习笔记&#xff0c;感兴趣的小伙伴&#xff0c;看的时候尽量从头开始看&#xff0c;这样更好理解&#xff0c;也更有收获。 simple RNN的单元结构图如下&#xff1a; 其中A就是我们需要学习的参数矩阵&#xff0c; h t − 1 h_{t-1} ht−1​…

【MySQL数据库 | 第十五篇】事务

目录 前言&#xff1a; 介绍事务&#xff1a; 控制事务&#xff1a; 事务四大特性&#xff1a; 并发事务问题&#xff1a; 事务隔离级别&#xff1a; 总结: 前言&#xff1a; 这章我们将进入到MySQL基础篇的最后一章&#xff1a;事务&#xff0c;希望大家可以坚持下去&#xf…

车间如何做好“生产计划”,打造高效运营的智能工厂

新形势下&#xff0c;面对外部不断变化的市场需求、供应链下游企业管理升级需求以及持续上涨的人力成本&#xff0c;传统工厂模式必须要变革才能更好地发展。热潮之下&#xff0c;企业纷纷规划建设智能工厂。那么&#xff0c;新工厂规划如何避免投入浪费&#xff0c;少走弯路&a…

Linux——进程间通信,信号量的使用+小demo(C语言)

一.什么是信号量呢&#xff1f;用途又是什么呢&#xff1f; 信号量就是解决进程之间竞争资源的情况&#xff0c;比如&#xff1a;我们在宿舍用的公共洗衣机&#xff0c;我们只有当它空闲的时候&#xff0c;我们才可以去使用它&#xff0c;当别人看到洗衣机在使用的时候&#xf…

LVS负载均衡群集部署(DR模式)

一.DR模式 LVS负载均衡群集部署 ipvsadm 工具选项说明&#xff1a; 工具选项作用-A添加虚拟服务器-D删除整个虚拟服务器-s指定负载调度算法&#xff08;轮询&#xff1a;rr、加权轮询&#xff1a;wrr、最少连接&#xff1a;lc、加权最少连接&#xff1a;wlc&#xff09;-a表示…

clickhouse-MergeTree

创建建表语句 create table t_order_mt(id UInt32,sku_id String,total_amount Decimal(16,2),create_time Datetime ) engine MergeTreepartition by toYYYYMMDD(create_time)primary key (id)order by (id,sku_id); 插入测试数据 insert into t_order_mt(id,sku_id,total_…