随机梯度下降的代码实现

单变量线性回归的机器学习代码中,我们讨论了批量梯度下降代码的实现,本篇将进行随机梯度下降的代码实现,整体和批量梯度下降代码类似,仅梯度下降部分不同:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import joblib

# 导入数据
path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])

# 分离特征和目标变量
X = data.iloc[:, 0:1].values  # Population列
y = data.iloc[:, 1].values  # Profit列
m = len(y)  # 样本数量

# 添加一列全为1的截距项
X = np.append(np.ones((m, 1)), X, axis=1)




# 批量梯度下降参数
alpha = 0.01  # 学习率
iterations = 1500  # 迭代次数

# 随机梯度下降算法
def stochasticGradientDescent(X, y, theta, alpha, num_iters):
    m = len(y)

    for iter in range(num_iters):
        for i in range(m):
            # 随机选择一个数据点进行梯度计算
            random_index = np.random.randint(0, m)
            X_i = X[random_index, :].reshape(1, X.shape[1])
            y_i = y[random_index].reshape(1, 1)

            # 计算预测值和误差
            prediction = np.dot(X_i, theta)
            error = prediction - y_i

            # 更新参数
            theta = theta - (alpha * X_i.T.dot(error)).flatten()


    return theta

# 初始化模型参数
theta = np.zeros(2)

"""
随机梯度下降前的损失显示
"""
# 定义损失函数,用于显示调用前后的损失值对比
def computeCost(X, y, theta):
    m = len(y)
    predictions = X.dot(theta)
    square_err = (predictions - y) ** 2
    return np.sum(square_err) / (2 * m)
# 计算初始损失
initial_cost = computeCost(X, y, theta)
print("初始的损失值:", initial_cost)


# 使用随机梯度下降进行模型拟合
theta = stochasticGradientDescent(X, y, theta, alpha, iterations)

"""
随机梯度下降后的损失显示
"""
# 计算优化后的损失
final_cost = computeCost(X, y, theta)
print("优化后的损失值:", final_cost)

"""
使用需要预测的数据X进行预测
"""
# 假设的人口数据
population_values = [3.5, 7.0]  # 代表35,000和70,000人口

# 对每个人口值进行预测
for pop in population_values:
    # 将人口值转换为与训练数据相同的格式(包括截距项)
    predict_data = np.matrix([1, pop])  # 添加截距项

    # 使用模型进行预测
    predict_profit = np.dot(predict_data, theta.T)
    print(f"模型预测结果 {pop} : {predict_profit[0,0]}")
"""
使用模型绘制函数
"""
# 创建预测函数
x_values = np.array(X[:, 1])
f = theta[0] * np.ones_like(x_values) + (theta[1] * x_values)  # 使用广播机制


# 绘制图表
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x_values, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Training Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()

"""
保存模型
"""
# 保存模型
joblib.dump(theta, 'linear_regression_model.pkl')

"""
加载模型并执行预测
"""
# 加载模型
loaded_model = joblib.load('linear_regression_model.pkl')

# 假设的人口数据
population_values = [3.5, 7.0]  # 代表35,000和70,000人口

# 使用模型进行预测
for pop in population_values:
    # 更新预测数据矩阵,包括当前的人口值
    predict_data = np.matrix([1, pop])
    
    # 进行预测
    predict_value = np.dot(predict_data, loaded_model.T)
    print(f"模型预测结果 {pop} : {predict_value[0,0]}")

实际测试下来,同迭代次数情况下随机梯度下降的收敛度远低于批量梯度下降:

初始的损失值: 32.072733877455676
优化后的损失值: 6.037742815925882 批量梯度下降为:4.47802760987997
模型预测结果 3.5 : -0.6151395665038226
模型预测结果 7.0 : 2.9916563373877203
模型预测结果 3.5 : -0.6151395665038226
模型预测结果 7.0 : 2.9916563373877203

即便是将迭代次数增加10倍也无法有效降低太多损失,15000次迭代的结果:

优化后的损失值: 5.620745223253086

个人总结:随机梯度下降估计只有针对超大规模的数据有应用意义。

注:本文为学习吴恩达版本机器学习教程的代码整理,使用的数据集为https://github.com/fengdu78/Coursera-ML-AndrewNg-Notes/blob/f2757f85b99a2b800f4c2e3e9ea967d9e17dfbd8/code/ex1-linear%20regression/ex1data1.txt

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 随机梯度下降机器学习中常用的一种优化算法,它具有较快的收敛速度和低内存消耗等优点。下面给出一份Matlab代码实现: function [theta, J_history] = stochastic_gradient_descent(X, y, theta, alpha, num_iters) m = length(y); J_history = zeros(num_iters, 1); for iter = 1:num_iters for i = 1:m h = X(i,:) * theta; J_history(iter) = J_history(iter) + (h - y(i))^2; for j = 1:size(X,2) theta(j) = theta(j) - alpha * (h - y(i)) * X(i,j); end end J_history(iter) = J_history(iter) / (2*m); end end 该函数有以下五个输入参数: 1)X:样本数据(输入变量) 2)y:样本数据(输出变量) 3)theta:参数向量 4)alpha:学习速率(步长) 5)num_iters:迭代次数 在函数主体中,通过for循环依次遍历每一个样本,计算每个样本的损失,并更新参数向量theta。最后,将每一次迭代的损失存储在J_history中。 使用该函数进行随机梯度下降时,只需要将样本输入矩阵X和输出向量y传递给函数即可。在函数返回时,输出参数theta即为优化得到的最佳参数向量,输出J_history即为每一次迭代的损失值。 需要注意的是,由于随机梯度下降是一种随机算法,每次迭代的结果可能都会有所不同。因此,在实际应用中,通常需要多次运行该函数,并将最终结果取平均值以提高模型的稳定性。 ### 回答2: 随机梯度下降(Stochastic Gradient Descent, SGD)是一种常用的优化算法,特别适合用于大规模数据集和高维模型的训练。以下是一份基于MATLAB实现的SGD代码: function [theta, J_history] = sgd(X, y, alpha, num_iters) % X: m x n的样本矩阵, m为样本数,n为特征数 % y: m x 1的标签向量 % alpha: 学习率 % num_iters: 迭代次数 % 初始化theta theta = zeros(size(X, 2), 1); % 记录每次迭代的代价函数值 J_history = zeros(num_iters, 1); for iter = 1:num_iters % 随机选择一个样本 i = randi(size(X, 1)); % 求解梯度,注意这里只用了一个样本 gradient = X(i, :)' * (X(i, :) * theta - y(i)); % 更新theta theta = theta - alpha * gradient; % 计算代价函数值 J_history(iter) = compute_cost(X, y, theta); end end function J = compute_cost(X, y, theta) % 计算代价函数,这里使用的是均方误差 m = length(y); J = 0; J = sum((X * theta - y).^2) / (2 * m); end 这段代码实现随机梯度下降,其中函数sgd执行迭代次数num_iters次,每次从样本中随机选取一个样本进行梯度计算和更新theta。compute_cost函数用于计算代价函数,这里使用的是均方误差。使用这个代码可以对数据进行线性回归等任务的优化。 ### 回答3: 随机梯度下降是一种常见的优化算法,通常用于机器学习和深度学习中的参数优化。Matlab提供了一个非常便捷的实现方式。 首先,我们需要定义损失函数和梯度函数。对于一个线性回归模型,定义损失函数为: ```matlab function J = loss(X, y, w) % X:训练集 % y:目标输出 % w:参数向量 % w = [w0, w1, ..., wn] m = length(y); % 样本数量 h = X*w; % 预测输出 J = (1/(2*m)) * sum((h-y).^2); % 均方误差 end ``` 接下来,我们需要定义梯度函数。对于线性回归而言,梯度函数为: ```matlab function grad = gradient(X, y, w) % X:训练集 % y:目标输出 % w:参数向量 % w = [w0, w1, ..., wn] m = length(y); % 样本数量 h = X*w; % 预测输出 grad = (1/m)*X'*(h-y); % 梯度 end ``` 接着,我们可以开始使用随机梯度下降算法: ```matlab % 初始化参数 w = randn(size(X, 2), 1); alpha = 0.01; % 学习率 max_iter = 1000; % 最大迭代次数 for i = 1:max_iter % 随机选择一个样本 idx = randi(size(X,1)); x = X(idx,:); y_i = y(idx,:); % 计算梯度 grad = gradient(x, y_i, w); % 更新参数 w = w - alpha*grad; % 计算损失 J = loss(X, y, w); fprintf('迭代次数:%d,训练误差:%f\n', i, J); end ``` 在每次迭代中,随机选择一个样本来计算梯度并更新参数。这种随机性有助于避免算法陷入局部最优解,同时减少计算时间。整个算法的收敛速度并不是很快,但是在较大的数据集上表现良好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值