前言
提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。
分类与回归算法
机器学习中的分类与回归算法是两种主要的监督学习任务,它们分别用于解决不同类型的问题。以下是这两种算法的总结:
分类算法:
分类算法用于将数据分成不同的类别,适用于输出为离散标签的问题。常见的分类算法包括:
- 逻辑回归:使用逻辑函数来估计概率,用于二分类问题,也可以扩展到多分类问题。
- 支持向量机(SVM):通过找到最优的决策边界来最大化样本的分类准确率,适用于高维数据。
- 决策树:通过树结构来进行决策,每个节点代表一个特征的选择,叶子节点代表分类结果。
- 随机森林:由多个决策树组成的集成学习方法,通过投票来决定最终分类结果。
- 梯度提升决策树(GBDT):通过构建和结合多个弱学习器来形成强学习器,适用于分类和回归问题。
- 朴素贝叶斯:基于贝叶斯定理,假设特征之间相互独立,适用于文本分类等场景。
- K近邻(KNN):根据样本之间的距离进行分类,适用于小规模数据集。
- 神经网络:通过多层感知机学习数据的复杂模式,适用于图像、语音等复杂分类问题。
回归算法:
回归算法用于预测连续数值输出,适用于输出为连续变量的问题。常见的回归算法包括:
- 线性回归:通过拟合一条直线来预测目标变量的值,是最简单的回归方法。
- 岭回归:线性回归的扩展,通过引入L2正则化项来防止过拟合。
- Lasso回归:线性回归的另一种扩展,通过引入L1正则化项来进行特征选择。
- 弹性网回归:结合了岭回归和Lasso回归,同时引入L1和L2正则化项。
- 决策树回归:使用决策树结构来进行回归预测,适用于非线性关系。
- 随机森林回归:由多个决策树组成的集成学习方法,通过平均来决定最终回归结果。
- 梯度提升决策树回归(GBDT回归):通过构建和结合多个弱学习器来形成强学习器,适用于回归问题。
- 支持向量回归(SVR):支持向量机在回归问题上的应用,通过找到最优的决策边界来最大化样本的回归准确率。
- 神经网络回归:通过多层感知机学习数据的复杂模式,适用于复杂的回归问题。
分类与回归算法的比较:
- 输出类型:分类算法输出离散标签,回归算法输出连续数值。
- 评估指标:分类算法常用准确率、召回率、F1分数等指标,回归算法常用均方误差(MSE)、均方根误差(RMSE)等指标。
- 问题类型:分类算法适用于类别预测问题,如垃圾邮件检测;回归算法适用于数值预测问题,如房价预测。 在实际应用中,选择分类还是回归算法取决于问题的性质和需求。有时,可以将回归问题转化为分类问题,或者将分类问题转化为回归问题,具体取决于问题的特点和目标。
神经网络分类与回归算法区别
神经网络分类算法可参见:python_神经网络
神经网络在分类和回归任务中的应用有所不同,主要体现在输出层的设计和损失函数的选择上。以下是两者的区别及其数学公式分析:
1. 输出层设计
-
分类任务:
- 输出层通常使用Softmax函数,将输出转换为概率分布。
- 对于二分类问题,输出层可以使用Sigmoid函数,输出一个介于0和1之间的值,表示属于某一类的概率。
- 公式:
- Softmax函数:
Softmax ( z i ) = e z i ∑ j = 1 K e z j \text{Softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^K e^{z_j}} Softmax(zi)=∑j=1Kezjezi
其中, z i z_i zi 是第 i i i 个神经元的输出, K K K 是类别总数。 - Sigmoid函数:
σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+e−z1
- Softmax函数:
-
回归任务:
- 输出层通常使用线性激活函数(即恒等函数),直接输出预测值。
- 公式:
y = z y = z y=z
其中, z z z 是输出层的加权和。
2. 损失函数
-
分类任务:
- 常用的损失函数是交叉熵损失(Cross-Entropy Loss),用于衡量预测概率分布与真实标签之间的差异。
- 公式:
- 对于多分类问题:
Cross-Entropy Loss = − ∑ i = 1 K y i log ( y ^ i ) \text{Cross-Entropy Loss} = -\sum_{i=1}^K y_i \log(\hat{y}_i) Cross-Entropy Loss=−i=1∑Kyilog(y^i)
其中, y i y_i yi 是真实标签的one-hot编码, y ^ i \hat{y}_i y^i 是预测概率。 - 对于二分类问题:
Binary Cross-Entropy Loss = − ( y log ( y ^ ) + ( 1 − y ) log ( 1 − y ^ ) ) \text{Binary Cross-Entropy Loss} = -\left( y \log(\hat{y}) + (1 - y) \log(1 - \hat{y}) \right) Binary Cross-Entropy Loss=−(ylog(y^)+(1−y)log(1−y^))
- 对于多分类问题:
-
回归任务:
- 常用的损失函数是均方误差(Mean Squared Error, MSE),用于衡量预测值与真实值之间的平方差。
- 公式:
MSE = 1 N ∑ i = 1 N ( y i − y ^ i ) 2 \text{MSE} = \frac{1}{N} \sum_{i=1}^N (y_i - \hat{y}_i)^2 MSE=N1i=1∑N(yi−y^i)2
其中, y i y_i yi 是真实值, y ^ i \hat{y}_i y^i 是预测值, N N N 是样本数量。
3. 目标
-
分类任务:
- 目标是预测样本所属的类别,输出是离散的类别标签或概率分布。
-
回归任务:
- 目标是预测连续值,输出是一个实数。
总结
- 分类任务:输出层使用Softmax或Sigmoid函数,损失函数使用交叉熵损失,目标是预测类别。
- 回归任务:输出层使用线性激活函数,损失函数使用均方误差,目标是预测连续值。
通过调整输出层和损失函数,神经网络可以灵活地应用于分类和回归任务。
神经网络回归数学原理
神经网络回归算法是一种利用神经网络模型进行数值预测的技术。神经网络由许多简单的计算单元(称为神经元)组成,通过层级结构进行信息处理。这种模型能够学习输入数据与目标输出之间的复杂关系,因此在回归问题中表现出色。以下是关于神经网络回归算法的详细介绍,包括其原理和数学公式。
1. 神经网络的基本结构
神经网络通常由以下几部分组成:
- 输入层:接收输入特征,每个神经元对应一个特征。
- 隐藏层:一个或多个层,负责学习输入数据的特征表示。隐藏层中的神经元连接到前一层的所有神经元,形成全连接结构。
- 输出层:生成最终的预测值,对于回归问题,通常只有一个神经元。
2. 前向传播
在神经网络中,数据通过网络的过程称为前向传播。假设有 L L L 层神经网络,每层的输出由以下公式计算:
- 层
l
l
l 的输出:
z ( l ) = W ( l ) a ( l − 1 ) + b ( l ) z^{(l)} = W^{(l)} a^{(l-1)} + b^{(l)} z(l)=W(l)a(l−1)+b(l)
a ( l ) = f ( z ( l ) ) a^{(l)} = f(z^{(l)}) a(l)=f(z(l))
其中:
- z ( l ) z^{(l)} z(l) 是层 l l l 的加权输入,
- W ( l ) W^{(l)} W(l) 是层 l l l 的权重矩阵,
- a ( l − 1 ) a^{(l-1)} a(l−1) 是层 l − 1 l-1 l−1 的激活输出(即输入层或前一层的输出),
- b ( l ) b^{(l)} b(l) 是层 l l l 的偏置向量,
- f f f 是激活函数(如 ReLU、Sigmoid、Tanh 等),用于引入非线性。
3. 激活函数
激活函数引入了非线性关系,使得神经网络能够学习复杂的函数关系。常用的激活函数包括:
-
ReLU (Rectified Linear Unit):
f ( x ) = max ( 0 , x ) f(x) = \max(0, x) f(x)=max(0,x) -
Sigmoid:
f ( x ) = 1 1 + e − x f(x) = \frac{1}{1 + e^{-x}} f(x)=1+e−x1 -
Tanh:
f ( x ) = e x − e − x e x + e − x f(x) = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}} f(x)=ex+e−xex−e−x
4. 输出层
对于回归问题,输出层通常只有一个神经元,输出是最终的预测值:
y ^ = a ( L ) \hat{y} = a^{(L)} y^=a(L)
5. 损失函数
损失函数用于评估模型的预测性能。在回归问题中,常用的损失函数是均方误差 (MSE):
L ( y , y ^ ) = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 L(y, \hat{y}) = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 L(y,y^)=n1i=1∑n(yi−y^i)2
其中 y i y_i yi 是真实值, y ^ i \hat{y}_i y^i 是预测值, n n n 是样本数量。
6. 反向传播
神经网络通过反向传播算法(Backpropagation)来更新权重和偏置,以最小化损失函数。反向传播的步骤如下:
-
计算损失函数的梯度:
∂ L ∂ W ( l ) 和 ∂ L ∂ b ( l ) \frac{\partial L}{\partial W^{(l)}} \quad \text{和} \quad \frac{\partial L}{\partial b^{(l)}} ∂W(l)∂L和∂b(l)∂L -
更新权重和偏置:
W ( l ) ← W ( l ) − η ∂ L ∂ W ( l ) W^{(l)} \leftarrow W^{(l)} - \eta \frac{\partial L}{\partial W^{(l)}} W(l)←W(l)−η∂W(l)∂L
b ( l ) ← b ( l ) − η ∂ L ∂ b ( l ) b^{(l)} \leftarrow b^{(l)} - \eta \frac{\partial L}{\partial b^{(l)}} b(l)←b(l)−η∂b(l)∂L
其中 η \eta η 是学习率,用于控制更新幅度。
7. 训练过程
神经网络的训练过程通常包括以下步骤:
- 初始化权重和偏置:通常使用小的随机值进行初始化。
- 前向传播:计算输出和损失。
- 反向传播:计算梯度并更新权重和偏置。
- 重复:迭代进行前向传播和反向传播,直到收敛或达到最大迭代次数。
8. 总结
神经网络回归算法通过一系列的线性变换和非线性激活函数来学习输入特征与输出目标之间的复杂关系。通过前向传播和反向传播算法优化模型参数,使得网络能够最小化损失函数,从而提高预测准确性。神经网络因其强大的表达能力,在许多实际应用中表现出了优秀的性能。
算法代码实现
手动实现
import numpy as np
import matplotlib.pyplot as plt
# 1. 定义激活函数和其导数
def relu(x):
return np.maximum(0, x)
def relu_derivative(x):
return 1. * (x > 0)
def linear(x):
return x
def linear_derivative(x):
return np.ones_like(x)
# 2. 定义神经网络类
class NeuralNetworkRegressor:
def __init__(self, input_size, hidden_sizes, output_size, learning_rate=0.01, epochs=1000):
self.input_size = input_size
self.hidden_sizes = hidden_sizes
self.output_size = output_size
self.learning_rate = learning_rate
self.epochs = epochs
# 初始化权重和偏置
self.weights = []
self.biases = []
prev_size = input_size
for size in hidden_sizes:
self.weights.append(np.random.randn(prev_size, size) * 0.01)
self.biases.append(np.zeros((1, size)))
prev_size = size
self.weights.append(np.random.randn(prev_size, output_size) * 0.01)
self.biases.append(np.zeros((1, output_size)))
# 定义激活函数
self.activations = [relu for _ in hidden_sizes] + [linear]
self.activation_derivatives = [relu_derivative for _ in hidden_sizes] + [linear_derivative]
def forward(self, X):
activations = [X]
for i in range(len(self.weights)):
z = np.dot(activations[-1], self.weights[i]) + self.biases[i]
a = self.activations[i](z)
activations.append(a)
return activations
def compute_gradients(self, X, y, activations):
m = X.shape[0]
deltas = []
# 输出层误差
output_error = activations[-1] - y
deltas.append(output_error * self.activation_derivatives[-1](activations[-1]))
# 反向传播
for i in range(len(self.weights)-2, -1, -1):
error = np.dot(deltas[-1], self.weights[i+1].T)
delta = error * self.activation_derivatives[i](activations[i+1])
deltas.append(delta)
deltas.reverse()
# 计算梯度
gradients_weights = []
gradients_biases = []
for i in range(len(self.weights)):
gradients_weights.append(np.dot(activations[i].T, deltas[i]) / m)
gradients_biases.append(np.sum(deltas[i], axis=0, keepdims=True) / m)
return gradients_weights, gradients_biases
def update_parameters(self, gradients_weights, gradients_biases):
for i in range(len(self.weights)):
self.weights[i] -= self.learning_rate * gradients_weights[i]
self.biases[i] -= self.learning_rate * gradients_biases[i]
def train(self, X, y):
for epoch in range(self.epochs):
activations = self.forward(X)
gradients_weights, gradients_biases = self.compute_gradients(X, y, activations)
self.update_parameters(gradients_weights, gradients_biases)
def predict(self, X):
activations = self.forward(X)
return activations[-1]
# 3. 示例数据
if __name__ == "__main__":
# 生成示例数据
np.random.seed(0)
X = np.linspace(-10, 10, 200).reshape(-1, 1)
y = 2 * X**3 + 3 * X**2 - 4 * X + 1 + np.random.normal(0, 10, X.shape) # 添加噪声
# 归一化数据
X_mean, X_std = np.mean(X), np.std(X)
y_mean, y_std = np.mean(y), np.std(y)
X_normalized = (X - X_mean) / X_std
y_normalized = (y - y_mean) / y_std
# 构建神经网络
hidden_sizes = [64, 64]
input_size = X_normalized.shape[1]
output_size = 1
learning_rate = 0.01
epochs = 5000
model = NeuralNetworkRegressor(input_size, hidden_sizes, output_size, learning_rate, epochs)
# 训练模型
model.train(X_normalized, y_normalized)
# 预测
X_test_normalized = np.linspace(-10, 10, 300).reshape(-1, 1)
X_test_normalized = (X_test_normalized - X_mean) / X_std
y_pred_normalized = model.predict(X_test_normalized)
y_pred = y_pred_normalized * y_std + y_mean
# 可视化
plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='blue', alpha=0.6, label='True Data')
plt.plot(X_test_normalized * X_std + X_mean, y_pred, color='red', linewidth=3, label='Predicted Curve')
plt.title("Neural Network Regression")
plt.xlabel("X")
plt.ylabel("y")
plt.legend()
plt.grid(True)
plt.show()
运行结果:
python函数库实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 生成示例数据
np.random.seed(42)
X = np.sort(5 * np.random.rand(80, 1), axis=0)
y = np.sin(X).ravel() + np.random.randn(80) * 0.1
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建 MLPRegressor 模型
model = MLPRegressor(
hidden_layer_sizes=(10, 10), # 定义隐藏层结构,这里有两个隐藏层,每层 10 个神经元
activation='relu', # 使用 ReLU 激活函数
solver='adam', # 使用 Adam 优化器
alpha=0.0001, # L2 正则化参数
max_iter=500, # 最大迭代次数
random_state=42
)
# 训练模型
model.fit(X_train, y_train)
# 在测试集上进行预测
y_pred = model.predict(X_test)
# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
# 生成用于绘制预测曲线的连续输入值
X_plot = np.linspace(0, 5, 100).reshape(-1, 1)
y_plot = model.predict(X_plot)
# 可视化结果
plt.figure(figsize=(10, 6))
plt.scatter(X_test, y_test, color='blue', label='True Values')
plt.scatter(X_test, y_pred, color='red', label='Predictions on Test Set')
plt.plot(X_plot, y_plot, color='green', linestyle='--', label='Prediction Curve')
plt.xlabel('Input')
plt.ylabel('Output')
plt.title('Neural Network Regression: True Values vs Predictions')
plt.legend()
plt.show()
运行结果: