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

文章目录

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

神经网络模型

神经网络(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+e−x1

将输入值映射到 (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:直到损失函数收敛或达到预设的训练轮数。

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

py 复制代码
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这个类可以用来实例化神经网络模型:

py 复制代码
from keras.models import Sequential
nn_reg = Sequential()

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

py 复制代码
from keras.layers import Dense

接下来添加第一层:

py 复制代码
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:这是网络接受的输入个数,其值等于数据集合中预测特征的个数。

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

py 复制代码
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的乘方逐次减少。

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

py 复制代码
nn_reg.add(Dense(units=1,activation=None))

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

训练 M L P MLP MLP

py 复制代码
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

py 复制代码
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()
    

基于神经网络的分类

类似的,这里先水一下:

py 复制代码
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}")
    
相关推荐
%d%d26 分钟前
RuntimeError: CUDA error: __global__ function call is not configured
人工智能·深度学习·机器学习
阿维的博客日记15 分钟前
ϵ-prediction和z0-prediction是什么意思
人工智能·深度学习·机器学习
学术交流23 分钟前
2025年软件工程与数据挖掘国际会议(SEDM 2025)
论文阅读·人工智能·数据挖掘·软件工程·论文笔记
生信漫谈40 分钟前
Rice Science∣武汉大学水稻研究团队发现水稻壁相关激酶OsWAKg16和OsWAKg52同时调控水稻抗病性和产量
人工智能·学习方法
TO ENFJ2 小时前
day 10 机器学习建模与评估
人工智能·机器学习
高效匠人2 小时前
文章五《卷积神经网络(CNN)与图像处理》
图像处理·人工智能·python·cnn
卧式纯绿2 小时前
卷积神经网络基础(五)
人工智能·深度学习·神经网络·目标检测·机器学习·计算机视觉·cnn
乌恩大侠2 小时前
【东枫科技】代理销售 NVIDIA DGX Spark 您的桌上有一台 Grace Blackwell AI 超级计算机。
大数据·人工智能·科技·spark·nvidia
zhanzhan01092 小时前
ubantu安装CUDA
人工智能·python·深度学习
IT古董2 小时前
【漫话机器学习系列】243.数值下溢(Underflow)
人工智能·机器学习