预测分析(四):面向预测分析的神经网络简介

面向预测分析的神经网络简介

神经网络模型

在这里插入图片描述
神经网络(Neural Network),也被称为人工神经网络(Artificial Neural Network,ANN),是一种模仿人类神经系统的计算模型,在机器学习和深度学习领域应用广泛。

1. 基本概念

  • 神经元:神经网络的基本计算单元,接收多个输入信号,通过激活函数对输入进行非线性变换后输出结果。一个简单的神经元可以表示为 y = f ( ∑ i = 1 n w i x i + b ) y = f(\sum_{i = 1}^{n}w_{i}x_{i}+b) y=f(i=1nwixi+b),其中 x i x_i xi 是输入, w i w_i wi 是对应的权重, b b b 是偏置, f f f激活函数。
  • :多个神经元组成一层,常见的层包括输入层、隐藏层和输出层。输入层接收原始数据;隐藏层对输入数据进行特征提取和转换;输出层给出最终的预测结果。
  • 网络结构:不同层之间相互连接形成神经网络的结构,常见的有前馈神经网络(Feed - Forward Neural Network),信息只能从输入层依次向前传递到输出层;还有循环神经网络(Recurrent Neural Network,RNN),它允许信息在网络中循环流动,适合处理序列数据。

2. 前馈神经网络

  • 工作原理:输入数据从输入层进入,经过隐藏层的一系列计算和变换,最终在输出层得到预测结果。每一层的神经元将上一层的输出作为输入,通过加权求和和激活函数处理后传递给下一层。
  • 训练过程
    • 定义损失函数:用于衡量预测结果与真实标签之间的差异,常见的损失函数有均方误差(Mean Squared Error,MSE)用于回归问题,交叉熵损失(Cross - Entropy Loss)用于分类问题。
    • 前向传播:将输入数据传入网络,计算得到预测结果。
    • 反向传播:根据损失函数的梯度,从输出层开始反向计算每个参数(权重和偏置)的梯度,以确定如何调整参数来减小损失。
    • 参数更新:使用优化算法(如随机梯度下降,SGD)根据计算得到的梯度更新网络中的参数。

3. 常见激活函数

  • Sigmoid函数

f ( x ) = 1 1 + e − x f(x)=\frac{1}{1 + e^{-x}} f(x)=1+ex1

将输入值映射到 (0, 1) 区间,常用于二分类问题的输出层。但它存在梯度消失问题,即当输入值过大或过小时,梯度趋近于 0,导致训练速度变慢。

  • ReLU函数

f ( x ) = max ⁡ ( 0 , x ) f(x)=\max(0,x) f(x)=max(0,x)

计算简单,能有效缓解梯度消失问题,在隐藏层中应用广泛。

  • Softmax函数

常用于多分类问题的输出层,将输入值转换为概率分布,所有输出值之和为 1。

4. 循环神经网络(RNN)

  • 特点:RNN 引入了循环结构,允许信息在不同时间步之间传递,因此能够处理序列数据,如自然语言处理中的文本序列、时间序列分析中的股票价格数据等。
  • 局限性:传统的 RNN 存在长期依赖问题,即难以捕捉序列中相隔较远的信息之间的关系。为了解决这个问题,出现了长短期记忆网络(LSTM)和门控循环单元(GRU)等改进模型。

5. 卷积神经网络(CNN)

  • 原理:CNN 主要用于处理具有网格结构的数据,如图像。它通过卷积层、池化层和全连接层组成。卷积层使用卷积核在输入数据上滑动进行卷积操作,提取局部特征;池化层用于降低特征图的维度,减少计算量;全连接层将卷积和池化得到的特征进行整合,输出最终的预测结果。
  • 优势:CNN 具有参数共享和局部连接的特点,大大减少了模型的参数数量,降低了计算复杂度,同时提高了模型的泛化能力。

MPL

MLP通常指多层感知机(Multilayer Perceptron),它是一种基础且经典的人工神经网络模型,下面从结构、工作原理、激活函数、训练方法、优缺点和应用场景等方面为你详细介绍:

结构

MLP由输入层、一个或多个隐藏层以及输出层组成。

  • 输入层:负责接收原始数据,神经元的数量通常等于输入特征的数量。
  • 隐藏层:可以有一层或多层,每一层包含多个神经元。隐藏层通过非线性变换对输入数据进行特征提取和转换,是MLP学习复杂模式的关键部分。
  • 输出层:输出模型的预测结果,神经元的数量根据具体的任务而定。例如,在二分类问题中,输出层可能只有一个神经元;在多分类问题中,输出层的神经元数量等于类别数。

工作原理

MLP的工作过程分为前向传播和反向传播。

  • 前向传播:输入数据从输入层传入,依次经过各个隐藏层,最终到达输出层。在每一层中,神经元会对输入进行加权求和,并通过激活函数进行非线性变换,将结果传递给下一层。
  • 反向传播:根据输出层的预测结果与真实标签之间的误差,计算误差关于每个神经元权重的梯度,然后使用优化算法(如梯度下降法)更新权重,以减小误差。

激活函数

激活函数为MLP引入非线性特性,使其能够学习复杂的非线性关系。常见的激活函数有:

  • Sigmoid函数:将输入映射到(0, 1)区间,常用于二分类问题的输出层。
  • ReLU函数:当输入大于0时,输出等于输入;当输入小于等于0时,输出为0。它计算简单,能有效缓解梯度消失问题,是隐藏层中常用的激活函数。
  • Softmax函数:常用于多分类问题的输出层,将输出转换为概率分布。

训练方法

MLP通常使用误差反向传播算法(Backpropagation)进行训练,具体步骤如下:

  1. 初始化权重:随机初始化MLP中所有神经元之间的连接权重。
  2. 前向传播:将输入数据传入网络,计算输出结果。
  3. 计算误差:根据输出结果与真实标签之间的差异,计算损失函数的值。
  4. 反向传播:计算误差关于每个权重的梯度。
  5. 更新权重:使用优化算法(如随机梯度下降、Adam等)根据梯度更新权重。
  6. 重复步骤2 - 5:直到损失函数收敛或达到预设的训练轮数。

基于神经网络的回归——以钻石为例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
%matplotlib inline

DATA_DIR = '../data'
FILE_NAME = 'diamonds.csv'
data_path = os.path.join(DATA_DIR, FILE_NAME)
diamonds = pd.read_csv(data_path)

# 数据预处理
diamonds = diamonds.loc[(diamonds['x'] > 0) | (diamonds['y'] > 0)]
diamonds.loc[11182, 'x'] = diamonds['x'].median()
diamonds.loc[11182, 'z'] = diamonds['z'].median()
diamonds = diamonds.loc[~((diamonds['y'] > 30) | (diamonds['z'] > 30))]
diamonds = pd.concat([diamonds, pd.get_dummies(diamonds['cut'], prefix='cut', drop_first=True)], axis=1)
diamonds = pd.concat([diamonds, pd.get_dummies(diamonds['color'], prefix='color', drop_first=True)], axis=1)
diamonds = pd.concat([diamonds, pd.get_dummies(diamonds['clarity'], prefix='clarity', drop_first=True)], axis=1)

# 分割数据集
X = diamonds.drop(['cut', 'color', 'clarity', 'price'], axis=1)
y = diamonds['price']

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=123)

# PCA降维
from sklearn.decomposition import PCA
pca = PCA(n_components=1, random_state=123)
pca.fit(X_train[['x', 'y', 'z']])
X_train['dim_index'] = pca.transform(X_train[['x', 'y', 'z']]).flatten()
X_train.drop(['x', 'y', 'z'], axis=1, inplace=True)

# 标准化数值特征
numerical_features = ['carat', 'depth', 'table', 'dim_index']
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train[numerical_features])
X_train.loc[:, numerical_features] = scaler.transform(X_train[numerical_features])

现在我们完成了神经网络的建模工作。

构建预测钻石价格的MLP

如前面所述,神经网络模型由一系列的层组成,因此Keras有一个类称为Sequential这个类可以用来实例化神经网络模型:

from keras.models import Sequential
nn_reg = Sequential()

现在需要为它添加层——奖使用的层名为全连接层或者稠密层:

from keras.layers import Dense

接下来添加第一层:

n_input=X_train.shape[1]
n_hidden1=32
# 增加第一个隐藏层
nn_reg.add(Dense(units=n_hidden1,activation='relu',input_shape=(n_input,)))
  • units:这是层中神经元的个数
  • activation:这是每个神经元的激活函数,这里选用:ReLu
  • input_shape:这是网络接受的输入个数,其值等于数据集合中预测特征的个数。

接下来我们可以添加更多的隐藏层:

n_hidden2=16
n_hidden3=8
nn_reg.add(Dense(units=n_hidden2,activation='relu'))
nn_reg.add(Dense(units=n_hidden3,activation='relu'))
......

注意:这里使用各层的单元个数以 2 2 2的乘方逐次减少。

我们现在还需要添加一个最终层——输出层。对于每个样本来说,这是一个回归问题,需要的结果只有一个。因此添加最后一层:

nn_reg.add(Dense(units=1,activation=None))

接下来就要训练 M L P MLP MLP了,修正这些随机的权重和偏置。

训练 M L P MLP MLP

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPRegressor
from sklearn.metrics import mean_squared_error, r2_score

# 假设之前的数据预处理代码已经执行,这里接着进行模型训练
# ...之前的数据预处理代码...

# 训练MLP模型
mlp = MLPRegressor(hidden_layer_sizes=(100, 50),  # 两个隐藏层,分别有100和50个神经元
                   activation='relu',  # 使用ReLU激活函数
                   solver='adam',  # 使用Adam优化器
                   random_state=123,
                   max_iter=500)  # 最大迭代次数

mlp.fit(X_train, y_train)

# 对测试集进行预测
X_test['dim_index'] = pca.transform(X_test[['x', 'y', 'z']]).flatten()
X_test.drop(['x', 'y', 'z'], axis=1, inplace=True)
X_test.loc[:, numerical_features] = scaler.transform(X_test[numerical_features])
y_pred = mlp.predict(X_test)

# 评估模型
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f"均方误差 (MSE): {mse}")
print(f"决定系数 (R²): {r2}")
    

all

import numpy as np
import pandas as pd
import os
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.metrics import mean_squared_error, r2_score

# 假设之前的数据预处理代码已经执行,这里接着进行模型训练
# ...之前的数据预处理代码...

# 创建Sequential模型
nn_reg = Sequential()

# 获取输入特征的数量
n_input = X_train.shape[1]
n_hidden1 = 32
# 增加第一个隐藏层
nn_reg.add(Dense(units=n_hidden1, activation='relu', input_shape=(n_input,)))

# 添加更多的隐藏层
n_hidden2 = 16
n_hidden3 = 8
nn_reg.add(Dense(units=n_hidden2, activation='relu'))
nn_reg.add(Dense(units=n_hidden3, activation='relu'))

# 添加输出层
nn_reg.add(Dense(units=1, activation=None))

# 编译模型
nn_reg.compile(optimizer='adam',  # 使用Adam优化器
               loss='mse',  # 使用均方误差作为损失函数
               metrics=['mse'])  # 监控均方误差

# 训练模型
history = nn_reg.fit(X_train, y_train,
                     epochs=50,  # 训练的轮数
                     batch_size=32,  # 每个批次的样本数
                     validation_split=0.1,  # 用于验证集的比例
                     verbose=1)

# 对测试集进行预测
X_test['dim_index'] = pca.transform(X_test[['x', 'y', 'z']]).flatten()
X_test.drop(['x', 'y', 'z'], axis=1, inplace=True)
X_test.loc[:, numerical_features] = scaler.transform(X_test[numerical_features])
y_pred = nn_reg.predict(X_test)

# 评估模型
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f"均方误差 (MSE): {mse}")
print(f"决定系数 (R²): {r2}")

# 绘制训练和验证损失曲线
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
    

基于神经网络的分类

类似的,这里先水一下:

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
from sklearn.metrics import accuracy_score

# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target

# 数据预处理
# 数据标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 标签编码
encoder = OneHotEncoder(sparse_output=False)
y = encoder.fit_transform(y.reshape(-1, 1))

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 构建模型
model = Sequential()
model.add(Dense(16, activation='relu', input_shape=(X_train.shape[1],)))
model.add(Dense(8, activation='relu'))
model.add(Dense(3, activation='softmax'))

# 编译模型
model.compile(optimizer=Adam(learning_rate=0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 训练模型
model.fit(X_train, y_train, epochs=50, batch_size=16, validation_split=0.1)

# 评估模型
y_pred = model.predict(X_test)
y_pred_classes = np.argmax(y_pred, axis=1)
y_test_classes = np.argmax(y_test, axis=1)
accuracy = accuracy_score(y_test_classes, y_pred_classes)
print(f"模型准确率: {accuracy}")
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值