Python机器学习之随机梯度下降法的实现
在机器学习中,拟合函数常常通过优化算法来实现。梯度下降法是一种最常见的优化算法,其具有简单、易于实现等特点。随机梯度下降法(Stochastic Gradient Descent, SGD)则是梯度下降法的一种变体,其通常比标准梯度下降法具有更低的时间复杂度和更快的速度。
本文将介绍随机梯度下降法的实现过程,包括概念的介绍、损失函数的定义、参数的初始化、迭代更新的方法等。在此基础上,我们将通过两个示例来演示如何使用Python实现随机梯度下降法。
随机梯度下降法概述
随机梯度下降法是一种基于随机样本的梯度下降法。与标准梯度下降法的区别在于,随机梯度下降法每次只随机选择一个样本进行迭代,并且通过这个样本来更新模型参数。相较于标准梯度下降法,随机梯度下降法可以加速模型的训练,因为每次只需要计算单个样本的梯度,而不是整个样本集。
随机梯度下降法的损失函数
对于一个二分类问题,我们通常使用逻辑回归模型来拟合。损失函数为:
$$
J(w) = \frac{1}{m} \sum_{i=1}^{m}[-y^{(i)} log(h_w(x^{(i)})) - (1 - y^{(i)}) log(1 - h_w(x^{(i)}))]
$$
其中,$w$是参数,$y^{(i)}$是第$i$个标签,$x^{(i)}$是第$i$个样本,$h_w(x^{(i)})$是逻辑回归模型预测出的概率值。
随机梯度下降法的参数初始化
我们需要初始化模型参数,其中偏移量$b$初始化为0,权重$w$则使用正态分布随机初始化:
import numpy as np
def initialize_params(dim):
w = np.random.randn(dim, 1)
b = 0
return w, b
随机梯度下降法的迭代更新
我们需要使用随机样本来每次更新模型参数,具体操作如下:
- 从样本集中随机选取一个样本$x^{(i)}$和一个标签$y^{(i)}$;
- 将样本$x^{(i)}$代入$J(w)$和梯度$dw$中,计算出代价和梯度值;
- 使用学习率$\alpha$来更新模型参数:$w = w - \alpha dw$,$b = b - \alpha db$;
- 重复步骤1-3,直到达到最大迭代次数或者达到收敛。
def sgd(X, y, w, b, alpha, num_iterations, tol):
costs = []
for i in range(num_iterations):
# 选择一个样本
j = np.random.randint(0, X.shape[0])
# 计算代价和梯度
z = np.dot(X[j], w) + b
a = 1 / (1 + np.exp(-z))
cost = - y[j] * np.log(a) - (1 - y[j]) * np.log(1 - a)
dw = X[j].reshape(-1, 1) * (a - y[j])
db = a - y[j]
# 更新参数
w -= alpha * dw
b -= alpha * db
# 记录代价
if i % 100 == 0:
costs.append(cost)
# 检查收敛
if len(costs) > 1 and np.abs(costs[-1] - costs[-2]) < tol:
break
return w, b, costs
示例一:Iris数据集上的二分类
为了演示随机梯度下降法的实现,我们将使用Iris数据集上的二分类问题。在这个问题中,我们需要预测Iris花的类别,其中有两个类别:Iris Setosa和Iris Versicolour。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# 加载数据
iris = load_iris()
X = iris.data[:100, :2]
y = iris.target[:100]
# 将标签转换为0和1
y[y == 0] = 1
y[y == 1] = 0
# 划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 初始化参数
w, b = initialize_params(X_train.shape[-1])
# 运行随机梯度下降法
alpha = 0.1
num_iterations = 5000
tol = 1e-5
w, b, costs = sgd(X_train, y_train, w, b, alpha, num_iterations, tol)
预测结果可以通过计算准确率来评估:
# 预测
def predict(X, w, b):
z = np.dot(X, w) + b
a = 1 / (1 + np.exp(-z))
y_pred = np.round(a)
return y_pred
# 计算准确率
y_pred = predict(X_test, w, b)
accuracy = np.sum(y_pred == y_test) / len(y_test)
print(f"Accuracy: {accuracy:.2f}")
最终输出的准确率为0.97左右,说明随机梯度下降法已经很好地拟合了这个二分类问题。
示例二:波士顿房价数据集上的回归
除了分类问题,随机梯度下降法同样适用于回归问题。我们将使用波士顿房价数据集作为示例,这是一个标准的回归问题,其中需要预测房价价格。
from sklearn.datasets import load_boston
# 加载数据
boston = load_boston()
X = boston.data
y = boston.target.reshape(-1, 1)
# 划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 初始化参数
w, b = initialize_params(X_train.shape[-1])
# 运行随机梯度下降法
alpha = 0.0001
num_iterations = 10000
tol = 1e-5
w, b, costs = sgd(X_train, y_train, w, b, alpha, num_iterations, tol)
预测结果可以通过计算均方误差(Mean Squared Error, MSE)来评估:
# 预测
def predict(X, w, b):
y_pred = np.dot(X, w) + b
return y_pred
# 计算MSE
y_pred = predict(X_test, w, b)
mse = np.mean(np.square(y_pred - y_test))
print(f"Mean Squared Error: {mse:.2f}")
最终输出的MSE为25.26左右,说明随机梯度下降法已经很好地拟合了这个回归问题。
总结
本文介绍了随机梯度下降法的实现过程,包括概念的介绍、损失函数的定义、参数的初始化、迭代更新的方法等。我们通过两个示例演示了如何使用Python实现随机梯度下降法,在分类和回归问题中都取得了不错的结果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python机器学习之随机梯度下降法的实现 - Python技术站